Skip to content

Commit 0138c6f

Browse files
authored
Merge pull request #1292 from vtex/feature/token-object
feat(tokens): export token object
2 parents 63bc656 + 0c8a3a6 commit 0138c6f

10 files changed

+119
-11
lines changed
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { ShorelineConfig } from '@vtex/shoreline-utils'
2+
import { format } from 'prettier'
3+
4+
import { tokensToDictionary } from './tokens-to-dictionary'
5+
6+
export async function genTokensObject(
7+
config: ShorelineConfig
8+
): Promise<Buffer> {
9+
const tokens = tokensToDictionary(config)
10+
const tsDeclaration = `export const ShorelineTokens = ${JSON.stringify(
11+
tokens
12+
)};`
13+
14+
const tsCode = await format(tsDeclaration, {
15+
parser: 'typescript',
16+
semi: false,
17+
singleQuote: true,
18+
})
19+
20+
return Buffer.from(tsCode)
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { tokensToDictionary } from '../tokens-to-dictionary'
2+
3+
const tokens = {
4+
color: {
5+
red: {
6+
6: '#FF0000',
7+
},
8+
},
9+
bg: {
10+
'*': '$color-red-6',
11+
},
12+
}
13+
14+
describe('tokens-to-dictionary', () => {
15+
it('should', () => {
16+
expect(
17+
tokensToDictionary({
18+
tokens,
19+
})
20+
).toStrictEqual({
21+
ColorRed6: 'var(--sl-color-red-6)',
22+
Bg: 'var(--sl-bg)',
23+
})
24+
})
25+
})

packages/theme/src/theme.ts

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { loadConfig } from './config'
33
import { outputFile } from './output-file'
44
import { genTypescript } from './gen-typescript'
55
import { extendConfig } from './extend-config'
6+
import { genTokensObject } from './gen-tokens-object'
67

78
export async function theme() {
89
const config = loadConfig({
@@ -26,4 +27,12 @@ export async function theme() {
2627
code: ts,
2728
successMessage: '🏆 Types generated!',
2829
})
30+
31+
const tokens = await genTokensObject(extendedConfig)
32+
33+
outputFile({
34+
path: `${extendedConfig.outdir}/tokens.ts`,
35+
code: tokens,
36+
successMessage: '🍰 Tokens generated!',
37+
})
2938
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { ShorelineConfig } from '@vtex/shoreline-utils'
2+
import { toVar, parseTokens } from '@vtex/shoreline-utils'
3+
4+
export function tokensToDictionary(config: ShorelineConfig) {
5+
const { tokens = {}, prefix } = config
6+
7+
const res: Record<string, string> = {}
8+
const unprefixedTokens = parseTokens({
9+
tokens,
10+
prefix,
11+
unprefixed: true,
12+
})
13+
14+
for (const prop in unprefixedTokens) {
15+
const key = toPascalCase(prop)
16+
17+
res[key] = `var(${toVar(prop)})`
18+
}
19+
20+
return res
21+
}
22+
23+
function toPascalCase(text: string) {
24+
return text.replace(/(^\w|-\w)/g, clearAndUpper)
25+
}
26+
27+
function clearAndUpper(text: string) {
28+
return text.replace(/-/, '').toUpperCase()
29+
}

packages/tokens/src/index.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
// TODO: Export theme as Object: https://github.com/vtex/shoreline/issues/1281.
2-
export const theme = {}
1+
export * from './tokens'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react'
2+
3+
import { ShorelineTokens } from '../tokens'
4+
5+
export default {
6+
title: 'tokens/token-object',
7+
}
8+
9+
export function Default() {
10+
return (
11+
<div
12+
style={{
13+
width: 100,
14+
height: 100,
15+
background: ShorelineTokens.ColorBlue13,
16+
borderRadius: ShorelineTokens.BorderRadiusMedium,
17+
}}
18+
/>
19+
)
20+
}

packages/tokens/src/tokens.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../shoreline/tokens'

packages/utils/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useId } from './use-id'
1616
import { useMergeRef } from './use-merge-ref'
1717
import { useSafeLayoutEffect } from './use-safe-layout-effect'
1818
import { hasSomeTextSelected } from './has-some-text-selected'
19+
import { toVar } from './to-var'
1920

2021
export {
2122
chain,
@@ -39,6 +40,7 @@ export {
3940
useMergeRef,
4041
useSafeLayoutEffect,
4142
hasSomeTextSelected,
43+
toVar,
4244
}
4345

4446
export * from './css-types'

packages/utils/src/parse-tokens.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { AnyObject, Dict } from './utility-types'
22
import { constants } from './constants'
33
import { cssVar } from './css-var'
44
import { flattenObject } from './flatten-object'
5+
import { toVar } from './to-var'
56

67
/**
78
* Parse token from the config to a Token Dict.
@@ -23,15 +24,6 @@ export function parseTokens(props: ParseTokensProps): Dict {
2324
return tokenDict
2425
}
2526

26-
/**
27-
* Parse a prefix-value to a CSS Variable declaration
28-
* @param {string} value
29-
* @param {string} prefix
30-
*/
31-
function toVar(value: string, prefix: string = constants.dsPrefix) {
32-
return `--${prefix}-${value}`
33-
}
34-
3527
interface ParseTokensProps {
3628
tokens: AnyObject
3729
unprefixed?: boolean

packages/utils/src/to-var.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { constants } from './constants'
2+
3+
/**
4+
* Parse a prefix-value to a CSS Variable declaration
5+
* @param {string} value
6+
* @param {string} prefix
7+
*/
8+
export function toVar(value: string, prefix: string = constants.dsPrefix) {
9+
return `--${prefix}-${value}`
10+
}

0 commit comments

Comments
 (0)