Skip to content

Commit

Permalink
feat(utils/sui-tokens): config file structure
Browse files Browse the repository at this point in the history
  • Loading branch information
andresin87 committed Jan 2, 2025
1 parent a218c61 commit bf442fb
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 36 deletions.
6 changes: 1 addition & 5 deletions utils/sui-theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
],
"main": "lib/index.scss",
"scripts": {
"tokens": "tokens scss -o ./src/.tokens/.tokens.scss",
"lib": "rm -rf ./lib && npm run tokens && cp -R src lib",
"lib": "rm -rf ./lib && cp -R src lib",
"prepublishOnly": "npm run lib"
},
"repository": {
Expand All @@ -36,9 +35,6 @@
"bugs": {
"url": "https://github.com/SUI-Components/sui-components/issues?q=is%3Aopen+label%3A%22Util%3A+theme%22"
},
"devDependencies": {
"@s-ui/tokens": "beta"
},
"homepage": "https://sui-components.vercel.app/",
"license": "MIT"
}
35 changes: 35 additions & 0 deletions utils/sui-tokens/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,38 @@ It provides:
```sh
$ npm install @s-ui/tokens --save-dev
```

## Usage

To see the resulting configuration, you can run the following command:
```sh
$ tokens -c <config.manifest.file.js>
```

To export the result on json format you can use the JSON script

```sh
$ tokens json -c <config.manifest.file.js> -o <output.json>
```

To export the result on SCSS format you can use the scss script

```sh
$ tokens scss -c <config.manifest.file.js> -o <output.scss>
```

To see other configurations you can use the -h flag

```sh
$ tokens -h
```

...or use it on each script

```sh
$ tokens json -h
```

```shell
$ tokens scss -h
```
1 change: 1 addition & 0 deletions utils/sui-tokens/bin/tokens-json.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ program
.description('building scss tokens file')
.option('-c, --configuration <config>', 'configuration file route')
.option('-o, --output <output>', 'output file route')
.option('-p, --primitive', 'include primitives in the output', false)
.action(runJSON)

program.parse(process.argv)
1 change: 1 addition & 0 deletions utils/sui-tokens/bin/tokens-scss.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ program
.option('-o, --output <output>', 'output file route')
.option('-s, --selector <selector>', 'css selector of tokens container', ':root')
.option('-m, --mode <selector>', 'color schemes of the config')
.option('-p, --primitives', 'include primitives in the output', false)
.action(runSCSS)

program.parse(process.argv)
8 changes: 8 additions & 0 deletions utils/sui-tokens/bin/tokens.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import {program} from 'commander'
import {createRequire} from 'node:module'
import {run} from '../src/build.js'
const require = createRequire(import.meta.url)

const {version} = require('../package.json')
Expand All @@ -11,4 +12,11 @@ program.version(version, '--version, -v')
program.command('scss', 'Generate scss theming variables')
program.command('json', 'Generate json theming variables')

program
.option('-c, --configuration <config>', 'configuration file route')
.option('-o, --output <output>', 'output file route')
.option('-p, --primitive', 'include primitives in the output', false)
.description('tokens result')
.action(run)

program.parse(process.argv)
6 changes: 4 additions & 2 deletions utils/sui-tokens/fotocasa.tokens.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import chroma from 'chroma-js'
import {type Theme, type PrimitiveTheme} from './src/types'

