Skip to content

Commit 607a995

Browse files
authored
Merge pull request #1834 from chanzuckerberg/release-v13.9.0
## [13.9.0](v13.8.1...v13.9.0) (2024-01-19) [Storybook](https://61313967cde49b003ae2a860-utfzotmwuw.chromatic.com/) ### Features * **Avatar:** adjust typography usages and sizing for icons ([#1830](#1830)) ([7da31e6](7da31e6)) * **InlineNotification:** remove deprecated variants ([#1833](#1833)) ([cfcf1fa](cfcf1fa)) * **Label:** mark optional as deprecated ([#1832](#1832)) ([8067082](8067082)) * **tokens:** output token literal values in a new tailwind config file ([#1828](#1828)) ([08fa1c4](08fa1c4)) ### Bug Fixes * **InputField:** mark unused prop as deprecated ([#1831](#1831)) ([622abfb](622abfb)) * **Select:** update incorrect documentation ([#1825](#1825)) ([94aace5](94aace5))
2 parents 7ae38fe + dc5db0a commit 607a995

27 files changed

+1253
-1085
lines changed

.storybook/components/Docs/Guidelines/Theming.stories.mdx

+19-9
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,29 @@ Below are instructions on how to use the tooling and tokens to define custom the
1515
EDS comes with some tooling to allow easy transfer of theme data from Figma (or some style-dictionary compatible format) into code.
1616

1717
* `eds-init-theme` - This command sets up the initial file(s) for theming your application
18-
* `eds-apply-theme` - This command parses the style dictionary files to generate the tokens (CSS Variables) used by EDS
18+
* `eds-apply-theme` - This command parses the style dictionary files to generate the tokens used by EDS (and tailwind, or other tools)
1919

2020
Each of these tools reads config to figure out where to read/write files. This can be defined in several ways, e.g., a top-level file `.edsrc.json`, or as a key-value set in package.json. Example:
2121

2222
`package.json`
2323

2424
```json
2525
"eds": {
26-
"json": "src/components/",
27-
"css": "src/components/"
26+
"src": "src/components/",
27+
"dest": "src/components/"
2828
},
2929
```
3030

3131
`.edsrc.json`
3232

3333
```json
3434
{
35-
"json": "src/components/",
36-
"css": "src/components/"
35+
"src": "src/components/",
36+
"dest": "src/components/"
3737
}
3838
```
3939

40-
`json` determines where the core theme file will be copied to OR read from, and `css` determines where the resulting css token file will be stored.
40+
`src` determines where the core theme file will be copied to (upon init) OR read from (upon apply), and `dest` determines where the processed files will be written to.
4141

4242
### eds-init-theme
4343

@@ -79,9 +79,9 @@ EDS comes pre-packaged with many tokens that define the base style and character
7979

8080
### eds-apply-theme
8181

82-
After making changes to the `app-theme.json` to reflect what has been defined by design, update the CSS token file by running `npx eds-apply-theme`.
82+
After making changes to the `app-theme.json` to reflect what has been defined by design, update the project's theme files by running `npx eds-apply-theme`.
8383

84-
Once run, you will have a CSS file `app-theme.css` that includes a set of token values that can be used in the app as appropriate.
84+
Once run, you will have a CSS file `app-theme.css` that includes a set of token values as CSS variables, which can be used in the app as appropriate.
8585

8686
```css
8787
/**
@@ -101,7 +101,17 @@ Once run, you will have a CSS file `app-theme.css` that includes a set of token
101101
}
102102
```
103103

