-
Notifications
You must be signed in to change notification settings - Fork 567
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose a larger number of design tokens in druid::theme #420
Comments
Cool, I think there's two separate related things here but they're both basically a matter of "haven't gotten to it yet":
Thanks for the issue and the links, it looks like a good starting place. 👍 |
I've been thinking a bit more about this, but I feel I need to work with the toolkit a bit more before patterns start to emerge. Meanwhile, I'll continue using this issue as a place to do a braindump of styling-related ideas, in case someone wants to pick this up at some point. General architectureI feel the current styling implementation is conceptually solid. Storing style information in Syntax sugarIt would be great to have syntax-sugar for quickly wrapping widgets inside
Syntax inspired by CSS and maplit.
|
I think we're generally on the same page:
|
My concern with this is that A good design, IMHO, would define a standard set of fields that can be expected to always be present, and also allow one field that could contain arbitrary data. For example:
However, I understand your concern @cmyr. Having this struct would result in a lot of cloning everywhere. I'm wondering if there's a way to have things both ways, but my Rust skills are not quite good enough to get there yet. |
So I think that we fundamentally agree, and The contents of
The goal, is basically that |
I'll go through widgets and will move non-configurable parameters to theme as in commit ^^ |
@Dmitry-Borodin thanks a lot for taking this up. I've been building an app where I want the buttons to have a more "flat" look than they have by default, and the lack of some of these configurable tokens was preventing me from building what I wanted. Just a note on your commit: I feel it would make more sense to have a More generic names for design tokens encourages reuse, which then makes it easier to override the look of multiple widgets by changing a small number of tokens. It also establishes a hierarchy of measures where the variables in the hierarchy can be configured such that they are mathematically related to each other. For example, in my app I could could force the margins between widgets as well as the sizes of widgets to be whole number multiples of 4. This would result an implicit grid that all widgets would line up with, thus producing a UI that feels more balanced to look at. |
@s3thi sorry I probably didn't get what do you mean. Currently widget takes some predefined values from theme by key, and the key for button starting with "button", because I may define it bigger or smaller than for textbox in my app. For example if I want textbox radius to be bigger than a button. If I would rename those keys to big and small, I would have to set value for BORDER_RADUIS_LARGE smaller, than for BORDER_RADUIS_SMALL, which is misleading. I like the idea of adding "border" to the key name for clarification. |
@Dmitry-Borodin I wasn't clear enough in my comment. Apologies. I opened this issue because I felt it would be useful if Druid's styling system was inspired by the "design systems" concept that is popular in UX design right now. When you build a design system for an app, you start with a basic set of values and measures called design tokens. This can include colors, font styles, font sizes, margins and paddings, opacities, shadows, etc. These common values are shared across all the widgets in the design system. For an example of what that looks like, see https://www.lightningdesignsystem.com/design-tokens/#category-radius These design tokens are defined first, and the widgets are designed around them. That is, instead of building a This approach lets you radically change the look and feel of your UI by changing a very small number of variables. You could make a design more compact by simply changing three or four padding values, or you could make a design more or less rounded by simply changing two or three radius values. This gives developers a lot of freedom to experiment with design without having to change too much code. So, instead of extracting The value of Future widgets could be designed around those three values, and defining new values would be restricted to very special cases. If a user of Druid decides they want a more angular design for their app, they could reset all of these values to I hope this made more sense than my previous comment. |
* #420 moved 2 hardcoded parameters to theme configuration * theme improvements - removing hardcoded parameters * theme improvements2 * added theme parameter for progress bar * rustfmt applied
I feel like Env is a more low-level abstraction. The current approach to store various theme parameters in there is the right decision; we can easily adjust how a particular widget looks. On top of Env, you can develop more high-level abstraction like a theme, which would change all env keys for widgets, e.g., you can create a struct with parameters as @s3thi suggested. Something like this: struct MyTheme {
pub border_radius_small: f64,
pub border_radius_medium: f64,
pub border_radius_large: f64,
...
}
impl MyTheme {
pub fn apply(&self, env: &mut Env) {
env.set(theme::BUTTON_BORDER_RADIUS, self.border_radius_medium);
env.set(theme::SCROLLBAR_RADIUS, self.border_radius_small);
env.set(theme::PROGRESS_BAR_RADIUS, self.border_radius_small);
env.set(theme::TEXTBOX_BORDER_RADIUS, self.border_radius_medium);
...
}
} |
What I don't like in current approach - it is how the library is rendering widgets, I like how flutter managed this, there I can make my buttons, text boxes, and other widgets look how I want. I would like to have control over how my widgets look, I would like to implement paint from scratch, but I don't want to reimplement all event handling and layout measurement and so on. |
I definitely think there's lots of room for us to find new and better patterns for this stuff. At least with buttons, we've moved in this direction; you can use the |
Is there any progress in this discussion? I think @s3thi's suggestion is good.
I am currently working on a project of my own. When using the button, I want the button to be a solid color, the activated state is another solid color, and the disabled state is also another solid color. His suggestion, if implemented, should allow me to set the theme of the button in an elegant way. My rust is not very good. Currently I want to implement my button theme. It can only be implemented locally through the clone repository, local reference, and modification of the local druid source code. Or is there a better way to achieve it? |
The current
EventScope
API allows me to override the variables listed indruid::theme
to customize how my application looks. However, there are a large number of variables used implicitly in the default widgets that I can't override. Instead of being picked up from theEnv
, these variables appear as literals in the source code.For example, the border radius for a
Button
is 4.0. It appears indruid/src/widget/button.rs
, but I can't retrieve or override it because it's just a literal value.Finding such variables and making them explicit in
druid::theme
will make styling a Druid application easier. There is precedent for this in the Design Systems communities, where these kinds of atomic base units are called design tokens. This article is a decent explainer, and this is a list of tokens used in the Salesforce design system.Adopting this approach would reduce inconsistencies across the toolkit and makes design decisions more explicit. E.g,
Button
has a border radius of 4.0, but aTextBox
has a border radius of 2.0. Both values appear as literals in the source code for those widgets. Exposing border radius values indruid::theme
would've either prevented this inconsistency, or documented it as an explicit design decision.This would also make it easy for custom widgets to fit in with the default set widget set.
It might not be an explicit goal of Druid, but this approach would also allow radical re-skinning of applications, with variable changes affecting both default, custom and community-built widgets.
I'm sure there are more ideas that Druid could pick up from the Design Systems community, but I can't think of anything at the moment. For now, setting up explicit design tokens would be a great start.
The text was updated successfully, but these errors were encountered: