square / maker

Maker Design System by Square
https://square.github.io/maker/styleguide/latest-stable/
Other
63 stars 14 forks source link

refactor!: theme color mapping and output #304

Closed landondurnan closed 2 years ago

landondurnan commented 2 years ago

Describe the problem this PR addresses

There's some changes in the v10 Beta theme configuration that make modifications to the theme data that are different from our plans and long-term goals.

Describe the changes in this PR

This PR updates the theme configuration data so that it's more compatible with existing data and theme data we plan to support in the future.

Other information

Details

The current theme data has a set of global design tokens primarily focused on Color, with v10 adding additional support for theming Typography. I've outlined the specific data changes in each version with more explanation on what we should add, change, or leave alone.

Colors

// SCROLL THIS CODE
// v9 Theme Color Data and CSS Properties
// Neutrals stay the same
'--color-background': colors.background,
'--color-text': colors.text,
'--color-heading': colors.heading,
'--color-elevation': colors['color-elevation'],
'--color-overlay': colors['color-overlay'],

// v10 Beta Theme Color Data and CSS Properties
// Neutrals stay the same
'--color-background': colors.background,
'--color-paragraph': colors.paragraph,
'--color-title': colors.title,
'--color-primary': colors.primary,
'--color-elevation': colors['color-elevation'],
'--color-overlay': colors['color-overlay'],

// v10 Recommended Theme Color Data CSS Properties
// Neutrals stay the same
'--color-background': colors.background,
'--color-text': colors.text,
'--color-heading': colors.heading,
'--color-primary': colors.primary,
'--color-secondary': colors.secondary,
'--color-elevation': colors.elevation,
'--color-overlay': colors.overlay,

Fonts (and fontWeights)

// SCROLL THIS CODE
// v9 Theme Fonts Data and CSS Properties
// None

// v10 Beta Theme Fonts Data and CSS Properties
fonts: {
    baseSize: 16,
    sizeScale: 1.17,
    title: {
        fontFamily: 'inherit',
        fontWeight: '500',
    },
    paragraph: {
        fontFamily: 'inherit',
        fontWeight: '400',
    },
    label: {
        fontFamily: 'inherit',
        fontWeight: '500',
    },
},

'--font-family-title': fonts.title.fontFamily,
'--font-weight-title': fonts.title.fontWeight,
'--font-family-paragraph': fonts.paragraph.fontFamily,
'--font-weight-paragraph': fonts.paragraph.fontWeight,
'--font-family-label': fonts.label.fontFamily,
'--font-weight-label': fonts.label.fontWeight,

// v10 Recommended Theme Fonts Data and CSS Properties
fonts: {
    baseSize: 16,
    sizeScale: 1.17,
    body: 'system-ui',
    heading: 'system-ui',
    headline: 'system-ui',
    label: 'system-ui',
},
fontWeights: {
    body: 400,
    heading: 600,
    headline: 400,
    label: 500,
},

'--font-body': fonts.body,
'--fontWeight-body': fontWeights.body,
'--font-heading': fonts.heading,
'--fontWeight-heading': fontWeights.heading,
'--font-label': fonts.label,
'--fontWeight-label': fontWeights.label,

Additional considerations and feedback from testing beta + labs

github-actions[bot] commented 2 years ago

Styleguide deployed to https://square.github.io/maker/styleguide/theme-data-revision/#/

github-actions[bot] commented 2 years ago

πŸ“Š Package size report   -0.05%↓

