Skip to content

Commit d89ac74

Browse files
authored
Support for SCSS output in bezier-tokens (#2568)
<!-- How to write a good PR title: - Follow [the Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/). - Give as much context as necessary and as little as possible - Prefix it with [WIP] while it’s a work in progress --> ## Self Checklist - [x] I wrote a PR title in **English** and added an appropriate **label** to the PR. - [x] I wrote the commit message in **English** and to follow [**the Conventional Commits specification**](https://www.conventionalcommits.org/en/v1.0.0/). - [x] I [added the **changeset**](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md) about the changes that needed to be released. (or didn't have to) - [x] I wrote or updated **documentation** related to the changes. (or didn't have to) - [x] I wrote or updated **tests** related to the changes. (or didn't have to) - [x] I tested the changes in various browsers. (or didn't have to) - Windows: Chrome, Edge, (Optional) Firefox - macOS: Chrome, Edge, Safari, (Optional) Firefox ## Related Issue <!-- Please link to issue if one exists --> <!-- Fixes #0000 --> ## Summary <!-- Please brief explanation of the changes made --> bezier-tokens에서 scss 파일을 내보냅니다. ## Details <!-- Please elaborate description of the changes --> - 일부 유틸 클래스를 만드는 CSS 모듈에서 토큰에 대한 종류를 모두 알고있어야하는 불편함이 있었습니다. 이번에 #2566 PR 작업을 진행하면서 동일한 작업이 반복되는걸 느껴 이를 함께 수정합니다. - bezier-tokens에서 [map-deep](https://styledictionary.com/reference/hooks/formats/predefined/#scssmap-deep) 포맷으로 scss output을 만들도록 합니다. 자바스크립트 케이스처럼 `index.scss` 를 만드는 과정을 추가했습니다. - bezier-token의 `sideEffects` 필드에 scss 파일을 추가합니다. - scss의 `pkg:` Importer 규칙에 따라 bezier-tokens의 conditional export field를 수정했습니다. bezier-react에선 storybook & build 과정 모두 상대 경로로 지정하는 게 잘 동작해서 pkg 프로토콜은 이 PR에서 사용하지 않았습니다 (시간이 좀 더 걸릴듯함) ### Breaking change? (Yes/No) <!-- If Yes, please describe the impact and migration path for users --> No - ev-inner, ev-base 에 대한 유틸 클래스가 추가로 생기지만 사용처 영향은 없습니다 (매우 미미한 스타일 시트 파일 크기 상승) ## References <!-- Please list any other resources or points the reviewer should be aware of --> - https://sass-lang.com/documentation/js-api/classes/nodepackageimporter/ - https://webpack.kr/guides/tree-shaking/
1 parent bc4319e commit d89ac74

File tree

9 files changed

+121
-31
lines changed

9 files changed

+121
-31
lines changed

.changeset/rotten-numbers-explain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@channel.io/bezier-tokens': minor
3+
---
4+
5+
Add SCSS support to access design tokens directly through SCSS variables.

packages/bezier-react/src/styles/components/elevation.module.scss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
$elevations: 1, 2, 3, 4, 5, 6;
1+
@use 'sass:map';
2+
@use '../../../../../node_modules/@channel.io/bezier-tokens/dist/scss' as *;
23

3-
@each $ev in $elevations {
4+
@each $ev in map.keys(map.get($tokens, 'light-theme', 'ev')) {
45
:where(.elevation-#{$ev}) {
56
/* stylelint-disable-next-line bezier/validate-token */
67
box-shadow: var(--ev-#{$ev});

packages/bezier-react/src/styles/components/radius.module.scss

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
1-
$radiuses:
2-
2,
3-
3,
4-
4,
5-
6,
6-
8,
7-
12,
8-
16,
9-
20,
10-
32,
11-
44,
12-
42-p;
1+
@use 'sass:map';
2+
@use '../../../../../node_modules/@channel.io/bezier-tokens/dist/scss' as *;
133

14-
@each $radius in $radiuses {
4+
@each $radius in map.keys(map.get($tokens, 'global', 'radius')) {
155
:where(.radius-#{$radius}) {
166
/* stylelint-disable-next-line bezier/validate-token */
177
border-radius: var(--radius-#{$radius});

packages/bezier-react/src/styles/components/z-index.module.scss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
$z-indices: hidden, base, floating, overlay, modal, toast, tooltip, important;
1+
@use 'sass:map';
2+
@use '../../../../../node_modules/@channel.io/bezier-tokens/dist/scss' as *;
23

3-
@each $z-index in $z-indices {
4+
@each $z-index in map.keys(map.get($tokens, 'global', 'z-index')) {
45
:where(.z-index-#{$z-index}) {
56
/* stylelint-disable-next-line bezier/validate-token */
67
z-index: var(--z-index-#{$z-index});

packages/bezier-tokens/README.md

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,54 @@ npm i -D @channel.io/bezier-tokens
1010

1111
## Usage
1212

13-
### JavaScript
13+
### CSS
1414

15-
You can access and use values by token group.
15+
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.
1616

1717
```ts
18-
import { tokens } from '@channel.io/bezier-tokens'
18+
import '@channel.io/bezier-tokens/css/styles.css'
19+
```
1920

20-
console.log(tokens.global.color['blue-300']) // "#..."
21-
console.log(tokens.lightTheme.color['bg-black-dark']) // "#..."
21+
```html
22+
<div data-bezier-theme="light">
23+
<div class="foo" />
24+
<div data-bezier-theme="dark">
25+
<div class="foo" />
26+
</div>
27+
</div>
2228
```
2329

24-
### CSS
30+
```css
31+
.foo {
32+
background-color: var(--bg-black-dark);
33+
}
34+
```
2535

26-
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.
36+
### SCSS
2737

28-
```ts
29-
import '@channel.io/bezier-tokens/css/styles.css'
38+
While CSS variables are recommended, you can also use SCSS variables directly if you need to.
39+
40+
```scss
41+
@use "sass:map";
42+
@use "pkg:@channel.io/bezier-tokens" as *;
3043

3144
div {
32-
background: var(--bg-black-dark);
45+
border-radius: map.get($tokens, "global", "radius", "4"); // ...px
46+
background-color: map.get($tokens, "light-theme", "bg", "black", "dark"); // #...
3347
}
3448
```
3549

50+
### JavaScript
51+
52+
You can access and use values by token group.
53+
54+
```ts
55+
import { tokens } from '@channel.io/bezier-tokens'
56+
57+
console.log(tokens.global.color['blue-300']) // "#..."
58+
console.log(tokens.lightTheme.color['bg-black-dark']) // "#..."
59+
```
60+
3661
## Contributing
3762

3863
See [contribution guide](https://github.com/channel-io/bezier-react/wiki/Contribute).

packages/bezier-tokens/package.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"import": {
2020
"types": "./dist/types/esm/index.d.mts",
2121
"default": "./dist/esm/index.mjs"
22-
}
22+
},
23+
"sass": "./dist/scss/index.scss"
2324
},
2425
"./alpha": {
2526
"require": {
@@ -29,10 +30,13 @@
2930
"import": {
3031
"types": "./dist/types/alpha/esm/index.d.mts",
3132
"default": "./dist/alpha/esm/index.mjs"
32-
}
33+
},
34+
"sass": "./dist/alpha/scss/index.scss"
3335
},
3436
"./css/*": "./dist/css/*",
35-
"./alpha/css/*": "./dist/alpha/css/*"
37+
"./scss/*": "./dist/scss/*",
38+
"./alpha/css/*": "./dist/alpha/css/*",
39+
"./alpha/scss/*": "./dist/alpha/scss/*"
3640
},
3741
"typesVersions": {
3842
"*": {
@@ -42,7 +46,8 @@
4246
}
4347
},
4448
"sideEffects": [
45-
"**/*.css"
49+
"**/*.css",
50+
"**/*.scss"
4651
],
4752
"files": [
4853
"dist"
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import fs from 'fs/promises'
2+
import path from 'path'
3+
4+
interface BuildScssIndexOptions {
5+
buildPath: string
6+
}
7+
8+
export async function buildScssIndex({ buildPath }: BuildScssIndexOptions) {
9+
const destination = path.join(buildPath, 'index.scss')
10+
11+
try {
12+
const files = await fs.readdir(buildPath)
13+
let useStatements = ''
14+
let mapStatements = '$tokens: (\n'
15+
16+
for (const file of files.filter(
17+
(file) => file.endsWith('.scss') && file !== path.basename(destination)
18+
)) {
19+
const moduleName = path.basename(file, '.scss')
20+
21+
useStatements += `@use './${moduleName}' as ${moduleName};\n`
22+
mapStatements += ` "${moduleName}": ${moduleName}.$tokens,\n`
23+
}
24+
25+
mapStatements += ');\n'
26+
27+
const result = `${useStatements}\n${mapStatements}`
28+
29+
await fs.writeFile(destination, result)
30+
31+
console.log(`\n✔︎ Created ${destination}`)
32+
} catch (error) {
33+
throw error
34+
}
35+
}

packages/bezier-tokens/scripts/build-tokens.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import StyleDictionary, {
66
} from 'style-dictionary'
77

88
import { buildJsIndex } from './build-js-index'
9+
import { buildScssIndex } from './build-scss-index'
910
import {
1011
alphaCustomCss,
1112
alphaCustomJsCjs,
@@ -14,6 +15,7 @@ import {
1415
customJsEsm,
1516
} from './lib/format'
1617
import { CSSTransforms } from './lib/transform'
18+
import { toKebabCase } from './lib/utils'
1719
import { mergeCss } from './merge-css'
1820

1921
const CustomTransforms = [...Object.values(CSSTransforms)]
@@ -24,6 +26,7 @@ const BUILD_PATH = {
2426
CJS: 'cjs',
2527
ESM: 'esm',
2628
CSS: 'css',
29+
SCSS: 'scss',
2730
}
2831

2932
const TokenBuilder = CustomTransforms.reduce(
@@ -125,6 +128,21 @@ function defineConfig({
125128
],
126129
transforms,
127130
}),
131+
'web/scss': defineWebPlatform({
132+
buildPath: `${basePath}/${BUILD_PATH.SCSS}/`,
133+
files: [
134+
{
135+
destination: `${toKebabCase(destination)}.scss`,
136+
format: 'scss/map-deep',
137+
filter: ({ filePath }) =>
138+
source.some((src) => minimatch(filePath, src)),
139+
options: {
140+
outputReferences: false,
141+
},
142+
},
143+
],
144+
transforms,
145+
}),
128146
},
129147
}
130148
}
@@ -209,6 +227,13 @@ async function main() {
209227
await mergeCss(buildPath)
210228
}
211229

230+
for (const buildPath of [
231+
`${BUILD_PATH.BASE}/${BUILD_PATH.SCSS}`,
232+
`${BUILD_PATH.BASE_ALPHA}/${BUILD_PATH.SCSS}`,
233+
]) {
234+
await buildScssIndex({ buildPath })
235+
}
236+
212237
for (const options of [
213238
{ buildPath: `${BUILD_PATH.BASE}/${BUILD_PATH.CJS}`, isCjs: true },
214239
{ buildPath: `${BUILD_PATH.BASE_ALPHA}/${BUILD_PATH.CJS}`, isCjs: true },

packages/bezier-tokens/scripts/lib/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ export const toCamelCase = (str: string) =>
66
.toLowerCase()
77
.replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase())
88

9+
export const toKebabCase = (str: string) =>
10+
str.replace(/([A-Z])/g, '-$1').toLowerCase()
11+
912
export const extractNumber = (str: string) =>
1013
str.match(/-?\d+(\.\d+)?/g)?.join('')
1114

0 commit comments

Comments
 (0)