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

Implement bezier-tokens package #1685

Merged
merged 24 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5d5481a
feat(bezier-tokens): npm init
sungik-choi Oct 18, 2023
64f7bc8
feat(bezier-tokens): init design tokens
sungik-choi Oct 18, 2023
581ee18
chore(deps): add style-dictionary
sungik-choi Oct 18, 2023
093107c
chore(deps): remove style dictionary and add cobalt-ui
sungik-choi Oct 18, 2023
7dbe77e
chore(tokens): add tokens
sungik-choi Oct 18, 2023
5f57722
chore(deps): back to style-dictionary
sungik-choi Nov 20, 2023
93a7ff2
feat(bezier-tokens): token scaffolding
sungik-choi Nov 20, 2023
e0ae091
fix(bezier-tokens): add rest global tokens
sungik-choi Nov 21, 2023
584e557
feat(bezier-tokens): enhance build script (wip)
sungik-choi Nov 21, 2023
1139742
chore(deps): add ts-node
sungik-choi Nov 21, 2023
fe6765d
feat(bezier-tokens): refine build script and change to typescript(esm)
sungik-choi Nov 21, 2023
aef1e31
feat(bezier-tokens): implement js index build script
sungik-choi Nov 21, 2023
b4578f2
fix(bezier-tokens): fix js index build script (mjs extension)
sungik-choi Nov 21, 2023
e8221d6
feat(bezier-tokens): add type build script
sungik-choi Nov 21, 2023
c681297
feat(bezier-tokens): set package entry point
sungik-choi Nov 21, 2023
c0277b4
feat(bezier-tokens): add eslint and lint fix
sungik-choi Nov 21, 2023
83086ac
chore(bezier-tokens): add tsconfig
sungik-choi Nov 21, 2023
d979b80
fix(bezier-tokens): fix wrong type extension
sungik-choi Nov 21, 2023
85b5d75
refactor: rm unused file
sungik-choi Nov 21, 2023
1df6dbf
chore(bezier-tokens): add css conditional exports
sungik-choi Nov 21, 2023
6d1048a
fix(bezier-tokens): change named export to default export
sungik-choi Nov 21, 2023
925555d
docs(bezier-tokens): update readme
sungik-choi Nov 21, 2023
11e5a01
docs(pkgs): update contributing doc link
sungik-choi Nov 21, 2023
a95ff35
chore(changeset): add changeset
sungik-choi Nov 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rare-coats-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@channel.io/bezier-tokens": minor
---

First release
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"jest-environment-jsdom": "^29.6.4",
"npm-run-all": "^4.1.5",
"stylelint": "^13.13.1",
"ts-node": "^10.9.1",
"turbo": "^1.10.13",
"typescript": "^4.9.5",
"typescript-plugin-css-modules": "^5.0.1"
Expand Down
2 changes: 1 addition & 1 deletion packages/bezier-figma-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Plugins > Development > Import plugin from manifest

## Contributing

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

## Maintainers

Expand Down
2 changes: 1 addition & 1 deletion packages/bezier-icons/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ console.log(isBezierIcon(<svg />)) // false

## Contributing

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

## Maintainers

