Usually, it is enough to define style only for the .root
and its children. But sometimes, you want to edit style for host element. Here is patterns for this.
Define Shadow Host style
To define Shadow Host style, just write CSS in :host
as usual.
class Example extends Craft.UI.View {
style(componentId){
return `
:host {
padding-top: env(safe-area-inset-top);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
`;
}
}
Direct Host style modification
You can directly update Host element styling via this.shadow.host.style[*]
.
class Example extends Craft.UI.View {
updateShadowHostWidth(){
this.shadow.host.style.width = '200px';
}
style(componentId){
return `
:host {
width: 100px;
}
`;
}
}
Swap Shadow Host CSS class
If you would like to change style of Host element on the fly, your target class should be defined in the parent component to be able to affect the shadow element.
class Example extends Craft.UI.View {
viewDidLoad(callback){
this.appendView(new ExampleCore());
if(callback){ callback(); }
}
style(componentId){
return `
.light { color:#333; background-color: #fff; }
.dark { color:#fff; background-color: #333; }
`;
}
}
class ExampleWrapped extends Craft.UI.View {
constructor(options){
super(options);
this.data = { mode:0 };
}
toggleMode(){
if( this.data.mode++ % 2 ){
this.shadow.host.classList.add('light')
this.shadow.host.classList.remove('dark')
}else{
this.shadow.host.classList.add('dark');
this.shadow.host.classList.remove('light')
}
}
style(componentId){
return `
:host { color:#333; background-color: #fff; }
.root {
width:100px; marign-left:auto; marign-right:auto;
}
`;
}
template(componentId){
return `
<div id="root" class="root"
onclick="${componentId}.toggleMode()">
Hello!
</div>
`;
}
}
Discouraged pattern
You can write something like the following code, but the code goes back and forth. So, this pattern should be avoided.
class ExampleWrapper extends Craft.UI.View {
constructor(options){
super(options);
this.data = { mode:1 };
this.views = { example:null };
}
viewDidLoad(callback){
this.views.example = new ExampleWrapped({delegate:this});
this.appendView(this.views.example);
if(callback){ callback(); }
}
toggleMode(){
if( this.data.mode++ % 2 ){
this.views.example.darkMode();
}else{
this.views.example.lightMode();
}
}
style(componentId){
return `
.light { color:#333; background-color: #fff; }
.dark { color:#fff; background-color: #333; }
`;
}
}
class ExampleWrapped extends Craft.UI.View {
constructor(options){
super(options);
this.delegate = options.delegate;
}
lightMode(){
this.shadow.host.classList.add('light')
this.shadow.host.classList.remove('dark')
}
darkMode(){
this.shadow.host.classList.add('dark');
this.shadow.host.classList.remove('light')
}
style(componentId){
return `
:host { color:#333; background-color: #fff; }
.root {
width:100px; marign-left:auto; marign-right:auto;
}
`;
}
template(componentId){
return `
<div id="root" class="root"
onclick="${componentId}.delegate.toggleMode()">
Hello!
</div>
`;
}
}
NOTE
Above examples are runnable on playground.
var view = new Example();
view.loadView();
Craft.Core.Context.getRootViewController().appendSubView(view);
🛺 Try CraftKit Playground:
https://github.com/craftkit/craftkit-playground
Top comments (0)