const theme: Theme = {
primitive: {
settings: {
fontSize: '16px',
colorSpace: 'rgb'
},
primitive: {
color: {
blue: {
50: '#F4F4FB',
Expand Down Expand Up @@ -111,7 +114,6 @@ const theme: Theme = {
gloom: '#000000'
}
},
colorSpace: 'rgb',
opacity: {
full: 1,
dim1: 0.82,
Expand Down
6 changes: 4 additions & 2 deletions utils/sui-tokens/milanuncios.tokens.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import chroma from 'chroma-js'
import {type Theme, type PrimitiveTheme} from './src/types'

const theme: Theme = {
primitive: {
settings: {
fontSize: '16px',
colorSpace: 'rgb'
},
primitive: {
color: {
hero: {
50: '#F2FCF7',
Expand Down Expand Up @@ -104,7 +107,6 @@ const theme: Theme = {
gloom: '#000000'
}
},
colorSpace: 'rgb',
opacity: {
full: 1,
dim1: 0.72,
Expand Down
2 changes: 1 addition & 1 deletion utils/sui-tokens/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@s-ui/tokens",
"version": "0.0.0-beta.19",
"version": "0.0.0-beta.20",
"description": "Tool for manipulate @s-ui tokens.",
"publishConfig": {
"access": "public"
Expand Down
58 changes: 45 additions & 13 deletions utils/sui-tokens/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import process from 'node:process'
import {colorParser, colorRampParser} from './checker'
import defaultTokensConfig from './default.tokens.config'
import {generate} from './generate'
import type {Theme, PrimitiveTheme} from './types'
import type {Theme, PrimitiveTheme, SettingsTheme} from './types'

const colorFn = (colorSpace: PrimitiveTheme['colorSpace']) => (v: string) => {
const colorFn = (colorSpace: SettingsTheme['colorSpace']) => (v: string) => {
switch (colorSpace) {
case 'hex':
return chroma(v).css()
Expand All @@ -23,11 +23,10 @@ const colorFn = (colorSpace: PrimitiveTheme['colorSpace']) => (v: string) => {
}

export function build(tokensConfig?: Theme) {
const buildPrimitive = (primitive: PrimitiveTheme) => {
const colorSpace = primitive?.colorSpace
const buildPrimitive = (primitive: PrimitiveTheme, settings: SettingsTheme) => {
const colorSpace = settings?.colorSpace
const colorTx = colorFn(colorSpace)
return {
prefix: primitive.prefix,
color: Object.entries(primitive.color).reduce((acc, [key, value]) => {
if (typeof value === 'string' && colorParser.safeParse(value).success) {
acc[key] = colorTx(value)
Expand All @@ -39,30 +38,37 @@ export function build(tokensConfig?: Theme) {
}
return acc
}, {}),
colorSpace: primitive.colorSpace,
opacity: primitive.opacity,
fontSize: primitive.fontSize,
fontFamily: primitive.fontFamily,
size: primitive.size,
elevation: primitive.elevation
}
}

const protoSettings =
tokensConfig?.settings != null
? deepmerge(defaultTokensConfig.settings, tokensConfig.settings)
: defaultTokensConfig.settings

const protoPrimitive =
tokensConfig?.primitive != null
? deepmerge(defaultTokensConfig.primitive, tokensConfig.primitive)
: defaultTokensConfig.primitive

const primitive = buildPrimitive(protoPrimitive)
const primitive = buildPrimitive(protoPrimitive, protoSettings)
const semantic =
tokensConfig?.semantic != null
? deepmerge(
defaultTokensConfig.semantic(buildPrimitive(defaultTokensConfig.primitive)),
tokensConfig.semantic(primitive)
defaultTokensConfig.semantic(
buildPrimitive(defaultTokensConfig.primitive, defaultTokensConfig.settings),
defaultTokensConfig.settings
),
tokensConfig.semantic(primitive, protoSettings)
)
: defaultTokensConfig.semantic(primitive)
: defaultTokensConfig.semantic(primitive, protoSettings)

return {
settings: protoSettings,
primitive,
semantic
}
Expand Down Expand Up @@ -123,13 +129,39 @@ export const runSCSS = async ({
console.log(chalk.blue('Done!'))
}

export const runJSON = async ({configuration, output}: {configuration?: string; output?: string}) => {
export const runJSON = async ({
configuration,
output,
primitive
}: {
configuration?: string
output?: string
primitive: boolean
}) => {
console.log(chalk.blue('Loading tokens configuration'))
const tokensConfig = await loadTokensConfig(configuration)
console.log(chalk.blue('Building tokens'))
console.log(chalk.green(JSON.stringify(tokensConfig, null, 2)))
const result = build(tokensConfig)
console.log(chalk.blue('Writing tokens'))
await writeTokensConfig(JSON.stringify(generate.json(result, {hasPrimitive: primitive}), null, 2), output)
console.log(chalk.blue('Done!'))
}

export const run = async ({
configuration,
primitive
}: {
configuration?: string
output?: string
primitive: boolean
}) => {
console.log(chalk.blue('Loading tokens configuration'))
const tokensConfig = await loadTokensConfig(configuration)
console.log(chalk.blue('Building tokens'))
console.log(chalk.green(JSON.stringify(tokensConfig, null, 2)))
const result = build(tokensConfig)
console.log(chalk.blue('Writing tokens'))
await writeTokensConfig(generate.json(result), output)
console.log(JSON.stringify(generate.json(result, {hasPrimitive: primitive}), null, 2))
console.log(chalk.blue('Done!'))
}
13 changes: 9 additions & 4 deletions utils/sui-tokens/src/default.tokens.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import chroma from 'chroma-js'

import {type Theme, type PrimitiveTheme} from './types'
import {type Theme, type PrimitiveTheme, type SettingsTheme} from './types'

const theme: Theme = {
primitive: {
settings: {
prefix: 's-ui',
fontSize: '16px',
colorSpace: 'rgb'
},
primitive: {
fontFamily: {
sans: ["'Open Sans'", 'Helvetica', 'sans-serif'],
serif: ['Georgia', 'Cambria', "'Times New Roman'", 'Times', 'serif'],
Expand Down Expand Up @@ -125,7 +128,6 @@ const theme: Theme = {
gloom: '#000000'
}
},
colorSpace: 'rgb',
opacity: {
full: 1,
dim1: 0.72,
Expand Down Expand Up @@ -218,7 +220,10 @@ const theme: Theme = {
tooltip: 1800
}
},
semantic: ({color, opacity, elevation, size, fontSize, fontFamily}: PrimitiveTheme) => {
semantic: (
{color, opacity, elevation, size, fontFamily}: PrimitiveTheme,
{fontSize, prefix, colorSpace}: SettingsTheme
) => {
return {
color: {
brand: {
Expand Down
16 changes: 11 additions & 5 deletions utils/sui-tokens/src/generate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {kebabCase} from 'change-case'

import {type SemanticTheme, type PrimitiveTheme} from './types'
import {type SemanticTheme, type PrimitiveTheme, type SettingsTheme} from './types'

const anidate = (accumulator: Map<string, string>, [key, value]) => {
if (typeof value === 'string' || typeof value === 'number') {
Expand All @@ -23,7 +23,7 @@ const anidate = (accumulator: Map<string, string>, [key, value]) => {

export const generate = {
scss: (
{primitive, semantic}: {primitive: PrimitiveTheme; semantic: SemanticTheme},
{settings, primitive, semantic}: {settings: SettingsTheme; primitive: PrimitiveTheme; semantic: SemanticTheme},
selector: string,
mode?: 'light' | 'dark'
) => {
Expand Down Expand Up @@ -73,7 +73,7 @@ $${key}: var(${getTokenKey(key)}) !default;`
)
}

const {prefix} = primitive
const {prefix} = settings
const hasMode = (mode?: 'light' | 'dark') => mode !== undefined

add('color', prefix, hasMode(mode) ? 2 : 1)
Expand All @@ -96,7 +96,13 @@ ${scssTokens.elevation}
${scssTokens.spacing}
`
},
json: ({semantic}: {primitive: PrimitiveTheme; semantic: SemanticTheme}) => {
return JSON.stringify(semantic, null, 2)
json: (
{primitive, semantic}: {primitive: PrimitiveTheme; semantic: SemanticTheme},
{hasPrimitive}: {hasPrimitive: boolean}
) => {
return {
...(hasPrimitive ? {primitive} : {}),
semantic
}
}
}
4 changes: 3 additions & 1 deletion utils/sui-tokens/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export {runSCSS, runJSON} from './build'

export {
type SettingsTheme,
type PrimitiveTheme,
type SemanticTheme,
type ColorPrimitives,
type ColorRamp,
type OpacityPrimitive,
type Base,
type Theme
type Theme,
type ThemeResult
} from './types'
16 changes: 13 additions & 3 deletions utils/sui-tokens/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ export interface OpacityPrimitive {

export type Base = string

export interface PrimitiveTheme {
export interface SettingsTheme {
prefix?: string
fontSize?: string
colorSpace?: 'hex' | 'rgb'
}

export interface PrimitiveTheme {
fontFamily?: {
[key: string]: string[]
}
color?: ColorPrimitives
colorSpace?: 'hex' | 'rgb'
opacity?: OpacityPrimitive
size?: {
[key: string]: string
Expand Down Expand Up @@ -228,6 +231,13 @@ export interface SemanticTheme {
}

export interface Theme {
settings: SettingsTheme
primitive: PrimitiveTheme
semantic: (themePrimitives?: PrimitiveTheme, settingsTheme?: SettingsTheme) => SemanticTheme
}

export interface ThemeResult {
settings: SettingsTheme
primitive: PrimitiveTheme
semantic: (themePrimitives: PrimitiveTheme) => SemanticTheme
semantic: SemanticTheme
}

0 comments on commit bf442fb

Please sign in to comment.