Skip to content
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

feat: updating to Style Dictionary v4 #3186

Open
wants to merge 16 commits into
base: alpha
Choose a base branch
from

Conversation

PKulkoRaccoonGang
Copy link
Contributor

@PKulkoRaccoonGang PKulkoRaccoonGang commented Aug 20, 2024

Description

This PR is an attempt to update the Style Dictionary v3 library to Style Dictionary v4 (including refactoring the design tokens to the DTCG format) + fixed some problems with typography.

Merge Checklist

  • If your update includes visual changes, have they been reviewed by a designer? Send them a link to the Netlify deploy preview, if applicable.
  • Does your change adhere to the documented style conventions?
  • Do any prop types have missing descriptions in the Props API tables in the documentation site (check deploy preview)?
  • Consider whether this change needs to reviewed/QA'ed for accessibility (a11y). If so, please request an a11y review for the PR in the #wg-paragon Open edX Slack channel.
  • Were your changes tested using all available themes (see theme switcher in the header of the deploy preview, under the "Settings" icon)?
  • Were your changes tested in the example app?
  • Is there adequate test coverage for your changes?

Post-merge Checklist

  • Verify your changes were released to NPM at the expected version.
  • If you'd like, share your contribution in #show-and-tell.
  • 🎉 🙌 Celebrate! Thanks for your contribution.

@PKulkoRaccoonGang PKulkoRaccoonGang self-assigned this Aug 20, 2024
@openedx-webhooks
Copy link

openedx-webhooks commented Aug 20, 2024

Thanks for the pull request, @PKulkoRaccoonGang!

What's next?

Please work through the following steps to get your changes ready for engineering review:

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.

🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads

🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

🔘 Let us know that your PR is ready for review:

Who will review my changes?

This repository is currently maintained by @openedx/paragon-working-group. Tag them in a comment and let them know that your changes are ready for review.

Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Aug 20, 2024
Copy link

netlify bot commented Aug 20, 2024

Deploy Preview for paragon-openedx ready!

Name Link
🔨 Latest commit 0ea4cb8
🔍 Latest deploy log https://app.netlify.com/sites/paragon-openedx/deploys/67346033d9021f0008ca0d99
😎 Deploy Preview https://deploy-preview-3186--paragon-openedx.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@PKulkoRaccoonGang PKulkoRaccoonGang marked this pull request as draft August 20, 2024 19:04
@PKulkoRaccoonGang
Copy link
Contributor Author

PKulkoRaccoonGang commented Aug 20, 2024

TODO

  • - correct display of the header of generated files
  • - checking the correctness of variable generation (for some variables you can notice an extra indication of the unit of measurement, for example 0rem)

...

ES6 modules
Since the updated Style Dictionary v4 API is based on ES6 modules, an open question is finding a solution for the correct operation of Style Dictionary v4 together with the existing CommonJS functionality of Gatsby. According to the Gatsby documentation, support for ES6 modules is implemented in more recent releases of the framework. Most likely, for the current version of Gatsby (4.23.1), a potential solution could be to use dynamically imports or update the Gatsby version.

@brian-smith-tcril
Copy link
Contributor

Thank you so much for putting this together! Considering the task of "do some discovery around v4" this is truly above and beyond!

checking the correctness of variable generation (for some variables you can notice an extra indication of the unit of measurement, for example 0rem)

I think it's reasonable to update the .json files to include units where we don't yet have them as a solution here.

Since the updated Style Dictionary v4 API is based on ES6 modules, an open question is finding a solution for the correct operation of Style Dictionary v4 together with the existing CommonJS functionality of Gatsby. According to the Gatsby documentation, support for ES6 modules is implemented in more recent releases of the framework. Most likely, for the current version of Gatsby (4.23.1), a potential solution could be to use asynchronous imports or update the Gatsby version.

Could you elaborate on this a bit? I worry that moving from Gatsby v4 to v5 would be quite a heavy lift, and I wonder how that compares to some workarounds people have tried gatsbyjs/gatsby#31599 (comment)