Expand Down
2 changes: 1 addition & 1 deletion packages/bezier-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ root.render(

## Contributing

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

## Maintainers

Expand Down
2 changes: 2 additions & 0 deletions packages/bezier-tokens/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
26 changes: 26 additions & 0 deletions packages/bezier-tokens/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module.exports = {
root: true,
extends: ['bezier'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.eslint.json',
},
rules: {
'no-restricted-imports': 'off',
'sort-imports': [
'error',
{
ignoreDeclarationSort: true,
},
],
'import/order': [
'error',
{
'newlines-between': 'always',
alphabetize: { order: 'asc' },
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
},
],
'@typescript-eslint/naming-convention': 'off',
},
}
44 changes: 44 additions & 0 deletions packages/bezier-tokens/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Bezier Tokens

Bezier Tokens is a design tokens library that implements Bezier design system.

## Installation

```bash
npm i -D @channel.io/bezier-tokens
```

## Usage

### JavaScript

You can access and use values by token group.

```ts
import { tokens } from '@channel.io/bezier-tokens'

console.log(tokens.global['blue-300']) // "#..."
console.log(tokens.lightTheme['bg-black-dark']) // "#..."
```

### CSS

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 '@channel.io/bezier-tokens/css/global.css'
import '@channel.io/bezier-tokens/css/light-theme.css'
import '@channel.io/bezier-tokens/css/dark-theme.css'

div {
background: var(--bg-black-dark);
}
```

## Contributing

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

## Maintainers

This package is mainly contributed by Channel Corp. Although feel free to contribution, or raise concerns!
56 changes: 56 additions & 0 deletions packages/bezier-tokens/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "@channel.io/bezier-tokens",
"version": "0.1.0",
"description": "Design tokens for Bezier design system.",
"repository": {
"type": "git",
"url": "https://github.com/channel-io/bezier-react",
"directory": "packages/bezier-tokens"
},
"main": "dist/cjs/index.js",
"module": "dist/esm/index.mjs",
"types": "dist/types/cjs/index.d.ts",
"exports": {
".": {
"require": {
"types": "./dist/types/cjs/index.d.ts",
"default": "./dist/cjs/index.js"
},
"import": {
"types": "./dist/types/esm/index.d.mts",
"default": "./dist/esm/index.mjs"
}
},
"./css/*": "./dist/css/*"
},
"sideEffects": [
"**/*.css"
],
"files": [
"dist"
],
"scripts": {
"build": "run-s clean:build build:tokens build:js-index build:types",
"build:tokens": "ts-node-esm scripts/build-tokens.ts",
"build:js-index": "ts-node-esm scripts/build-js-index.ts",
"build:types": "tsc -p tsconfig.build.json",
"lint": "TIMING=1 eslint --cache .",
"typecheck": "tsc --noEmit",
"clean": "run-s 'clean:*'",
"clean:build": "rm -rf dist",
"clean:cache": "rm -rf node_modules .turbo .eslintcache"
},
"keywords": [
"channel",
"design",
"tokens",
"design tokens"
],
"author": "Channel Corp.",
"license": "Apache-2.0",
"devDependencies": {
"eslint-config-bezier": "workspace:*",
"style-dictionary": "^3.9.0",
"tsconfig": "workspace:*"
}
}
73 changes: 73 additions & 0 deletions packages/bezier-tokens/scripts/build-js-index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import fs from 'fs'
import path from 'path'

interface BuildJsIndexFileOptions {
buildPath: string
isCjs: boolean
}

const getFileExtensionByModuleSystem = (isCjs: boolean) =>
(isCjs ? '.js' : '.mjs')

function buildJsIndexFile({ buildPath, isCjs }: BuildJsIndexFileOptions) {
const fileExtension = getFileExtensionByModuleSystem(isCjs)
const indexFile = `index${fileExtension}`
let exportStatements = ''

if (!fs.existsSync(buildPath)) {
// eslint-disable-next-line no-console
console.log(`Directory not found: ${buildPath}`)
return
}

const files = fs.readdirSync(buildPath)
// eslint-disable-next-line no-console
console.log(`Reading files in ${buildPath}:`, files)

files.forEach((file) => {
if (file.endsWith(fileExtension) && file !== indexFile) {
const moduleName = file.replace(fileExtension, '')
if (!isCjs) {
exportStatements += `import ${moduleName} from './${file}';\n`
}
}
})

if (isCjs) {
exportStatements += 'exports.tokens = Object.freeze({\n'
} else {
exportStatements += '\nexport const tokens = Object.freeze({\n'
}

files.forEach((file) => {
if (file.endsWith(fileExtension) && file !== indexFile) {
const moduleName = file.replace(fileExtension, '')
if (isCjs) {
exportStatements += ` ${moduleName}: require('./${moduleName}'),\n`
} else {
exportStatements += ` ${moduleName},\n`
}
}
})

exportStatements += '});\n'

fs.writeFileSync(path.join(buildPath, indexFile), exportStatements)
// eslint-disable-next-line no-console
console.log(`✅ Created ${indexFile} in ${buildPath}`)
}

function main() {
[
{
buildPath: 'dist/cjs',
isCjs: true,
},
{
buildPath: 'dist/esm',
isCjs: false,
},
].forEach(buildJsIndexFile)
}

main()
108 changes: 108 additions & 0 deletions packages/bezier-tokens/scripts/build-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import StyleDictionary, { type Config } from 'style-dictionary'

import {
customJsCjs,
customJsEsm,
} from './lib/format'
import { customFontPxToRem } from './lib/transform'
import { toCamelCase } from './lib/utils'

const TokenBuilder = StyleDictionary.registerTransform(customFontPxToRem)
.registerFormat(customJsCjs)
.registerFormat(customJsEsm)

const COMMON_WEB_TRANSFORMS = [
'attribute/cti',
'name/cti/kebab',
'size/rem',
'color/css',
customFontPxToRem.name,
]

interface DefineConfigOptions {
source: string[]
destination: string
options?: {
cssSelector: string
}
}

function defineConfig({
source,
destination,
options,
}: DefineConfigOptions): Config {
return {
source,
platforms: {
'js/cjs': {
transforms: COMMON_WEB_TRANSFORMS,
buildPath: 'dist/cjs/',
files: [
{
destination: `${toCamelCase(destination)}.js`,
format: customJsCjs.name,
filter: (token) => token.filePath.includes(destination),
},
],
},
'js/esm': {
transforms: COMMON_WEB_TRANSFORMS,
buildPath: 'dist/esm/',
files: [
{
destination: `${toCamelCase(destination)}.mjs`,
format: customJsEsm.name,
filter: (token) => token.filePath.includes(destination),
},
],
},
css: {
transforms: COMMON_WEB_TRANSFORMS,
basePxFontSize: 10,
buildPath: 'dist/css/',
files: [
{
destination: `${destination}.css`,
format: 'css/variables',
filter: (token) => token.filePath.includes(destination),
options: {
selector: options?.cssSelector,
outputReferences: true,
},
},
],
},
},
}
}

function main() {
[
TokenBuilder.extend(
defineConfig({
source: ['src/global/*.json'],
destination: 'global',
options: { cssSelector: ':where(:root, :host)' },
}),
),
TokenBuilder.extend(
defineConfig({
source: ['src/global/*.json', 'src/semantic/light-theme/*.json'],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

semantic 토큰이 global 토큰을 참조하고 있기 때문에, 빌드 에러를 방지하기 위해선 source 배열에 global 토큰이 포함되어야 합니다.

destination: 'light-theme',
options: {
cssSelector: ':where(:root, :host), [data-bezier-theme="light"]',
},
}),
),
TokenBuilder.extend(
defineConfig({
source: ['src/global/*.json', 'src/semantic/dark-theme/*.json'],
destination: 'dark-theme',
options: { cssSelector: '[data-bezier-theme="dark"]' },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기는 :root selector 를 안줘도 되는 것인가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기본 테마로 라이트 테마가 설정되고, 다크 테마는 data 속성으로 필요한 경우에 뗐다 붙였다 하는 걸 기대했어요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(#1690 예시처럼)

}),
),
].forEach((builder) => builder.buildAllPlatforms())
}

main()
41 changes: 41 additions & 0 deletions packages/bezier-tokens/scripts/lib/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
type Format,
type Named,
formatHelpers,
} from 'style-dictionary'

type CustomFormat = Named<Format>

const { fileHeader } = formatHelpers

export const customJsCjs: CustomFormat = {
name: 'custom/js/cjs',
formatter({ dictionary, file }) {
return (
`${fileHeader({ file })
}module.exports = {` +
`\n${
dictionary.allTokens
.map((token) => ` "${token.name}": ${JSON.stringify(token.value)},`)
.join('\n')
}\n` +
'}'
)
},
}

export const customJsEsm: CustomFormat = {
name: 'custom/js/esm',
formatter({ dictionary, file }) {
return (
`${fileHeader({ file })
}export default {` +
`\n${
dictionary.allTokens
.map((token) => ` "${token.name}": ${JSON.stringify(token.value)},`)
.join('\n')
}\n` +
'}'
)
},
}
Loading