Vaadin + LitElement - styles from `get styles()` not getting applied - css

I have a trivial LitElement class that I want to style with some internal CSS:
import {LitElement, html, css, customElement, property} from 'lit-element';
#customElement('address-card')
export class AddressCard extends LitElement {
#property()
streetAddress?: string;
#property()
postalCode?: string;
#property()
city?: string;
static get styles() {
return css`
.address { border: 1px dashed gray; }
`;
}
render() {
return html`
<div class="address">
<div>${this.streetAddress}</div>
<div>${this.postalCode} ${this.city}</div>
</div>
`;
// Remove this method to render the contents of this view inside Shadow DOM
createRenderRoot() {
return this;
}
}
The static get styles() method should allow me to add styles to the component, but nothing I add there seems to get applied. Not even a * { ... } selector, which should affect all elements, seems to do anything.

The problem is the createRenderRoot() method. If you disable shadow root, there's no need to encapsulate styles inside the component implementation - you can use global CSS. If you want to encapsulate styles, remove the createRenderRoot override and the static get styles() rules will get applied.

Related

How to access or read the css property value in angular typescript file

html file:
<div #sampleComponent class="cdt-sample-component"
[ngStyle]="{'height': (view_height) + 'px'}" >
<app-component></app-component>
</div>
css file:
.cdt-sample-component {
display: flex;
flex: 1;
height: calc(100% / 3);
}
}
ts file:
constructor(private renderer: Renderer2) {
}
ngAfterViewInit() {
logger.info("NativeElement height " + this.renderer.selectRootElement(this.metricsComponent['nativeElement']).getAttribute('height'));
}
The above log print in ts file is returning null for "height" attribute.
I am using angular 7.
I would like to get the value of "height" attribute defined in css in div element "cdt-sample-component", somehow i am getting null. Can you please answer on how to get the height attribute value in ts file which is defined in css file.
You could try to use ViewChild to get a reference to the element and read it's clientHeight or offsetHeight property.
Controller
import { AfterViewInit, Component, ElementRef, ViewChild } from "#angular/core";
export class SomeComponent implements AfterViewInit {
#ViewChild("sampleComponent") sampleComponent: ElementRef<any>;
ngAfterViewInit() {
console.log(this.sampleComponent.nativeElement.clientHeight);
}
}
For clientHeight vs offsetHeight see here: https://stackoverflow.com/a/15615701/6513921

Overwrite render method extending from parentComponent in lit element

im trying to create a new lit element component extending from other component
but render method donĀ“t works.
the component is empty..
export default class ChildComponent extends FatherComponent {
static get styles() {
return css`
:host {
display: block;
}`;
}
render() {
return html`<h1>Hi</h1>`;
}
}
window.customElements.define('child-component', ChildComponent);
I had the same kind of issue today. It seems that render() was not triggered.
To solve my issue I had to call super.connectedCallback() in the connectedCallback() methods for both child and parent.
I also call super() in the constructor.
Hope that helps.

How to apply css only to React child component

I have a child component needs to use spectre.css, but when I import spectre.css in child component, parent component also got affected. How can I make spectre.css only apply to the child component? Thanks
Parent Component:
class ParentComponent extends React.Component{
render(){
return <ChildComponent></ChildComponent>
}
}
In Child component,
import from 'spectre.css'
class ChildComponent extends React.Component{
/* ... */
}
most probably your css is bundled in one single file.
You can add className to your components, to differentiate them.
you can create your styles inside your component
const styles= {
wrapper: {
color: red,
},
};
class ChildComponent extends React.Component{
/* ... */
render() {
return (<div style={styles.wrapper}> </div>
}
}
or you can try css-in-js libraries such as emotion or styled-components

Passing css styles from React Parent component to its child component

I have React parent component A which has its own scss file a-style.scss. Component B is child of A. A is passing styleInfo object as props which is applied on B.
My question is - is there any way we can define styleObj in a-style.scss instead of defining it inline. I want all styling related info should be in external scss file.
Component A
import "./a-style.scss";
import B from "./B.js";
class A extends Component {
constructor(props) {
super(props);
}
const styleObj = {
backgroundColor: "#F9F9F9",
borderRadius: '2px',
color: "#686868",
};
render() {
return (<B styleInfo={this.styleObj}></B>);
}
}
Component B
class B extends Component {
constructor(props) {
super(props);
}
render() {
return (<div style={this.props.styleInfo}></div>);
}
}
The standard way is to define CSS properties based on class in your scss/css. And then pass className from props in your React component:
class A extends Component {
theme = "themeA";
render() {
return (<B styleInfo={this.theme} />);
}
}
class B extends Component {
styleClass = ["B"];
render() {
const className = styleClass.push(this.props.styleInfo).join(' ');
return (<div className={className} />);
}
}
.themeA {
background-color: #F9F9F9;
border-radius: 2px;
color: #686868;
}
.B {
/* Some style for B component */
}
Why not just import that one file directly into B.js?
Is there any benefit of having it go through a parent, seems like necessary routing to me!
If you do need this, then I would just keep it in JS, as this is what JS is good at, or at least, have JS just do the className switching and, again, just have one css file that is a main style lookup hash!
Best of luck!

StencilJS Component Styles

What is the proper way to use the styles option/property of the ComponentDecorator? Using the styles property with the default my-name component from the repository stencil-component-starter doesn't seem to affect the styles of the respective component nor generate something like a <style> tag in the <head>. How is styles intended to work? Or has it not been implemented yet? If the goal is to avoid having a separate CSS asset that needs to be loaded, but provide styles for the component, would styles be the right choice or is there another property such as host would need to be used?
Below is a sample component generated from the stencil-component-starter]1 with stylesUrl #Component property replaced with a styles property and setting font-size property. No errors are generated during dev or build tasks.
import { Component, Prop } from '#stencil/core';
#Component({
tag: 'my-name',
styles: `my-name { font-size: 24px; }`
})
export class MyName {
#Prop() first: string;
render() {
return (
<div>
Hello, my name is {this.first}
</div>
);
}
}
ComponentDecorator is defined as:
export interface ComponentOptions {
tag: string;
styleUrl?: string;
styleUrls?: string[] | ModeStyles;
styles?: string;
shadow?: boolean;
host?: HostMeta;
assetsDir?: string;
assetsDirs?: string[];
}
Thank you for any help you can provide!
I just tried with latest version 0.0.6-22, and it seems to work completely now.
While compiling, it will tell you if your styles contents is valid or not (mainly looking for valid selectors).
Here is a working example (with a simple string):
import { Component, Prop } from "#stencil/core";
#Component({
tag: "inline-css-example",
styles: 'inline-css-example { font-size: 24px; }'
})
export class InlineCSSExampleComponent {
#Prop() first: string;
render() {
return <div>Hello, my name is {this.first}</div>;
}
}
This one works too, with ES6 Template Strings (just showing multiline):
import { Component, Prop } from "#stencil/core";
#Component({
tag: "inline-templatestring-css-example",
styles: `
inline-templatestring-css-example {
font-size: 24px;
}
`
})
export class InlineCSSExampleComponent {
#Prop() first: string;
render() {
return <div>Hello, my name is {this.first}</div>;
}
}
(EDITed to show evolution since 0.0.6-13)

Resources