File Before After
components/ActionBar/styles.css 5.5 kB -0.13%↓5.5 kB
components/Button/styles.css 3.6 kB -0.19%↓3.6 kB
components/Calendar/styles.css 2.1 kB -0.34%↓2.1 kB
components/Choice/styles.css 1.3 kB -0.53%↓1.3 kB
components/Container/styles.css 1.2 kB -1.92%↓1.2 kB
components/PinInput/styles.css 1.3 kB -0.53%↓1.3 kB
components/SegmentedControl/styles.css 1.0 kB -0.69%↓1.0 kB
components/Stepper/styles.css 476 B -1.47%↓469 B
components/Textarea/styles.css 1.5 kB -1.16%↓1.5 kB
components/TextButton/styles.css 1.5 kB -0.46%↓1.5 kB
components/Theme/script.js 7.3 kB -1.45%↓7.2 kB
components/Theme/styles.css 247 B -8.91%↓225 B
Total (Includes all files) 1.2 MB -0.05%↓1.2 MB
Tarball size 232.5 kB -0.01%↓232.5 kB
Unchanged files | File | Size | | --------------------------------------------------------------------------------------- | --------: | | `components/ActionBar/index.js` | `46 B` | | `components/ActionBar/script.js` | `14.5 kB` | | `components/Blade/index.js` | `46 B` | | `components/Blade/script.js` | `6.2 kB` | | `components/Blade/styles.css` | `740 B` | | `components/Button/index.js` | `46 B` | | `components/Button/script.js` | `6.3 kB` | | `components/Calendar/index.js` | `46 B` | | `components/Calendar/script.js` | `7.7 kB` | | `components/Card/index.js` | `46 B` | | `components/Card/script.js` | `1.7 kB` | | `components/Card/styles.css` | `214 B` | | `components/Checkbox/index.js` | `46 B` | | `components/Checkbox/script.js` | `3.9 kB` | | `components/Checkbox/styles.css` | `1.4 kB` | | `components/Choice/index.js` | `46 B` | | `components/Choice/script.js` | `4.7 kB` | | `components/Container/index.js` | `46 B` | | `components/Container/script.js` | `4.5 kB` | | `components/Dialog/index.js` | `46 B` | | `components/Dialog/script.js` | `7.4 kB` | | `components/Dialog/styles.css` | `1.2 kB` | | `components/Divider/index.js` | `46 B` | | `components/Divider/script.js` | `1.7 kB` | | `components/Divider/styles.css` | `172 B` | | `components/Image/index.js` | `46 B` | | `components/Image/script.js` | `3.3 kB` | | `components/Image/styles.css` | `208 B` | | `components/ImageUploader/index.js` | `46 B` | | `components/ImageUploader/script.js` | `11.7 kB` | | `components/ImageUploader/styles.css` | `2.3 kB` | | `components/Input/index.js` | `46 B` | | `components/Input/script.js` | `4.2 kB` | | `components/Input/styles.css` | `2.1 kB` | | `components/Loading/index.js` | `46 B` | | `components/Loading/script.js` | `2.2 kB` | | `components/Loading/styles.css` | `1.2 kB` | | `components/Modal/index.js` | `46 B` | | `components/Modal/script.js` | `9.8 kB` | | `components/Modal/styles.css` | `1.1 kB` | | `components/Notice/index.js` | `46 B` | | `components/Notice/script.js` | `4.7 kB` | | `components/Notice/styles.css` | `1.1 kB` | | `components/PinInput/index.js` | `46 B` | | `components/PinInput/script.js` | `4.6 kB` | | `components/Popover/index.js` | `46 B` | | `components/Popover/script.js` | `10.3 kB` | | `components/Popover/styles.css` | `498 B` | | `components/ProgressBar/index.js` | `46 B` | | `components/ProgressBar/script.js` | `2.9 kB` | | `components/ProgressBar/styles.css` | `1.1 kB` | | `components/Radio/index.js` | `46 B` | | `components/Radio/script.js` | `3.6 kB` | | `components/Radio/styles.css` | `1.5 kB` | | `components/SegmentedControl/index.js` | `46 B` | | `components/SegmentedControl/script.js` | `3.1 kB` | | `components/Select/index.js` | `46 B` | | `components/Select/script.js` | `5.0 kB` | | `components/Select/styles.css` | `2.0 kB` | | `components/Skeleton/index.js` | `46 B` | | `components/Skeleton/script.js` | `4.3 kB` | | `components/Skeleton/styles.css` | `937 B` | | `components/StarRating/index.js` | `46 B` | | `components/StarRating/script.js` | `5.9 kB` | | `components/StarRating/styles.css` | `322 B` | | `components/Stepper/index.js` | `46 B` | | `components/Stepper/script.js` | `4.2 kB` | | `components/Text/index.js` | `46 B` | | `components/Text/script.js` | `4.6 kB` | | `components/Text/styles.css` | `4.7 kB` | | `components/Textarea/index.js` | `46 B` | | `components/Textarea/script.js` | `3.6 kB` | | `components/TextButton/index.js` | `46 B` | | `components/TextButton/script.js` | `3.7 kB` | | `components/Theme/index.js` | `46 B` | | `components/Toggle/index.js` | `46 B` | | `components/Toggle/script.js` | `3.7 kB` | | `components/Toggle/styles.css` | `3.5 kB` | | `components/TouchCapture/index.js` | `25 B` | | `components/TouchCapture/script.js` | `3.5 kB` | | `components/TransitionFadeIn/index.js` | `25 B` | | `components/TransitionFadeIn/script.js` | `2.3 kB` | | `components/TransitionResize/index.js` | `25 B` | | `components/TransitionResize/script.js` | `3.6 kB` | | `components/TransitionSpringLeft/index.js` | `25 B` | | `components/TransitionSpringLeft/script.js` | `2.3 kB` | | `components/TransitionSpringUp/index.js` | `25 B` | | `components/TransitionSpringUp/script.js` | `2.3 kB` | | `components/TransitionStaggered/index.js` | `25 B` | | `components/TransitionStaggered/script.js` | `2.5 kB` | | [`LICENSE`](https://github.com/square/maker/blob/theme-data-revision/LICENSE) | `552 B` | | [`package.json`](https://github.com/square/maker/blob/theme-data-revision/package.json) | `5.1 kB` | | [`README.md`](https://github.com/square/maker/blob/theme-data-revision/README.md) | `327 B` | | `utils/assert.js` | `1.1 kB` | | `utils/BlockFormControlLayout/index.js` | `46 B` | | `utils/BlockFormControlLayout/script.js` | `1.8 kB` | | `utils/BlockFormControlLayout/styles.css` | `234 B` | | `utils/css-validator.js` | `933 B` | | `utils/debug.js` | `1.0 kB` | | `utils/get-contrast.js` | `1.1 kB` | | `utils/InlineFormControlLayout/index.js` | `46 B` | | `utils/InlineFormControlLayout/script.js` | `2.5 kB` | | `utils/InlineFormControlLayout/styles.css` | `315 B` | | `utils/Transition/index.js` | `25 B` | | `utils/Transition/script.js` | `2.4 kB` | | `utils/TransitionResponsive/index.js` | `25 B` | | `utils/TransitionResponsive/script.js` | `2.2 kB` | | `utils/transitions.js` | `4.2 kB` |
Hidden files | File | Before | After | | ----------------------------------------------- | --------: | --------------------------: | | `components/ActionBar/script.js.map` | `55.4 kB` | -0.01%↓`55.4 kB` | | `components/ActionBar/styles.css.map` | `18.4 kB` | -0.04%↓`18.4 kB` | | `components/Blade/script.js.map` | `23.3 kB` | `23.3 kB` | | `components/Blade/styles.css.map` | `3.9 kB` | `3.9 kB` | | `components/Button/script.js.map` | `25.2 kB` | -0.03%↓`25.2 kB` | | `components/Button/styles.css.map` | `11.0 kB` | -0.06%↓`11.0 kB` | | `components/Calendar/script.js.map` | `29.6 kB` | -0.02%↓`29.6 kB` | | `components/Calendar/styles.css.map` | `10.4 kB` | -0.07%↓`10.4 kB` | | `components/Card/script.js.map` | `8.9 kB` | `8.9 kB` | | `components/Card/styles.css.map` | `729 B` | `729 B` | | `components/Checkbox/script.js.map` | `18.7 kB` | `18.7 kB` | | `components/Checkbox/styles.css.map` | `3.8 kB` | `3.8 kB` | | `components/Choice/script.js.map` | `20.7 kB` | -0.03%↓`20.7 kB` | | `components/Choice/styles.css.map` | `6.4 kB` | -0.11%↓`6.4 kB` | | `components/Container/script.js.map` | `18.2 kB` | -0.13%↓`18.2 kB` | | `components/Container/styles.css.map` | `5.1 kB` | -0.45%↓`5.1 kB` | | `components/Dialog/script.js.map` | `28.6 kB` | `28.6 kB` | | `components/Dialog/styles.css.map` | `6.8 kB` | `6.8 kB` | | `components/Divider/script.js.map` | `8.8 kB` | `8.8 kB` | | `components/Divider/styles.css.map` | `735 B` | `735 B` | | `components/Image/script.js.map` | `14.1 kB` | `14.1 kB` | | `components/Image/styles.css.map` | `2.9 kB` | `2.9 kB` | | `components/ImageUploader/script.js.map` | `46.0 kB` | `46.0 kB` | | `components/ImageUploader/styles.css.map` | `20.2 kB` | `20.2 kB` | | `components/Input/script.js.map` | `20.1 kB` | `20.1 kB` | | `components/Input/styles.css.map` | `4.9 kB` | `4.9 kB` | | `components/Loading/script.js.map` | `11.0 kB` | `11.0 kB` | | `components/Loading/styles.css.map` | `2.3 kB` | `2.3 kB` | | `components/Modal/script.js.map` | `34.9 kB` | `34.9 kB` | | `components/Modal/styles.css.map` | `10.7 kB` | `10.7 kB` | | `components/Notice/script.js.map` | `18.7 kB` | `18.7 kB` | | `components/Notice/styles.css.map` | `4.3 kB` | `4.3 kB` | | `components/PinInput/script.js.map` | `18.6 kB` | -0.04%↓`18.6 kB` | | `components/PinInput/styles.css.map` | `7.1 kB` | -0.1%↓`7.1 kB` | | `components/Popover/script.js.map` | `36.7 kB` | `36.7 kB` | | `components/Popover/styles.css.map` | `6.4 kB` | `6.4 kB` | | `components/ProgressBar/script.js.map` | `13.3 kB` | `13.3 kB` | | `components/ProgressBar/styles.css.map` | `2.6 kB` | `2.6 kB` | | `components/Radio/script.js.map` | `17.6 kB` | `17.6 kB` | | `components/Radio/styles.css.map` | `3.7 kB` | `3.7 kB` | | `components/SegmentedControl/script.js.map` | `14.3 kB` | -0.05%↓`14.3 kB` | | `components/SegmentedControl/styles.css.map` | `3.5 kB` | -0.2%↓`3.5 kB` | | `components/Select/script.js.map` | `23.0 kB` | `23.0 kB` | | `components/Select/styles.css.map` | `5.7 kB` | `5.7 kB` | | `components/Skeleton/script.js.map` | `17.8 kB` | `17.8 kB` | | `components/Skeleton/styles.css.map` | `3.0 kB` | `3.0 kB` | | `components/StarRating/script.js.map` | `22.3 kB` | `22.3 kB` | | `components/StarRating/styles.css.map` | `6.3 kB` | `6.3 kB` | | `components/Stepper/script.js.map` | `17.4 kB` | -0.04%↓`17.4 kB` | | `components/Stepper/styles.css.map` | `3.8 kB` | -0.18%↓`3.8 kB` | | `components/Text/script.js.map` | `22.3 kB` | -0.01%↓`22.3 kB` | | `components/Text/styles.css.map` | `11.5 kB` | -0.03%↓`11.5 kB` | | `components/Textarea/script.js.map` | `17.7 kB` | -0.1%↓`17.7 kB` | | `components/Textarea/styles.css.map` | `3.9 kB` | -0.44%↓`3.9 kB` | | `components/TextButton/script.js.map` | `16.9 kB` | -0.04%↓`16.9 kB` | | `components/TextButton/styles.css.map` | `4.3 kB` | -0.16%↓`4.3 kB` | | `components/Theme/script.js.map` | `27.4 kB` | -0.25%↓`27.3 kB` | | `components/Theme/styles.css.map` | `2.9 kB` | -3.97%↓`2.8 kB` | | `components/Toggle/script.js.map` | `19.6 kB` | `19.6 kB` | | `components/Toggle/styles.css.map` | `5.4 kB` | `5.4 kB` | | `components/TouchCapture/script.js.map` | `12.0 kB` | `12.0 kB` | | `components/TransitionFadeIn/script.js.map` | `10.5 kB` | `10.5 kB` | | `components/TransitionResize/script.js.map` | `14.4 kB` | `14.4 kB` | | `components/TransitionSpringLeft/script.js.map` | `10.5 kB` | `10.5 kB` | | `components/TransitionSpringUp/script.js.map` | `10.5 kB` | `10.5 kB` | | `components/TransitionStaggered/script.js.map` | `11.1 kB` | `11.1 kB` | | `utils/assert.js.map` | `4.2 kB` | `4.2 kB` | | `utils/BlockFormControlLayout/script.js.map` | `8.4 kB` | `8.4 kB` | | `utils/BlockFormControlLayout/styles.css.map` | `762 B` | `762 B` | | `utils/css-validator.js.map` | `3.3 kB` | `3.3 kB` | | `utils/debug.js.map` | `3.6 kB` | `3.6 kB` | | `utils/get-contrast.js.map` | `4.9 kB` | `4.9 kB` | | `utils/InlineFormControlLayout/script.js.map` | `12.6 kB` | `12.6 kB` | | `utils/InlineFormControlLayout/styles.css.map` | `1.4 kB` | `1.4 kB` | | `utils/Transition/script.js.map` | `10.7 kB` | `10.7 kB` | | `utils/TransitionResponsive/script.js.map` | `10.3 kB` | `10.3 kB` | | `utils/transitions.js.map` | `16.8 kB` | `16.8 kB` |

πŸ€– This report was automatically generated by pkg-size-action

pretzelhammer commented 2 years ago

I've updated the PR title from refactor to refactor! because this contains breaking changes

pretzelhammer commented 2 years ago

It appears that setting the button patterns data in the default theme doesn't work as expected. In this PR, I'm setting default colors for the primary / secondary variants, but even testing these changes manually on the beta they aren't working.

That branch isn't working because the Buttons styleguide doesn't use patterns yet, it's still on variants. I've made a new branch which updates the Button styleguide to use patterns so it's now responsive to changes in the default theme.

pretzelhammer commented 2 years ago

Since we know that others are using what was previously considered internal CSS properties and that changes to those properties now constitute breaking changes -- we should consider prefixing CSS properties (and eventually classes) we're generating to prevent collisions. maker-[token] for example.

This is reasonable and should be its own PR. I've made a PR for it here: https://github.com/square/maker/pull/305

github-actions[bot] commented 2 years ago

Styleguide deployed to https://square.github.io/maker/styleguide/theme-data-revision/#/

pretzelhammer commented 2 years ago

Change: Our theme-default sets data for colors.elevation and colors.overlay however, the data we've been passing into the theme object has explicitly included a hyphenated version of the token, despite being part of the same colors object. We should change the theme to accept the same color tokens that are set in the theme-default and be consistent with how all the other colors are named.

I think this is probably an oversight or a bug. I think this is reasonable as its own standalone task so I've made a PR for it: https://github.com/square/maker/pull/307

pretzelhammer commented 2 years ago

Leave alone: colors.text and colors.heading as generic global tokens are intended to apply to all headings and text. Changing these names to names like paragraph and title insinuates that the colors apply to less of our output. The original names were not selected because of labels in our largest consuming app, but primarily to define a spec that is more inline with definitions in other systems and agnostic to ever-changing product opinions. Our design tokens and data shouldn't need to change due to a single product UI.

We have title and paragraph text patterns, and the colors apply to those patterns, so it makes sense that the title color applies to the title text pattern. I think it's reasonable to keep the beta names as they are. Also, our design and data shouldn't need to change to fall in line with some arbitrary 3rd-party open source spec.

Add: colors.primary and colors.secondary is a great addition that provides a reusable mapping to our components, but also subsequently custom components or styling based on globally defined color profiles. We discovered that one piece of data we're setting globally called outlineButtonColor is missing in the global data which should directly map to our secondary button variant. So setting / passing both primary and secondary colors would be helpful for buttons and likely future scenarios.

We have colors.primary, and as Lauren said we don't really need a colors.secondary. The convention at the moment is to use colors.paragraph for any secondary/outline buttons, both internally in Maker and within Website. If Website needs to customize this they can override it within the button secondary pattern.

Change: (Worth debating) Simplify the fonts object and split into fonts and fontWeights, makes our tokens simpler and easier to type check and automate processing in the future.

I disagree. I find this harder to write and harder to cognitively parse:

fonts: { // is really only font family data, not general font data
    headline: 'etc',
    title: 'etc',
    paragraph: 'etc',
    label: 'etc',
},
fontWeights: {
    headline: '700',
    title: '500',
    paragraph: '400',
    label: '500',
},
fontColors: {
   headline: 'etc',
   title: 'etc',
   paragraph: 'etc',
   label: 'etc',
}

Than this:

fonts: {
    headline: {
        family: 'etc',
        color: 'etc',
        weight: '700',
    },
    title: {
        family: 'etc',
        color: 'etc',
        weight: '500',
    },
    paragraph: {
        family: 'etc',
        color: 'etc',
        weight: '400',
    },
    label: {
        family: 'etc',
        color: 'etc',
        weight: '500',
    },
},

In the former example, if I want to understand how a headline will be rendered, I have to look at n-different sub-objects stitch it together in my head. In the latter example I just have to look at one place and all the headline data is there. The latter is much simpler imo.

  • Change: body instead of paragraph.
  • Change: heading instead of title.

Since we have title and paragraph text patterns I think it's nice to keep the global names consistent with the individual pattern names.

Change: CSS property naming conventions. As we defined with the colors we've begun to establish a good pattern of [tokenCategory].[token].[value] and making our CSS properties consistent with those names. We've begun to establish the singular form of the token category. So colors.primary easily translates to --color-primary. As we look at our fonts, we should do the same thing. fonts.body easily translates to --font-body. Depending on some decisions make around the font vs fontWeight data structure -- this translation to the CSS property should be maintained.

No. We want to maintain a layer of abstraction between the theme spec & the public CSS API. We should never make any promises about how one is turned into the other. This is especially important if we ever want to make changes to the theme spec or the public CSS API without affecting the other. It's further important if we want to add design tokens to the theme spec that do not have a 1:1 relationship to some existing CSS property. A good example of this is shape. We may add shape: 'squared' | 'rounded' | 'pill' to the theme spec and it makes no sense to expose a --shape: 'squared' | 'rounded' | 'pill' to the public CSS API because that is not a valid CSS property.

I think exposing a pattern concept as an alternative to both global design tokens and variants is premature, particularly since this concept is limited to two components where one is already using variants. While I appreciate it's solving a problem, I think we should keep the concept internal until we can refactor our code to have a more robust theming system with variants.

patterns === variants. They're the same thing, just have a different name.

landondurnan commented 2 years ago

Much of this PR has been addressed in other smaller separate PRs.