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

Add Theo support to Rollup configuration #788

Closed
wants to merge 4 commits into from

Conversation

tylersticka
Copy link
Member

@tylersticka tylersticka commented Jun 10, 2020

Overview

Adds support for importing tokens from Theo configuration files in YAML format. (There is a Rollup plugin for Theo, but it appears to only transform to CSS.)

Tokens use the module.js format, which converts tokens into ES exports.

So given a token file like this:

aliases:
  black_transparent_85: 'rgba(0, 0, 0, 0.85)'
props:
  - name: text_dark
    value: '{!black_transparent_85}'
    category: text-color
    comment: Accessible on white and lightest gray.

And JavaScript source like this:

import * as colors from 'path/to/design-tokens/colors.yml';

console.log(colors.textDark);

The compiled JavaScript will look like this:

/* Accessible on white and lightest gray. */
const textDark = "rgba(0, 0, 0, 0.85)";

console.log(textDark);

This also adds usage examples in JavaScript to the design token pages.

Screenshots

Screen Shot 2020-06-10 at 12 11 35 PM

Testing

  1. Check out branch locally.
  2. Attempt to import a design token of your choosing using one of those documented in Storybook. (To avoid having to create a new file, try adding it to the Elastic Textarea script.)
  3. Run npm run build
  4. See if the token made it to dist/cloudfour-patterns.js.

@changeset-bot
Copy link

changeset-bot bot commented Jun 10, 2020

💥 No Changeset

Latest commit: 5124da6

Merging this PR will not cause any packages to be released. If these changes should not cause updates to packages in this repo, this is fine 🙂

If these changes should be published to npm, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@tylersticka
Copy link
Member Author

@calebeby When I go through my own testing steps, Typescript complains that it can't figure out the types from the token file. Any ideas for how I could resolve that?

@calebeby
Copy link
Member

@tylersticka You can add a declaration block like this: https://github.com/cloudfour/cloudfour.com-patterns/blob/v-next/src/types.ts#L1-L4

In this case, each yaml file can have infinitely many exports, and TS will not be able to know those. I don't know of any way to tell TS "anything can be imported from this module". This is the closest I could get:

declare module '*.yml' {
  const tokens: Record<string, any>;
  export = tokens;
}

Then it only allows importing as namespace, for some reason:

import * as colors from '../../design-tokens/colors.yml';

console.log(colors.purple_light);

@tylersticka
Copy link
Member Author

@calebeby Would we be able to avoid this issue somehow if we made a new Theo module, like a module.ts?

Module definitions are pretty simple. Here's the module.js one we're currently using: https://github.com/salesforce-ux/theo/blob/master/lib/formats/module.js.js

Is there some way we could add more info that way, or is it more that Typescript doesn't know how we're using it within our project JS file?

(Apologies if these are dumb questions.)

@calebeby
Copy link
Member

@tylersticka That would only work if it actually writes .ts or .d.ts files to the filesystem. TS doesn't know about the rollup or webpack build.

There is a similar problem with CSS Modules, and they solved it by automatically writing .d.ts files to disk: https://github.com/Quramy/typed-css-modules

@calebeby
Copy link
Member

There is a discussion here: salesforce-ux/theo#174 (comment)

@tylersticka
Copy link
Member Author

@calebeby

Then it only allows importing as namespace, for some reason:

If we do it that way, do you know if Rollup's tree-shaking will remove the unused variables for us, or will all of colors hang out even if we aren't using more than one variable therein?

@tylersticka
Copy link
Member Author

Awesome!

So in that case, I think your first suggestion probably makes the most sense for now. Do you agree?

@calebeby
Copy link
Member

Yeah probably. export = tokens feels like a hack for this scenario, and it is really weird that that makes namespace imports work but not named imports.

But for now, that is probably the easiest solution 👍

Maybe in the future we can add an npm script that generates .d.ts files for each yml file, (or we can make the rollup or webpack plugin do it), but for now that isn't necessary

@tylersticka
Copy link
Member Author

@calebeby One issue with that approach... it looks like we'll have to disable the no-unsafe-member-access rule every single time we reference one of these properties.

I might take a look at the other approach later unless you're aware of a quick fix.

@calebeby
Copy link
Member

I would be fine with disabling that rule globally, I did not realize it was enabled

@tylersticka
Copy link
Member Author

@calebeby After making these changes and using one of the tokens, buildTypes results in an error:

src/components/input/elastic-textarea.ts(1,25): error TS2307: Cannot find module '../../design-tokens/colors.yml' or its corresponding type declarations.

Previously npm run build ran fine, but npm run type failed. Now that is reversed.

@tylersticka
Copy link
Member Author

@calebeby Looking at this again, I think I can generate modules and declarations pretty easily. Trying it out instead. Might be nicer to use overall.

@tylersticka
Copy link
Member Author

This is no longer necessary now that #790 has been merged.

@tylersticka tylersticka deleted the feature/rollup-theo branch June 16, 2020 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Figure out how to consume design tokens in client-side JS
2 participants