Sharing style state between components and elements #2711
NicholasBoll
started this conversation in
Ideas
Replies: 1 comment
-
I don't think we want to add <button class="cnvs-button cnvs-button--variant-primary" data-modifier-variant="primary"`>
Primary Button
</button> And that's only if the data attribute is necessary for correct styling of the button. I think it makes more sense to use the class name of a parent Stencil than a data attribute. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I've been going through a lot of our components and noticed two patterns emerging:
Let's look at the first problem:
Using the model to share style-only state
The model pattern is meant to share model and events with a component group. Using it to share style-only state causes an issue: the model has to be reproduced by CSS-only authors. It means that more of the style API is in React than in CSS. As we move to more of a CSS-first approach, this starts to feel wrong. There are a few ways to share state between elements. An example might be the
:has
selector. An example might be<input required>
and the label needing to know if there's an input with a required field:&:has(:required) label {}
. The:has
allows for selecting something that's true for a child element and style a different child element.We cannot use
:has
yet, but CSS can support this type of thing using other selectors instead. An example might be theFormField
having anorientation
modifier. TheFieldFormLabel
needs to know what the orientation is, so the model was used to pass down this information.An alternative would be to update the
FormField
render function to encode this into the DOM so that CSS can select this:We can remember to add the
data-modifier-*
when needed. We could also add this directly to Stencils so thedata-modifier-*
is always present whether we need it or not. A CSS author not using Stencils would need to make sure to add it to their implementation of the DOM output when needed. It would at least give us a predictable way of targeting parent modifiers.Using more than one stencil per component
The previous deals with sharing modifiers between a family of components, but the inverse is a single component with more than one Stencil. This usually happens where there's more than one element per component.
The following is a common example:
There's a problem here. The application developer only has doesn't have access to the
myStencil
element becauseelemProps
are being spread on the container, making thediv
with themyStencil
not selectable without resorting to tricks like'& > div': styleOverrides
. The component no longer maps to a Stencil. It maps to two Stencils, breaking the "A Stencil is a style-specific mapping of a Component". It means the render function holds additional glue code not encoded in the Stencil.I propose we handle this case with a
data-element
attribute where we're allowed to semi-semantically name the child component. It will create a more intentional API for these cases. The example becomes this:It is possible to have an
elements
config on the stencil to allow for less chance of collision to make authoring a bit more natural:Overriding the style of
MyComponent
can look like:Or:
Beta Was this translation helpful? Give feedback.
All reactions