@brian-smith-tcril
Copy link
Contributor

Just adding a note based on the discussion in the Paragon WG meeting today:

The migration guidelines have a few suggestions for how to handle this - one that seemed to be a good candidate was

dynamically import Style Dictionary into your CommonJS files const StyleDictionary = (await import('style-dictionary')).default;

Copy link

codecov bot commented Aug 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 93.76%. Comparing base (0e16dbb) to head (0ea4cb8).

Additional details and impacted files
@@            Coverage Diff             @@
##            alpha    #3186      +/-   ##
==========================================
- Coverage   93.76%   93.76%   -0.01%     
==========================================
  Files         229      229              
  Lines        3787     3784       -3     
  Branches      908      906       -2     
==========================================
- Hits         3551     3548       -3     
- Misses        229      232       +3     
+ Partials        7        4       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

package.json Outdated Show resolved Hide resolved
styles/css/core/variables.css Outdated Show resolved Hide resolved
tokens/src/core/components/ActionRow.json Outdated Show resolved Hide resolved
}
"base": { "source": "$card-border-radius", "$value": "{size.border.radius.base}" },
"logo": { "source": "$card-logo-border-radius", "$value": ".25rem" },
"inner": { "source": "$card-inner-border-radius", "$value": "calc({size.card.border.radius.base} - {size.card.border.width})" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[curious] Have we looked into whether we can avoid including CSS-specific syntax calc in the token itself, or how such tokens would be transformed outside of CSS variables?

For example, if there is arithmetic like subtraction as in this line, could the token $value be {size.card.border.radius.base} - {size.card.border.width} and have some sort of transform for the CSS variables output to wrap it with calc(...)?

That way, tokens like these would be more portable to other non-CSS based platforms like mobile.

Copy link
Member

@adamstankiewicz adamstankiewicz Sep 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dug into this a bit. It appears this still remains a complex problem within the style-dictionary community. There is support for a resolveMath transform, from tokens-studio/sd-transforms; however, when the token outputs references via outputReferences: true | fn, the transformed/resolved math is replaced with the original reference (i.e., a CSS variable with var(--foo: 5px) in this case).

I attempted to craft a solution for tokens-studio/sd-transforms#203, but came to the same realization recently described here:

The big issue is that outputting refs happens on the format lifecycle and wrapping values in calc() statements usually happens in the transform lifecycle that happens before. So even if you wrap the values in calc() in transform, the format part will just undo that work by outputting refs by using the original value.

Either the calc wrapping needs to happen on the format level or the outputting refs util needs to act on the transformed value somehow (keeping in mind the bugs that this used to cause in v3 and not regressing on this again)

There are a couple of open issues to rethink how references are resolved and how values with references in them are transformed for a future v5 version of Style Dictionary, but this topic is rather complex and this issue won't be fixed until we have solutions to that broader topic.

tl;dr; Handling the wrapping of math expressions with the CSS calc syntax remains an open question, and likely will not land in v4 of Style Dictionary per the above. Given this, it probably makes sense to keep the calc syntax for now, but when we begin transforming to non-CSS platforms (e.g., JavaScript, iOS, Android), having calc in the token value itself will present an issue. A possible workaround for if/when this becomes an issue might be to introduce custom transforms for the (future) non-CSS platforms that strips the wrapping calc(...) from the underlying math operations used in the token value.

Copy link
Contributor Author

@PKulkoRaccoonGang PKulkoRaccoonGang Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely a very interesting question that we haven't thought about yet. Thanks for your research, now we know more!

A possible workaround for if/when this becomes an issue might be to introduce custom transforms for the (future) non-CSS platforms that strips the wrapping calc(...) from the underlying math operations used in the token value.

It seemed to me earlier that when adding mobile platforms, Style Dictionary would generate the necessary variables taking into account the various CSS tools (calc) that we use for design tokens, converting them into alternatives acceptable for mobile platforms.

I also consulted with Android and iOS developers from Raccoon Gang, they confirmed that there is no alternative to calc CSS. There are tools to do this in the languages ​​of mobile platforms, but it is desirable that Paragon design tokens provide static (integer) values ​​for variables.

I agree with you, most likely in the future (if there are no new Style Dictionary updates) we will have to make additional modifiers for mobile platforms.

Android

<resources>
    <dimen name="size_card_border_radius_base">16dp</dimen>
    <dimen name="size_card_border_width">2dp</dimen>
</resources>

iOS

<plist version="1.0">
<dict>
    <key>size_card_border_radius_base</key>
    <string>16</string>
    <key>size_card_border_width</key>
    <string>2</string>
</dict>
</plist>

Resources

tokens/src/core/components/general/link.json Outdated Show resolved Hide resolved
tokens/src/core/global/other.json Outdated Show resolved Hide resolved
tokens/src/core/global/typography.json Outdated Show resolved Hide resolved
tokens/src/themes/light/components/Avatar.json Outdated Show resolved Hide resolved
tokens/style-dictionary.js Outdated Show resolved Hide resolved
tokens/style-dictionary.js Outdated Show resolved Hide resolved
…s format (#3203)

* feat: --output-references CLI arg for build-tokens, registers filters, and updates CSS vars format

* Exposes `--output-references` CLI argument for `build-tokens` command. Defaults to `true`. Ensures brand package output with the CLI includes references in build output out-of-the-box.

* Registers filter(s) `isThemeVariant.{'light'}`, handling future theme variants when implemented (e.g., `isThemeVariant.dark`).
* Migrates `createCustomCSSVariables` to use `formattedVariables` to rely on out-of-the-box CSS variable formatting. The formatter still supports token-specific overrides of `outputReferences`. If a token has modifications via `modify`, the modified base reference is not included in the output.
* Updates custom fileHeader implementation, including a relative path to design tokens documentation.
* Fixes bug with line-height tokens, switching their `$type` from `dimension` to `number` to resolve typography style regressions.
* Updates typography tokens related to font size, font weight, and line-height for more consistent naming structure when taking into account mobile.
* Updates `@mobile-type` SCSS mixin to support level-specific customization of mobile typography styles for display 1-4.
* Renames `"description"` field in tokens to `"$description""` per the DTCG format.

* Ensures the "Typography" foundations page properly previews the correct font size for regular "Body" text and includes the missing "HEADING LABEL" example.
* Updates to "Colors" page in docs site:
  * Displays token name instead of CSS variable in the color swatch previews (see screenshot below).
  * Include `accent-a` and `accent-b` alongside other color names, rather than manually rendering `Swatch` for the accents.
  * Modifies the grid styles for color swatch preview to be more responsive.
* Resolves `NaNpx` bug in `MeasuredItem` component on docs site, while computing the measurements to display for an element (e.g., font size). Instead, it renders an empty block while measurements are resolved.
* Updates `CodeBlock` styles on docs site to add its border and background color only to the `LivePreview`, not the entire `CodeBlock` example.
* Reduces whitespace on docs site homepage.
* Simplifies columns on docs site header, ensuring `SiteTitle` is horizontally aligned in the center.
@PKulkoRaccoonGang PKulkoRaccoonGang marked this pull request as ready for review September 4, 2024 09:00
lib/build-tokens.js Show resolved Hide resolved
"source": "$lead-font-size",
"description": "Lead text font size."
"$value": "{typography.font.size.base} * 1.25",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D'oh, I think in my commit I lost the calc(...) that was previously wrapping this token's $value (this was the only token I experimented with). When previewing the docs site locally, the .lead utility class isn't working properly anymore, noticed first on the home page. Adding calc(...) back in will resolve.

[context] This was removed while exploring the sd-transforms transform for ts/resolveMath to see if we could abstract away calc, but as discussed in another comment, there is not currently a great solution for this, so we need to keep calc in here, at least for now :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform] Implemented in follow-up PR: #3222

@@ -1,32 +1,33 @@
{
"typography": {
"code": {
"font-size": { "value": "87.5%", "type": "percentage", "source": "$code-font-size" },
"font-size": { "source": "$code-font-size", "$value": "87.5%", "$type": "percentage" },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] I believe this 87.5% is equivalent to the {typography.font.size.sm} if we wanted to treat this token an alias to a semantic token (i.e., if/when {typography.font.size.sm} changes, this token will also change).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small difference exists between 87.5% and 0.875rem. The 87.5% value is calculated relative to the font size of the parent element. For example, if the parent has a font size of 16px, then 87.5% will be equivalent to 14px. However, if the parent font size is different, the resulting pixel value will change accordingly.

In contrast, 0.875rem is always calculated relative to the root element’s (<html>) base font size, which is typically 16px by default in browsers. Thus, 0.875rem will consistently be equivalent to 14px as long as the html font size is 16px, regardless of the parent element’s font size.

Currently, when using the 0.875rem value from the token {typography.font.size.sm}, the value is indeed calculated relative to the root font size of the html tag (16px = 1rem). The previous percentage value of 87.5% was calculated based on the parent font size of 1.125rem (the font size of the body).

I suggest using 87.5%, what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform] Implemented in follow-up commit: 6676868 (#3186)

Comment on lines 41 to 49
"sm": {
"source": "$small-font-size",
"$value": ".875rem",
"$description": "Small font size."
},
"xs": {
"source": "$x-small-font-size",
"$value": ".75rem",
"$description": "X-small font size."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing the computed typography values in the docs for this PR's local checkout vs. published docs site, it looks like we might actually want/need to keep the % scale these tokens originally had.

For example, x-small used to be 75% but we migrated it to .75rem, which seems to result in slightly different font sizes. Note the .small and .x-small examples specifically (left: local; right: prod):

image

[aside] Related, you might notice the line heights are also slightly off for some of them as well. This seems to be due to the switch to DataTable, where some of the cell content is inheriting DataTable's line-height styles, i.e. .pgn__data-table td (left: local; right: prod):

image

I suppose we could consider overriding DataTable's default CSS styles for typography example tables by unset'ing the line-height related definition(s), or maybe cross-check whether the CSS utility classes are defining explicit line-height style properties vs. inheriting from its parent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we will definitely need to do a full check of all tokens after the latest changes, as we can easily miss some small detail that can have a significant impact on both the components and the documentation site. Thanks! 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform] Implemented in follow-up commit: 6676868 (#3186)

"$value": "5.625rem",
"$description": "Font size for heading of level 3."
},
"4": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a local checkout of the docs site from this branch, it looks like the migrate of typography example tables to use DataTable is inheriting its overflow: hidden on table cells, cutting off the text of "Display 4" on smaller screen sizes. Probably not a big deal, but figured I'd flag it as it could be perceived as a style bug potentially.

image image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform] Implemented in follow-up commit: 6676868 (#3186)

"base": { "value": "none", "type": "textDecoration", "source": "$link-decoration" },
"hover": { "value": "underline", "type": "textDecoration", "source": "$link-hover-decoration" },
"$type": "textDecoration",
"base": { "source": "$link-decoration", "$value": "none" },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform, docs site bug] The "Links" section on the typography foundations page is incorrectly showing text-decoration: underline; on "standalone links" (left: local; right: prod):

image

It appears this is due to the migration of the example tables to DataTable, where the TextCell is wrapping the cell content with a p, which according to the table description, "For links inside a p...", the standalone links are actually getting treated as inline links even without the explicit .inline-link class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform] Implemented in follow-up commit: 6676868 (#3186)

refactor: corrected expanded tokens

refactor: code refactoring

refactor: created an abstracted CSS variables

refactor: added missing expanded tokens

refactor: added missing expanded tokens

refactor: small refactoring after review

refactor: corrected imports for CSS files

feat: expanded --pgn-transition-carousel-base token, some refactoring

fix: corrected --pgn-transition-base-timing-function value

refactor: some refactoring and updates

refactor: corrected progress-bar and typography tokens
@PKulkoRaccoonGang PKulkoRaccoonGang force-pushed the Peter_Kulko/style-dictionary-v4 branch 3 times, most recently from 6676868 to 1be86b9 Compare October 28, 2024 07:52
@PKulkoRaccoonGang
Copy link
Contributor Author

@brian-smith-tcril @adamstankiewicz In this commit we removed the brand-openedx theme. Do we want to remove the sidebar toggle button and any mention of the brand in Paragon?

image

Copy link
Contributor

@brian-smith-tcril brian-smith-tcril left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is looking really great! I left a few comments with questions, but it's awesome to see v4 so close to ready!

lib/build-tokens.js Show resolved Hide resolved
lib/build-tokens.js Show resolved Hide resolved
lib/build-tokens.js Show resolved Hide resolved
lib/build-tokens.js Outdated Show resolved Hide resolved
src/Card/CardDeck.jsx Show resolved Hide resolved
styles/css/core/custom-media-breakpoints.css Show resolved Hide resolved
styles/scss/core/_utilities.scss Show resolved Hide resolved
tokens/src/core/components/CloseButton.json Show resolved Hide resolved
bin/paragon-scripts.js Outdated Show resolved Hide resolved
Comment on lines +4 to +10
"base": { "source": "$avatar-size", "$value": "3rem", "$type": "dimension" },
"xs": { "source": "$avatar-size-xs", "$value": "1.5rem", "$type": "dimension" },
"sm": { "source": "$avatar-size-sm", "$value": "2.25rem", "$type": "dimension" },
"lg": { "source": "$avatar-size-lg", "$value": "4rem", "$type": "dimension" },
"xl": { "source": "$avatar-size-xl", "$value": "6rem", "$type": "dimension" },
"xxl": { "source": "$avatar-size-xxl", "$value": "11.5rem", "$type": "dimension" },
"huge": { "source": "$avatar-size-huge", "$value": "18.75rem", "$type": "dimension" },
Copy link
Member

@adamstankiewicz adamstankiewicz Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nit: might recommend keeping source the last property defined, as the other properties like $value, and $type are more critical (i.e., source is only needed to support the Paragon CLI tools to help migrate from SCSS to CSS variables and vice-versa).

Edit: feel free to ignore/defer. Not critical for release. Would likely take awhile to update across all tokens/files.

Copy link
Contributor Author

@PKulkoRaccoonGang PKulkoRaccoonGang Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, that's a good idea 👍
I would also leave some documentation somewhere about what rules to follow when creating/editing design tokens. Since it's not entirely obvious what sequence should be present in design tokens. I think we should stop at something like this:

  1. $value
  2. description
  3. outputReferences
  4. modify
  5. source

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform]: We have a draft PR providing additions of a linter for JSON files and a sorter script
#3285

@@ -1,19 +1,61 @@
{
"elevation": {
"$type": "ratio",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[sanity check] Does ratio make sense as the type (see DTCG format spec's description of the ratio type)? Perhaps we want this to be "$type": "number" since it's really just a number (docs)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform] Implemented in follow-up PR: #3286

"border": {
"width": { "value": "1px", "type": "dimension", "source": "$border-width", "description": "Default border width." },
"width": { "source": "$border-width", "$value": "1px", "$description": "Default border width." },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[curious] Cross-checking the dimension type with the DTCG spec again, I noticed that it seems you can also define the dimension value and its unit separately, e.g.:

{
  "size": {
    "$type": "dimension",
    "border": {
      "width": {
        "$value": {
          "value": 1,
          "unit": "px"
        }
      }
     }
  }
}

Not sure if this is something style-dictionary v4 supports out-of-the-box. Do we think it's worth exploring defining dimension token values and units separately vs. combined as we have it today (i.e., "$value": "1px").

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is what is documented in the DTCG spec I'd think we'd want to move forward with this change. Let's verify this works with style-dictionary v4 and figure out next steps from there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open-source-contribution PR author is not from Axim or 2U
Projects
Status: In Eng Review
Development

Successfully merging this pull request may close these issues.

4 participants