DRAFT FOR COMMENT: Design system modularization#2559
Conversation
| neutralOutlineHover, | ||
| neutralOutlineRest, | ||
| } from "../utilities/color"; | ||
| import { neutralFocus, neutralForegroundRest, neutralOutline } from "../utilities/color"; |
There was a problem hiding this comment.
I think the outline button example given is a good one - I'd like to see how the swapping gets implemented here. Would it be possible to create a stories.tsx file with one example similar to what you detailed in the write-up?
an alternate implementation, like outlines are neutral colored by default, and go to accent on hover or active states.
There was a problem hiding this comment.
I've tried this, and I found that this code is not working quite as expected. I'm having a problem that seems to be something related to webpack, where the function value I'm putting into the design system is getting swapped out with some 'reviver' function that doesn't seem to be resolving correctly.
I suspect we can do something like this with some sort of design system registry, where we could potentially even look up or pass in named resources from the standard or custom design system. I don't understand enough about webpack to resolve this though.
| restDelta: number | DesignSystemResolver<number>, | ||
| hoverDelta: number | DesignSystemResolver<number>, | ||
| activeDelta: number | DesignSystemResolver<number>, | ||
| focusDelta: number | DesignSystemResolver<number> |
There was a problem hiding this comment.
Just a thought, and I know this is in the idea stage - but perhaps this algo can be defined by more of a config driven aspect? That may help those using it and reading it. It seems like the algorithm needs two things: 1) Palette, 2) interactive state config for the deltas
export interface InteractiveOffsetConfig {
restDelta: number | DesignSystemResolver<number>;
hoverDelta: number | DesignSystemResolver<number>;
activeDelta: number | DesignSystemResolver<number>;
focusDelta: number | DesignSystemResolver<number>;
}
export function offsetsAlgorithm(palette: Palette | DesignSystemResolver<Palette>, config: InteractiveOffsetConfig): SwatchFamilyResolver { };There was a problem hiding this comment.
Is the benefit here cleaner syntax, reuse of config, or both? It does seem like it would protect from potential future changes easier as properties could be added and defaulted or deprecated without changing the signature. I would probably put everything in though, including the palette. I could see an implementation of this that wants both an accent and neutral, or even success or error, etc.
Perhaps in the design system service model there would be a way for style modules like this to retrieve properties from the registry of sorts. For instance, a custom design system might add a fourth color, and through composition the style could find it. This feels like a fairly standard composition problem that possibly has a framework or structure already in place. I wonder if we could pull something in.
There was a problem hiding this comment.
Initially I see it for cleaner syntax - from a fn() standpoint, once you hit more than 3 inputs it's going to become difficult to manage. Considering the deltas are all "related" and inform the palette I think the syntax makes more sense than having them all at the same level.
|
I'm going to take a stab at translating your stated goals into more specific requirements. Note that I'm saying "style recipe" here because I think the system should support arbitrary key/value pairs unspecific to color. Also note that the following code is pseudo-code and is not a recommendation for implementation:
Currently the "design system" is simply a set of serializeable data informing functions. The above will require some mechanism for providing and overriding function implementations. With "design system as a service" conversations, it is unclear to me in this scenario what exactly the "design system" is and what information will be provided from said service. The two primary approaches I see would be to either limit the data provided by a service or define a protocol that creates runtime functions on the client. Related but tangential is how color recipes are created. Color recipes generally follow one or more patterns - can we refactor color algorithm creation tools to map more closely to those patterns where each specific recipe implementation can be a product of pattern implementations, and in general be more composable and extensible. I think this is a separate issue though, so perhaps we can limit this discussion to how we can map overrideable function implementations to CSS properties. Are there any requirements you see that I missed? |
|
I'm fine with "style recipe". Yes, these should definitely work for any potential styling value including color, measurement, shadow, etc. 1a. Not explicitly, at least initially, but that thought has definitely come up. For instance, we have a lot of repetition between states, and I've even added state functions for retrieving values from the swatch family in this PR, so that is at least a minor pain point. The other usage of this that comes to mind is RTL application of padding on "left" and "right" attributes.
Agreed on the "service" aspects, but I don't think that's any different than with what we have now. Let's say the service provided values for the currently serializable design system properties. If an app had needed the customizations we're talking about supporting, they would have had to write custom code and restyle components anyway. At the very least this improves the situation as we abstract some of the style providers and potentially reduce the need for custom code. I think either implementation would require code being able to be run within the app, or potentially the service can do the actual calculations instead of only returning values. That has different tradeoffs though. Any shared sort of service would only ever be able to communicate the standard aspects of the design, I believe. Also agreed regarding the color recipes, on functionality as well as separating it out. I think it will be a good example when discussing this update, so I'm sure they will come up again anyway. One aspect that isn't yet described here, and I only mentioned it in the last sentence of the description, is an idea around formalizing the interface of style recipes a particular component uses or has available. The basic idea is that a I still like the idea of something like this, but I'm not sure props or something like this is the best approach, because it doesn't allow for a style or override to decide that it also needed another type of recipe later. This gets me back to the idea that the design system is a registry and potential mapping of style recipes / modules. Right now the solution for the above would require wrapping in a DesignSystemProvider, which seems a bit heavy and is what I was looking for a way to avoid. |
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Initial idea for converting recipe parameters into a style provider module.
Description
Goals
The current recipes can't represent a wide variety of intended looks through properties alone.
For instance, a one-off special color button.
Transition groups of design system properties (for example, color ramp deltas) and associated functions (ex: color recipes) into a single resource (object) that can be configured, referenced, and replaced in a modular fashion. Allows for easily adding new recipe types or changing design without needing to restyle components.
For instance, the design system provides a resource that knows how to provide outline color swatches. The
Outline Buttonreferences that resource, which by default might use the neutral ramp and apply states by offsets on the same ramp. Another design could provide an alternate implementation, like outlines are neutral colored by default, and go to accent on hover or active states. Another example would be a default shadow algorithm being replaced by another that does something outside of the parameters available in the default algorithm, like x-offset or more shadow levels.This is the initial part of creating modules, where a remaining portion would provide for an easy way to swap a particular modular resource at the instance level (goal #2).
Motivation & context
Starting to look into some of the challenges with applying the design system, particularly color, and ways to extend the current systems approach into more customized styles that don't work with the base recipes. The current design system setup requires everything to be conveyable in the given set of properties, and larger adjustments require restyling components, which is complex and error-prone.
Issue type checklist
Is this a breaking change?
Process & policy checklist