From 511599e80e85c89ec3302364a6fd1eedfde8a1b5 Mon Sep 17 00:00:00 2001 From: Ed Sungik Choi Date: Tue, 17 Dec 2024 20:20:07 +0900 Subject: [PATCH 1/5] feat(bezier-tokens): add scss output --- .../bezier-tokens/scripts/build-scss-index.ts | 35 +++++++++++++++++++ .../bezier-tokens/scripts/build-tokens.ts | 25 +++++++++++++ packages/bezier-tokens/scripts/lib/utils.ts | 3 ++ 3 files changed, 63 insertions(+) create mode 100644 packages/bezier-tokens/scripts/build-scss-index.ts diff --git a/packages/bezier-tokens/scripts/build-scss-index.ts b/packages/bezier-tokens/scripts/build-scss-index.ts new file mode 100644 index 000000000..d1a823550 --- /dev/null +++ b/packages/bezier-tokens/scripts/build-scss-index.ts @@ -0,0 +1,35 @@ +import fs from 'fs/promises' +import path from 'path' + +interface BuildScssIndexOptions { + buildPath: string +} + +export async function buildScssIndex({ buildPath }: BuildScssIndexOptions) { + const destination = path.join(buildPath, 'index.scss') + + try { + const files = await fs.readdir(buildPath) + let useStatements = '' + let mapStatements = '$tokens: (\n' + + for (const file of files.filter( + (file) => file.endsWith('.scss') && file !== path.basename(destination) + )) { + const moduleName = path.basename(file, '.scss') + + useStatements += `@use './${moduleName}' as ${moduleName};\n` + mapStatements += ` "${moduleName}": ${moduleName}.$tokens,\n` + } + + mapStatements += ');\n' + + const result = `${useStatements}\n${mapStatements}` + + await fs.writeFile(destination, result) + + console.log(`\n✔︎ Created ${destination}`) + } catch (error) { + throw error + } +} diff --git a/packages/bezier-tokens/scripts/build-tokens.ts b/packages/bezier-tokens/scripts/build-tokens.ts index 74758c1c3..26c99f5ed 100644 --- a/packages/bezier-tokens/scripts/build-tokens.ts +++ b/packages/bezier-tokens/scripts/build-tokens.ts @@ -6,6 +6,7 @@ import StyleDictionary, { } from 'style-dictionary' import { buildJsIndex } from './build-js-index' +import { buildScssIndex } from './build-scss-index' import { alphaCustomCss, alphaCustomJsCjs, @@ -14,6 +15,7 @@ import { customJsEsm, } from './lib/format' import { CSSTransforms } from './lib/transform' +import { toKebabCase } from './lib/utils' import { mergeCss } from './merge-css' const CustomTransforms = [...Object.values(CSSTransforms)] @@ -24,6 +26,7 @@ const BUILD_PATH = { CJS: 'cjs', ESM: 'esm', CSS: 'css', + SCSS: 'scss', } const TokenBuilder = CustomTransforms.reduce( @@ -125,6 +128,21 @@ function defineConfig({ ], transforms, }), + 'web/scss': defineWebPlatform({ + buildPath: `${basePath}/${BUILD_PATH.SCSS}/`, + files: [ + { + destination: `${toKebabCase(destination)}.scss`, + format: 'scss/map-deep', + filter: ({ filePath }) => + source.some((src) => minimatch(filePath, src)), + options: { + outputReferences: false, + }, + }, + ], + transforms, + }), }, } } @@ -209,6 +227,13 @@ async function main() { await mergeCss(buildPath) } + for (const buildPath of [ + `${BUILD_PATH.BASE}/${BUILD_PATH.SCSS}`, + `${BUILD_PATH.BASE_ALPHA}/${BUILD_PATH.SCSS}`, + ]) { + await buildScssIndex({ buildPath }) + } + for (const options of [ { buildPath: `${BUILD_PATH.BASE}/${BUILD_PATH.CJS}`, isCjs: true }, { buildPath: `${BUILD_PATH.BASE_ALPHA}/${BUILD_PATH.CJS}`, isCjs: true }, diff --git a/packages/bezier-tokens/scripts/lib/utils.ts b/packages/bezier-tokens/scripts/lib/utils.ts index c2ae222ed..6bc793d20 100644 --- a/packages/bezier-tokens/scripts/lib/utils.ts +++ b/packages/bezier-tokens/scripts/lib/utils.ts @@ -6,6 +6,9 @@ export const toCamelCase = (str: string) => .toLowerCase() .replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase()) +export const toKebabCase = (str: string) => + str.replace(/([A-Z])/g, '-$1').toLowerCase() + export const extractNumber = (str: string) => str.match(/-?\d+(\.\d+)?/g)?.join('') From 1e375aa2243f0efa4a3af2951715097fef14178a Mon Sep 17 00:00:00 2001 From: Ed Sungik Choi Date: Tue, 17 Dec 2024 20:21:05 +0900 Subject: [PATCH 2/5] build(bezier-tokens): add sass conditional export config https://sass-lang.com/documentation/js-api/classes/nodepackageimporter/ --- packages/bezier-tokens/package.json | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/bezier-tokens/package.json b/packages/bezier-tokens/package.json index 236b63396..7c8428f3f 100644 --- a/packages/bezier-tokens/package.json +++ b/packages/bezier-tokens/package.json @@ -19,7 +19,8 @@ "import": { "types": "./dist/types/esm/index.d.mts", "default": "./dist/esm/index.mjs" - } + }, + "sass": "./dist/scss/index.scss" }, "./alpha": { "require": { @@ -29,10 +30,13 @@ "import": { "types": "./dist/types/alpha/esm/index.d.mts", "default": "./dist/alpha/esm/index.mjs" - } + }, + "sass": "./dist/alpha/scss/index.scss" }, "./css/*": "./dist/css/*", - "./alpha/css/*": "./dist/alpha/css/*" + "./scss/*": "./dist/scss/*", + "./alpha/css/*": "./dist/alpha/css/*", + "./alpha/scss/*": "./dist/alpha/scss/*" }, "typesVersions": { "*": { @@ -42,7 +46,8 @@ } }, "sideEffects": [ - "**/*.css" + "**/*.css", + "**/*.scss" ], "files": [ "dist" From bb7e4a6b297085e40bf9bc50a7a8588b4544c611 Mon Sep 17 00:00:00 2001 From: Ed Sungik Choi Date: Tue, 17 Dec 2024 20:26:30 +0900 Subject: [PATCH 3/5] refactor(bezier-react): use the tokens sass map --- .../src/styles/components/elevation.module.scss | 5 +++-- .../src/styles/components/radius.module.scss | 16 +++------------- .../src/styles/components/z-index.module.scss | 5 +++-- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/packages/bezier-react/src/styles/components/elevation.module.scss b/packages/bezier-react/src/styles/components/elevation.module.scss index c28b6ef28..2ae0f3524 100644 --- a/packages/bezier-react/src/styles/components/elevation.module.scss +++ b/packages/bezier-react/src/styles/components/elevation.module.scss @@ -1,6 +1,7 @@ -$elevations: 1, 2, 3, 4, 5, 6; +@use 'sass:map'; +@use '../../../../../node_modules/@channel.io/bezier-tokens/dist/scss' as *; -@each $ev in $elevations { +@each $ev in map.keys(map.get($tokens, 'light-theme', 'ev')) { :where(.elevation-#{$ev}) { /* stylelint-disable-next-line bezier/validate-token */ box-shadow: var(--ev-#{$ev}); diff --git a/packages/bezier-react/src/styles/components/radius.module.scss b/packages/bezier-react/src/styles/components/radius.module.scss index 513950519..1d5e3b0fe 100644 --- a/packages/bezier-react/src/styles/components/radius.module.scss +++ b/packages/bezier-react/src/styles/components/radius.module.scss @@ -1,17 +1,7 @@ -$radiuses: - 2, - 3, - 4, - 6, - 8, - 12, - 16, - 20, - 32, - 44, - 42-p; +@use 'sass:map'; +@use '../../../../../node_modules/@channel.io/bezier-tokens/dist/scss' as *; -@each $radius in $radiuses { +@each $radius in map.keys(map.get($tokens, 'global', 'radius')) { :where(.radius-#{$radius}) { /* stylelint-disable-next-line bezier/validate-token */ border-radius: var(--radius-#{$radius}); diff --git a/packages/bezier-react/src/styles/components/z-index.module.scss b/packages/bezier-react/src/styles/components/z-index.module.scss index 7d91189df..4e6702568 100644 --- a/packages/bezier-react/src/styles/components/z-index.module.scss +++ b/packages/bezier-react/src/styles/components/z-index.module.scss @@ -1,6 +1,7 @@ -$z-indices: hidden, base, floating, overlay, modal, toast, tooltip, important; +@use 'sass:map'; +@use '../../../../../node_modules/@channel.io/bezier-tokens/dist/scss' as *; -@each $z-index in $z-indices { +@each $z-index in map.keys(map.get($tokens, 'global', 'z-index')) { :where(.z-index-#{$z-index}) { /* stylelint-disable-next-line bezier/validate-token */ z-index: var(--z-index-#{$z-index}); From 48de4dc3de2e2cde1f92383a70cf3385a62d31d5 Mon Sep 17 00:00:00 2001 From: Ed Sungik Choi Date: Tue, 17 Dec 2024 20:58:54 +0900 Subject: [PATCH 4/5] docs(bezier-tokens): update readme --- packages/bezier-tokens/README.md | 45 +++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/packages/bezier-tokens/README.md b/packages/bezier-tokens/README.md index 4b8e6ee4e..306411788 100644 --- a/packages/bezier-tokens/README.md +++ b/packages/bezier-tokens/README.md @@ -10,29 +10,54 @@ npm i -D @channel.io/bezier-tokens ## Usage -### JavaScript +### CSS -You can access and use values by token group. +Provide all design tokens as CSS variables. If you want to apply dark theme tokens, add the `data-bezier-theme="dark"` attribute to the parent element. The default is light theme tokens, which can also be applied by adding the `data-bezier-theme="light"` attribute to the parent element. ```ts -import { tokens } from '@channel.io/bezier-tokens' +import '@channel.io/bezier-tokens/css/styles.css' +``` -console.log(tokens.global.color['blue-300']) // "#..." -console.log(tokens.lightTheme.color['bg-black-dark']) // "#..." +```html +
+
+
+
+
+
``` -### CSS +```css +.foo { + background-color: var(--bg-black-dark); +} +``` -Provide all design tokens as CSS variables. If you want to apply dark theme tokens, add the `data-bezier-theme="dark"` attribute to the parent element. The default is light theme tokens, which can also be applied by adding the `data-bezier-theme="light"` attribute to the parent element. +### SCSS -```ts -import '@channel.io/bezier-tokens/css/styles.css' +While CSS variables are recommended, you can also use SCSS variables directly if you need to. + +```scss +@use "sass:map"; +@use "pkg:@channel.io/bezier-tokens" as *; div { - background: var(--bg-black-dark); + border-radius: map.get($tokens, "global", "radius", "4"); // ...px + background-color: map.get($tokens, "light-theme", "bg", "black", "dark"); // #... } ``` +### JavaScript + +You can access and use values by token group. + +```ts +import { tokens } from '@channel.io/bezier-tokens' + +console.log(tokens.global.color['blue-300']) // "#..." +console.log(tokens.lightTheme.color['bg-black-dark']) // "#..." +``` + ## Contributing See [contribution guide](https://github.com/channel-io/bezier-react/wiki/Contribute). From 3039dcfff55914f216496d5522400fdd97126106 Mon Sep 17 00:00:00 2001 From: Ed Sungik Choi Date: Tue, 17 Dec 2024 21:01:03 +0900 Subject: [PATCH 5/5] chore(changeset): add --- .changeset/rotten-numbers-explain.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rotten-numbers-explain.md diff --git a/.changeset/rotten-numbers-explain.md b/.changeset/rotten-numbers-explain.md new file mode 100644 index 000000000..824e4078b --- /dev/null +++ b/.changeset/rotten-numbers-explain.md @@ -0,0 +1,5 @@ +--- +'@channel.io/bezier-tokens': minor +--- + +Add SCSS support to access design tokens directly through SCSS variables.