Skip to content

Commit

Permalink
Support for SCSS output in bezier-tokens (#2568)
Browse files Browse the repository at this point in the history
<!--
  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/
  • Loading branch information
sungik-choi authored Dec 18, 2024
1 parent bc4319e commit d89ac74
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/rotten-numbers-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@channel.io/bezier-tokens': minor
---

Add SCSS support to access design tokens directly through SCSS variables.
Original file line number Diff line number Diff line change
@@ -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});
Expand Down
16 changes: 3 additions & 13 deletions packages/bezier-react/src/styles/components/radius.module.scss
Original file line number Diff line number Diff line change
@@ -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});
Expand Down
Original file line number Diff line number Diff line change
@@ -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});
Expand Down
45 changes: 35 additions & 10 deletions packages/bezier-tokens/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<div data-bezier-theme="light">
<div class="foo" />
<div data-bezier-theme="dark">
<div class="foo" />
</div>
</div>
```

### 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).
Expand Down
13 changes: 9 additions & 4 deletions packages/bezier-tokens/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"import": {
"types": "./dist/types/esm/index.d.mts",
"default": "./dist/esm/index.mjs"
}
},
"sass": "./dist/scss/index.scss"
},
"./alpha": {
"require": {
Expand All @@ -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": {
"*": {
Expand All @@ -42,7 +46,8 @@
}
},
"sideEffects": [
"**/*.css"
"**/*.css",
"**/*.scss"
],
"files": [
"dist"
Expand Down
35 changes: 35 additions & 0 deletions packages/bezier-tokens/scripts/build-scss-index.ts
Original file line number Diff line number Diff line change
@@ -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
}
}
25 changes: 25 additions & 0 deletions packages/bezier-tokens/scripts/build-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import StyleDictionary, {
} from 'style-dictionary'

import { buildJsIndex } from './build-js-index'
import { buildScssIndex } from './build-scss-index'
import {
alphaCustomCss,
alphaCustomJsCjs,
Expand All @@ -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)]
Expand All @@ -24,6 +26,7 @@ const BUILD_PATH = {
CJS: 'cjs',
ESM: 'esm',
CSS: 'css',
SCSS: 'scss',
}

const TokenBuilder = CustomTransforms.reduce(
Expand Down Expand Up @@ -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,
}),
},
}
}
Expand Down Expand Up @@ -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 },
Expand Down
3 changes: 3 additions & 0 deletions packages/bezier-tokens/scripts/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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('')

Expand Down

0 comments on commit d89ac74

Please sign in to comment.