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
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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
:hasselector. 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:hasallows for selecting something that's true for a child element and style a different child element.We cannot use
:hasyet, but CSS can support this type of thing using other selectors instead. An example might be theFormFieldhaving anorientationmodifier. TheFieldFormLabelneeds to know what the orientation is, so the model was used to pass down this information.An alternative would be to update the
FormFieldrender 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
myStencilelement becauseelemPropsare being spread on the container, making thedivwith themyStencilnot 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-elementattribute 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
elementsconfig on the stencil to allow for less chance of collision to make authoring a bit more natural:Overriding the style of
MyComponentcan look like:Or:
Beta Was this translation helpful? Give feedback.
All reactions