104-
Add this file to your core app root file. That's it! Now, the theme will be applied to the tokens used by EDS components. To make other changes, edit `app-theme.json`, then re-run `npx eds-apply-theme`.
104+
Add this file to your core app root file.
105+
106+
This also generates an additional file `app-tailwind-theme.config.json` which contains [useful tailwind configuration](https://github.com/chanzuckerberg/edu-design-system?tab=readme-ov-file#tailwind-setup) for EDS-specific utility classes
107+
This will also show a preview of the tokens in your IDE of choice. To use this config, replace the import from the package with a link to this files location:
108+
109+
```diff
110+
-const edsConfig = require('@chanzuckerberg/eds/tailwind.config');
111+
+const edsConfig = require('./src/components/app-tailwind-theme.config');
112+
```
113+
114+
That's it! Now, the theme will be applied to the tokens used by EDS components. To make other changes, edit `app-theme.json`, then re-run `npx eds-apply-theme`.
105115

106116
**NOTE**: do not edit this file directly. Instead, follow the instructions at the top of the file!
107117

CHANGELOG.md

+16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
## [13.9.0](https://github.com/chanzuckerberg/edu-design-system/compare/v13.8.1...v13.9.0) (2024-01-19)
6+
7+
8+
### Features
9+
10+
* **Avatar:** adjust typography usages and sizing for icons ([#1830](https://github.com/chanzuckerberg/edu-design-system/issues/1830)) ([7da31e6](https://github.com/chanzuckerberg/edu-design-system/commit/7da31e6d8f9dc973ae03b9337c33bbe00bf7a666))
11+
* **InlineNotification:** remove deprecated variants ([#1833](https://github.com/chanzuckerberg/edu-design-system/issues/1833)) ([cfcf1fa](https://github.com/chanzuckerberg/edu-design-system/commit/cfcf1fae674215cac8fb3ca2101ef77758ecb3c8))
12+
* **Label:** mark optional as deprecated ([#1832](https://github.com/chanzuckerberg/edu-design-system/issues/1832)) ([8067082](https://github.com/chanzuckerberg/edu-design-system/commit/806708291d9dc8733eee3b782c29cb1409f1cb95))
13+
* **tokens:** output token literal values in a new tailwind config file ([#1828](https://github.com/chanzuckerberg/edu-design-system/issues/1828)) ([08fa1c4](https://github.com/chanzuckerberg/edu-design-system/commit/08fa1c4783651d815939f735d4ed55d360b473aa))
14+
15+
16+
### Bug Fixes
17+
18+
* **InputField:** mark unused prop as deprecated ([#1831](https://github.com/chanzuckerberg/edu-design-system/issues/1831)) ([622abfb](https://github.com/chanzuckerberg/edu-design-system/commit/622abfb0e5a29ab5aaf38a8f9ea08c1bf76308b1))
19+
* **Select:** update incorrect documentation ([#1825](https://github.com/chanzuckerberg/edu-design-system/issues/1825)) ([94aace5](https://github.com/chanzuckerberg/edu-design-system/commit/94aace5ecda613600de23566c85304bb415b3765))
20+
521
### [13.8.1](https://github.com/chanzuckerberg/edu-design-system/compare/v13.8.0...v13.8.1) (2024-01-04)
622

723
## [13.8.0](https://github.com/chanzuckerberg/edu-design-system/compare/v13.7.1...v13.8.0) (2023-12-06)

README.md

+3-6
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ module.exports = {
5252
};
5353
```
5454

55-
This will replace the default color tokens that come [with Tailwind](https://tailwindcss.com/docs/customizing-colors) with those defined by EDS. **NOTE**: this might cause regressions in your project, if you have been using the default colors from tailwind.
55+
This will replace the default color tokens that come [with Tailwind](https://tailwindcss.com/docs/customizing-colors) with those defined by EDS. **NOTE**: this might cause regressions in your project, if you have been using the default colors provided by tailwind.
5656

5757
#### Applying the EDS tailwind extensions piecemeal
5858

@@ -63,7 +63,7 @@ If you want a gentler transition to using EDS tailwind config, you can instead i
6363
const edsConfig = require('@chanzuckerberg/eds/tailwind.config');
6464

6565
module.exports = {
66-
content: ['./app/**/*.{ts,tsx,jsx,js}'],
66+
// ...
6767
theme: {
6868
extend: {
6969
...edsConfig.theme.extend
@@ -74,9 +74,7 @@ module.exports = {
7474

7575
This will add in the utility classes for properties like background color `bg-*`, border `border-*`, and text color `text-*`. These match the styles and variables defined in Figma designs.
7676

77-
You can spread each of the sub-objects in `theme` as desired, e.g., `fontSize`, `fontWeight`, etc.
78-
79-
Refer to the [tokens tailwind section][tokens] for usage guidelines.
77+
Refer to the [tokens tailwind section][tokens] for usage guidelines if your project uses the theming tooling.
8078

8179
[tokens]: https://chanzuckerberg.github.io/edu-design-system/?path=/docs/documentation-guidelines-tokens--docs
8280

@@ -102,7 +100,6 @@ EDS also provides the tokens used in the internal styles, to use in any custom c
102100

103101
Refer to the "EDS Token and Theme Tools" in [the tokens documentation](https://chanzuckerberg.github.io/edu-design-system/?path=/docs/documentation-theming--docs) to learn about the optional tooling setup.
104102

105-
106103
## Usage
107104

108105
Import any of the components from the top-level package:

bin/_util.js

+120-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,129 @@ module.exports = {
1515
// If no config exists, fail
1616
if (!settings) {
1717
throw new Error(
18-
'Please add EDS config to your project before continuing (specify "json" and "css" target paths)',
18+
'Please add EDS config to your project before continuing (specify "src" and "dest" target paths)',
19+
);
20+
}
21+
22+
/**
23+
* TODO: Remove the old names for the input/output keys in the config at a future major version
24+
* json => src
25+
* css => dest
26+
*/
27+
if (settings.config.json) {
28+
settings.config.src = settings.config.json;
29+
console.warn(
30+
'WARNING: You are using "json" in your config. Please replace with "src".',
31+
);
32+
}
33+
34+
if (settings.config.css) {
35+
settings.config.dest = settings.config.css;
36+
console.warn(
37+
'WARNING: You are using "css" in your config. Please replace with "dest".',
1938
);
2039
}
2140

2241
return settings.config;
2342
},
43+
/**
44+
* Utilities for handling generation of tokens in various formats.
45+
*
46+
* These will be used when preparing files upon publish, and are used with tooling provided by EDS to
47+
* consumers.
48+
*/
49+
/**
50+
* Function to handle various minimizing tasks on style-dictionary rows, where a value to transform exists
51+
*
52+
* @param {StyleObject} obj Metadata object produced from style-dictionary
53+
* @param {Function} formatFunc function containing all the metadata for a given token
54+
* @returns object representing the full transformed token object
55+
*/
56+
minifyDictionaryUsingFormat: function (obj, formatFunc) {
57+
if (typeof obj !== 'object' || Array.isArray(obj)) {
58+
return obj;
59+
}
60+
61+
const toRet = {};
62+
63+
if (obj.hasOwnProperty('value')) {
64+
return formatFunc(obj);
65+
} else {
66+
for (const name in obj) {
67+
toRet[name] = module.exports.minifyDictionaryUsingFormat(
68+
obj[name],
69+
formatFunc,
70+
);
71+
}
72+
}
73+
return toRet;
74+
},
75+
/**
76+
* Determine if the given theme file is a subset of what's in the base theme file.
77+
* If it isnt, throw an error:
78+
* - If keys are in base that are missing in the theme file, that's OK (no need to override everything)
79+
* - If keys are in theme that aren't in base, throw (you can't theme tokens that don't exist in EDS)
80+
* @param {object} base The tokens theme file stored in the EDS project
81+
* @param {object} theme The project theme file stored in the app code (same format as bas)
82+
* @param {Array} path The base path, stored as an array of object key names (default [])
83+
* @throws Error when there are tokens in theme that aren't in base
84+
*/
85+
isStrictSubset: function (base, theme, path = []) {
86+
for (const name in theme) {
87+
if (typeof theme[name] === 'object') {
88+
if (base[name] === undefined) {
89+
throw new Error(
90+
`Local themeable value does not exist in base theme: --${path.join(
91+
'-',
92+
)}.${name}"`,
93+
);
94+
}
95+
module.exports.isStrictSubset(
96+
base[name],
97+
theme[name],
98+
path.concat(name),
99+
);
100+
}
101+
}
102+
},
103+
/**
104+
* Flatten token names such that any "root-tokens" do not include `@` in the resulting token name.
105+
*
106+
* Example:
107+
* "neutral": {
108+
* "default": {
109+
* "@": "var(--eds-theme-color-border-neutral-default)",
110+
* "hover": "var(--eds-theme-color-border-neutral-default-hover)"
111+
* },
112+
* },
113+
*
114+
* will be changed to
115+
*
116+
* "neutral": {
117+
* "default": {
118+
* "hover": "var(--eds-theme-color-border-neutral-default-hover)"
119+
* },
120+
* },
121+
* "neutral-default": "var(--eds-theme-color-border-neutral-default)",
122+
*/
123+
formatEdsTokens: function (obj) {
124+
for (const name in obj) {
125+
if (typeof obj[name] === 'object') {
126+
for (const nestedName in obj[name]) {
127+
if (obj[name][nestedName]['@']) {
128+
obj[name + '-' + nestedName] = obj[name][nestedName]['@'];
129+
delete obj[name][nestedName]['@'];
130+
if (Object.keys(obj[name][nestedName]).length === 0) {
131+
delete obj[name][nestedName];
132+
}
133+
if (Object.keys(obj[name]).length === 0) {
134+
delete obj[name];
135+
}
136+
} else if (typeof obj[name][nestedName] === 'object') {
137+
module.exports.formatEdsTokens(obj[name]);
138+
}
139+
}
140+
}
141+
}
142+
},
24143
};

bin/eds-apply-theme.js

+31-31
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,29 @@
33
const StyleDictionary = require('style-dictionary');
44
const path = require('path');
55
const fs = require('fs');
6-
const { getConfig } = require('./_util');
6+
const {
7+
formatEdsTokens,
8+
getConfig,
9+
isStrictSubset,
10+
minifyDictionaryUsingFormat,
11+
} = require('./_util');
712

813
let packageRootPath;
914
try {
1015
packageRootPath =
1116
path.dirname(require.resolve('@chanzuckerberg/eds')) + '/tokens/json/';
1217
} catch (e) {
18+
// used for working on theming within EDS
1319
console.error('EDS package not installed. Using local path...');
14-
packageRootPath =
15-
path.dirname(require.main.path) + '/src/tokens-dist/json/';
20+
packageRootPath = path.dirname(require.main.path) + '/lib/tokens/json/';
1621
}
1722

1823
// Read the config to sort out where to read JSON from and where to write the CSS file
1924
const config = await getConfig();
2025

2126
// read and parse JSON files on disk
2227
const localTheme = JSON.parse(
23-
fs.readFileSync(`${config.json}app-theme.json`, 'utf8'),
28+
fs.readFileSync(`${config.src}app-theme.json`, 'utf8'),
2429
);
2530
const baseTheme = JSON.parse(
2631
fs.readFileSync(`${packageRootPath}theme-base.json`, 'utf8'),
@@ -35,12 +40,24 @@
3540
],
3641
});
3742

43+
StyleDictionary.registerFormat({
44+
name: 'json/tailwind-utility-config',
45+
formatter: function (dictionary) {
46+
const minifiedCssDictionary = minifyDictionaryUsingFormat(
47+
dictionary.properties,
48+
(obj) => `${obj.value}`,
49+
);
50+
formatEdsTokens(minifiedCssDictionary);
51+
return JSON.stringify(minifiedCssDictionary, null, 2);
52+
},
53+
});
54+
3855
const EDSStyleDictionary = StyleDictionary.extend({
39-
source: [config.json + 'app-theme.json'],
56+
source: [config.src + 'app-theme.json'],
4057
platforms: {
4158
css: {
4259
transforms: [...StyleDictionary.transformGroup.css, 'name/cti/kebab'],
43-
buildPath: config.css,
60+
buildPath: config.dest,
4461
files: [
4562
{
4663
format: 'css/variables',
@@ -54,36 +71,19 @@
5471
return token.attributes.category !== 'legacy';
5572
},
5673
},
74+
{
75+
format: 'json/tailwind-utility-config',
76+
destination: 'app-tailwind-theme.config.json',
77+
options: {
78+
outputReferences: true,
79+
fileHeader: 'cssOverrideHeader',
80+
},
81+
},
5782
],
5883
},
5984
},
6085
});
6186

62-
/**
63-
* Determine if the given theme file is a subset of what's in the base theme file.
64-
* If it isnt, throw an error:
65-
* - If keys are in base that are missing in the theme file, that's OK (no need to override everything)
66-
* - If keys are in theme that aren't in base, throw (you can't theme tokens that don't exist in EDS)
67-
* @param {object} base The tokens theme file stored in the EDS project
68-
* @param {object} theme The project theme file stored in the app code (same format as bas)
69-
* @param {Array} path The base path, stored as an array of object key names (default [])
70-
* @throws Error when there are tokens in theme that aren't in base
71-
*/
72-
function isStrictSubset(base, theme, path = []) {
73-
for (const name in theme) {
74-
if (typeof theme[name] === 'object') {
75-
if (base[name] === undefined) {
76-
throw new Error(
77-
`Local themeable value does not exist in base theme: --${path.join(
78-
'-',
79-
)}.${name}"`,
80-
);
81-
}
82-
isStrictSubset(base[name], theme[name], path.concat(name));
83-
}
84-
}
85-
}
86-
8787
try {
8888
// Keys in the theme file must be a strict subset of those in the base file
8989
isStrictSubset(baseTheme, localTheme);

bin/eds-init.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
packageRootPath =
1010
path.dirname(require.resolve('@chanzuckerberg/eds')) + '/tokens/json/';
1111
} catch (e) {
12+
// used for working on theming within EDS
1213
console.error('EDS package not installed. Using local path...');
13-
packageRootPath =
14-
path.dirname(require.main.path) + '/src/tokens-dist/json/';
14+
packageRootPath = path.dirname(require.main.path) + '/lib/tokens/json/';
1515
}
1616

1717
// read in the config from config file, package json "eds", etc.
@@ -22,16 +22,19 @@
2222
try {
2323
fs.copyFileSync(
2424
packageRootPath + 'theme-base.json',
25-
`${config.json}app-theme.json`,
25+
`${config.src}app-theme.json`,
2626
fs.constants.COPYFILE_EXCL,
2727
);
2828
} catch (error) {
29-
console.error('The local theme file already exists. Exiting.');
29+
console.error(
30+
'The local theme file already exists. Exiting. Details: \n',
31+
error,
32+
);
3033
return 1;
3134
}
3235

3336
console.log(
34-
'File copy completed! Please use `npx eds-apply-theme` to generate theme tokens (CSS Variables).',
37+
'File copy completed! Please use `npx eds-apply-theme` to generate theme token file(s).',
3538
);
3639
}
3740
})();

0 commit comments

Comments
 (0)