@aziontech/theme 1.13.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +19 -21
- package/src/scripts/build-tokens.mjs +391 -0
- package/src/scripts/compile-primitives.js +165 -0
- package/src/scripts/compile-theme.js +117 -0
- package/src/{tokens/build → scripts}/css-vars.js +10 -9
- package/src/{tokens/build → scripts}/resolve.js +2 -0
- package/src/tests/primitives.html +293 -0
- package/src/tests/theme.html +310 -0
- package/src/tests/tokens.html +84 -0
- package/src/tokens/README.md +306 -272
- package/src/tokens/index.js +4 -12
- package/src/tokens/primitives/animations/animate.js +8 -0
- package/src/tokens/primitives/animations/ease.js +7 -0
- package/src/tokens/primitives/border-widths.js +9 -0
- package/src/tokens/primitives/breakpoints.js +9 -0
- package/src/tokens/primitives/colors/alpha.js +104 -0
- package/src/tokens/primitives/colors/brand.js +40 -0
- package/src/tokens/primitives/colors/colors.js +142 -0
- package/src/tokens/primitives/effects/blur.js +11 -0
- package/src/tokens/primitives/effects/drop-shadow.js +10 -0
- package/src/tokens/primitives/effects/inset-shadow.js +7 -0
- package/src/tokens/primitives/effects/opacity.js +8 -0
- package/src/tokens/primitives/effects/perspective.js +9 -0
- package/src/tokens/primitives/effects/shadow.js +11 -0
- package/src/tokens/primitives/ring-offset.js +5 -0
- package/src/tokens/primitives/shape/aspect-video.js +3 -0
- package/src/tokens/primitives/shape/container.js +17 -0
- package/src/tokens/primitives/shape/height.js +32 -0
- package/src/tokens/primitives/shape/radius.js +13 -0
- package/src/tokens/primitives/shape/shape.js +12 -0
- package/src/tokens/primitives/shape/size.js +32 -0
- package/src/tokens/primitives/shape/spacing.js +33 -0
- package/src/tokens/primitives/shape/width.js +19 -0
- package/src/tokens/primitives/typography/font-family.js +7 -0
- package/src/tokens/primitives/typography/font-size.js +30 -0
- package/src/tokens/primitives/typography/font-weight.js +13 -0
- package/src/tokens/primitives/typography/leading.js +9 -0
- package/src/tokens/primitives/typography/line-height.js +13 -0
- package/src/tokens/primitives/typography/tracking.js +10 -0
- package/src/{tailwind/semantic-animations-plugin.js → tokens/semantic/animations.js} +3 -21
- package/src/tokens/semantic/colors.js +138 -0
- package/src/tokens/semantic/containers.data.js +18 -0
- package/src/tokens/semantic/containers.js +70 -0
- package/src/tokens/semantic/spacings.data.js +18 -0
- package/src/tokens/semantic/spacings.js +163 -0
- package/src/tokens/semantic/texts.data.js +103 -0
- package/src/{tailwind/semantic-texts-plugin.js → tokens/semantic/texts.js} +30 -9
- package/src/tokens/theme/accent.js +18 -0
- package/src/tokens/theme/background.js +32 -0
- package/src/tokens/theme/border.js +18 -0
- package/src/tokens/theme/feedback/danger.js +16 -0
- package/src/tokens/theme/feedback/info.js +16 -0
- package/src/tokens/theme/feedback/success.js +16 -0
- package/src/tokens/theme/feedback/warning.js +16 -0
- package/src/tokens/theme/primary.js +18 -0
- package/src/tokens/theme/ring.js +12 -0
- package/src/tokens/theme/secondary.js +18 -0
- package/src/tokens/theme/surfaces.js +23 -0
- package/src/tokens/theme/text.js +18 -0
- package/src/tokens/theme.js +32 -0
- package/colors-brand.js +0 -24
- package/src/tailwind/semantic-colors-plugin.js +0 -91
- package/src/tailwind/semantic-spacing-plugin.js +0 -151
- package/src/tailwind/tailwind-theme.js +0 -54
- package/src/tokens/build/preset.js +0 -62
- package/src/tokens/build/tailwind-flat-colors.js +0 -75
- package/src/tokens/build/tailwind-helper.js +0 -12
- package/src/tokens/build/tailwind-plugin.js +0 -175
- package/src/tokens/colors-brand.js +0 -24
- package/src/tokens/primitives/brand.js +0 -69
- package/src/tokens/primitives/colors.js +0 -144
- package/src/tokens/semantic/backgrounds.js +0 -46
- package/src/tokens/semantic/borders.js +0 -44
- package/src/tokens/semantic/text.js +0 -48
- /package/src/{tokens/build → scripts}/refs.js +0 -0
package/src/tokens/README.md
CHANGED
|
@@ -1,345 +1,379 @@
|
|
|
1
|
+
<h1 align="center">azion-theme · tokens</h1>
|
|
1
2
|
|
|
2
|
-
|
|
3
|
+
Design tokens organized as JavaScript modules, compiled into CSS custom properties and a Tailwind config. The pipeline emits **two parallel targets** from the same source:
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
- **`dist/v3/`** — Tailwind v3 preset (`tailwind-preset.js` / `tailwind.config.js`) + a self-contained `globals.css` with `@tailwind` directives, `:root` / `[data-theme=dark]` blocks, responsive `@media` overrides, and the component classes.
|
|
6
|
+
- **`dist/v4/`** — Tailwind v4 CSS-first output: `globals.css` with `@import "tailwindcss"` + `@theme { … }` + plain `:root` for shape/typography semantics + `@layer components`.
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
<img
|
|
8
|
-
src="./doc/cover-image.png"
|
|
9
|
-
width="1200px"
|
|
10
|
-
/>
|
|
11
|
-
</p>
|
|
8
|
+
Tokens live in JS as the source-of-truth and are compiled at package build time, not in the browser.
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
## 📋 Table of contents
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
- [Architecture overview](#-architecture-overview)
|
|
13
|
+
- [File structure](#-file-structure)
|
|
14
|
+
- [Token types](#-token-types)
|
|
15
|
+
- [Building & consuming](#-building--consuming)
|
|
16
|
+
- [How to add a new token](#-how-to-add-a-new-token)
|
|
17
|
+
- [Token references (`tokenRef`)](#-token-references-tokenref)
|
|
18
|
+
- [Test pages](#-test-pages)
|
|
19
|
+
- [Theme switching](#-theme-switching)
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
- [Usage](#-usage)
|
|
19
|
-
- [Development](#-development)
|
|
20
|
-
- [Design Tokens](#-design-tokens)
|
|
21
|
-
- [Links](#-links)
|
|
21
|
+
---
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## 🏗 Architecture overview
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Three layers:
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
yarn add azion-theme
|
|
31
|
-
```
|
|
27
|
+
1. **Primitives** — raw, theme-invariant values (color hexes, px sizes, font sizes, durations).
|
|
28
|
+
2. **Semantic / theme** — light/dark variants and responsive (per-breakpoint) tokens that **reference** primitives via `tokenRef(...)`.
|
|
29
|
+
3. **Output bundles** — `dist/v3/` and `dist/v4/` artifacts emitted by `scripts/build-tokens.mjs`.
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
Compile pipeline:
|
|
34
32
|
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
33
|
+
```
|
|
34
|
+
tokens/primitives/** ─┐
|
|
35
|
+
│
|
|
36
|
+
tokens/semantic/colors.js ─┤
|
|
37
|
+
tokens/semantic/*.data.js ─┼──► scripts/build-tokens.mjs ──► dist/v3/{globals.css,tailwind-preset.js,tailwind.config.js}
|
|
38
|
+
tokens/theme/** ─┤ dist/v4/globals.css
|
|
39
|
+
│
|
|
40
|
+
scripts/{compile-primitives, ─┘
|
|
41
|
+
compile-theme,
|
|
42
|
+
resolve,
|
|
43
|
+
css-vars,
|
|
44
|
+
refs}.js (building blocks used by build-tokens.mjs)
|
|
41
45
|
```
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
- Primitives emit a single block (values don't change between themes).
|
|
48
|
+
- Semantic colors flip between `:root, [data-theme=light]` and `[data-theme=dark], .dark, .azion.azion-dark`.
|
|
49
|
+
- Responsive semantic tokens (containers, spacings, texts) emit `@media (min-width: …)` overrides.
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
---
|
|
46
52
|
|
|
47
|
-
|
|
53
|
+
## 📂 File structure
|
|
48
54
|
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
```
|
|
56
|
+
src/
|
|
57
|
+
├── tokens/
|
|
58
|
+
│ ├── primitives/
|
|
59
|
+
│ │ ├── colors/
|
|
60
|
+
│ │ │ ├── colors.js # base, blue, gray, violet, orange, slate, yellow,
|
|
61
|
+
│ │ │ │ # green, red + surface palettes + brand re-export
|
|
62
|
+
│ │ │ ├── brand.js # primary, accent, surfaces, absolute
|
|
63
|
+
│ │ │ └── alpha.js # alpha variants for each palette
|
|
64
|
+
│ │ ├── shape/
|
|
65
|
+
│ │ │ ├── aspect-video.js
|
|
66
|
+
│ │ │ ├── container.js # container-3xs … container-7xl
|
|
67
|
+
│ │ │ ├── height.js # h-2 … h-96
|
|
68
|
+
│ │ │ ├── radius.js # none, sm, DEFAULT, md, lg, xl, 2xl, 3xl, full
|
|
69
|
+
│ │ │ ├── shape.js # shape aliases (`max-w-*`, etc.)
|
|
70
|
+
│ │ │ ├── size.js # size-2 … size-96
|
|
71
|
+
│ │ │ ├── spacing.js # spacing-1 … spacing-96
|
|
72
|
+
│ │ │ └── width.js # w-3xs … w-7xl (alias → container.X)
|
|
73
|
+
│ │ ├── typography/
|
|
74
|
+
│ │ │ ├── font-family.js # sans, mono, code
|
|
75
|
+
│ │ │ ├── font-size.js # text-xs … text-9xl
|
|
76
|
+
│ │ │ ├── font-weight.js # 100 … 900
|
|
77
|
+
│ │ │ ├── leading.js # leading-3 … leading-10
|
|
78
|
+
│ │ │ ├── line-height.js # line-height-none … line-height-loose
|
|
79
|
+
│ │ │ └── tracking.js # tracking-tighter … tracking-widest
|
|
80
|
+
│ │ ├── effects/
|
|
81
|
+
│ │ │ ├── blur.js # blur-xs … blur-3xl
|
|
82
|
+
│ │ │ ├── drop-shadow.js
|
|
83
|
+
│ │ │ ├── inset-shadow.js
|
|
84
|
+
│ │ │ ├── opacity.js # opacity-0 … opacity-100
|
|
85
|
+
│ │ │ ├── perspective.js
|
|
86
|
+
│ │ │ └── shadow.js # box-shadow scale
|
|
87
|
+
│ │ ├── animations/
|
|
88
|
+
│ │ │ ├── animate.js # named keyframe animations
|
|
89
|
+
│ │ │ └── ease.js # easing curves
|
|
90
|
+
│ │ ├── border-widths.js # border-0 … border-4
|
|
91
|
+
│ │ ├── breakpoints.js # sm, md, lg, xl, 2xl
|
|
92
|
+
│ │ └── ring-offset.js
|
|
93
|
+
│ ├── theme/
|
|
94
|
+
│ │ ├── primary.js # primary, primary-mask/hover/contrast
|
|
95
|
+
│ │ ├── secondary.js
|
|
96
|
+
│ │ ├── accent.js
|
|
97
|
+
│ │ ├── surfaces.js # surface-0 … surface-950 (alias for gray)
|
|
98
|
+
│ │ ├── background.js # bg-canvas, bg-surface, bg-mask, …
|
|
99
|
+
│ │ ├── border.js # border-default/muted/strong/selected
|
|
100
|
+
│ │ ├── text.js # text-default, text-muted
|
|
101
|
+
│ │ ├── ring.js # ring-color
|
|
102
|
+
│ │ └── feedback/
|
|
103
|
+
│ │ ├── success.js
|
|
104
|
+
│ │ ├── warning.js
|
|
105
|
+
│ │ ├── danger.js
|
|
106
|
+
│ │ └── info.js
|
|
107
|
+
│ ├── semantic/
|
|
108
|
+
│ │ ├── colors.js # text/background/border semantic refs (consumed by v3 preset)
|
|
109
|
+
│ │ ├── containers.js # static + responsive container tokens
|
|
110
|
+
│ │ ├── containers.data.js # `{ key: { sm, md, lg, … } }` data table
|
|
111
|
+
│ │ ├── spacings.js
|
|
112
|
+
│ │ ├── spacings.data.js
|
|
113
|
+
│ │ ├── texts.js
|
|
114
|
+
│ │ ├── texts.data.js # font-size + line-height + letter-spacing bundles
|
|
115
|
+
│ │ └── animations.js
|
|
116
|
+
│ ├── theme.js # Tailwind theme.extend (colors + semantic mappings)
|
|
117
|
+
│ └── index.js # public re-exports
|
|
118
|
+
├── scripts/
|
|
119
|
+
│ ├── refs.js # tokenRef helper + isTokenRef guard
|
|
120
|
+
│ ├── resolve.js # resolves `tokenRef` paths to literal values
|
|
121
|
+
│ ├── css-vars.js # builds light/dark CSS var maps from semantic refs
|
|
122
|
+
│ ├── compile-primitives.js # flattens primitive trees into CSS vars
|
|
123
|
+
│ ├── compile-theme.js # legacy theme compiler (used by the harness pages)
|
|
124
|
+
│ └── build-tokens.mjs # main entrypoint: emits dist/v3 and dist/v4 bundles
|
|
125
|
+
└── tests/
|
|
126
|
+
├── primitives.html # visual harness for all primitives
|
|
127
|
+
├── theme.html # semantic tokens with light/dark toggle
|
|
128
|
+
└── tokens.html # combined view
|
|
52
129
|
```
|
|
53
130
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
## 💻 Development
|
|
131
|
+
---
|
|
57
132
|
|
|
58
|
-
|
|
133
|
+
## 🎨 Token types
|
|
59
134
|
|
|
60
|
-
###
|
|
135
|
+
### Primitives
|
|
61
136
|
|
|
62
|
-
|
|
137
|
+
Plain JS objects with literal values. Theme-invariant.
|
|
63
138
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
139
|
+
```js
|
|
140
|
+
// tokens/primitives/colors/brand.js
|
|
141
|
+
export const brandPrimitives = {
|
|
142
|
+
primary: { 50: '#FFF5EF', 100: '#FFE7D8', /* … */ 500: '#FE601F', /* … */ 950: '#401602' },
|
|
143
|
+
accent: { 50: '#F6F6FF', /* … */ 500: '#8A84EC', /* … */ 950: '#0B0A19' },
|
|
144
|
+
absolute: { black: '#0A0A0A', white: '#FCFCFC' },
|
|
145
|
+
};
|
|
146
|
+
```
|
|
70
147
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
```
|
|
148
|
+
```js
|
|
149
|
+
// tokens/primitives/shape/spacing.js
|
|
150
|
+
export const spacing = { 1: '4px', 2: '8px', /* … */ 96: '384px' };
|
|
151
|
+
```
|
|
76
152
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
cd ../azion-webkit && npm i && npm link azion-theme
|
|
81
|
-
```
|
|
153
|
+
### Semantic / theme
|
|
82
154
|
|
|
83
|
-
|
|
155
|
+
Objects with `light` / `dark` variants. Values are `tokenRef(...)` calls that point to primitives.
|
|
84
156
|
|
|
85
|
-
|
|
157
|
+
```js
|
|
158
|
+
// tokens/theme/primary.js
|
|
159
|
+
import { tokenRef } from '../../scripts/refs.js';
|
|
86
160
|
|
|
87
|
-
|
|
161
|
+
export const primary = {
|
|
162
|
+
light: {
|
|
163
|
+
primary: tokenRef('brand.primary.primary-500'),
|
|
164
|
+
'primary-mask': tokenRef('primitives.alpha.orange.100'),
|
|
165
|
+
'primary-hover': tokenRef('brand.primary.primary-600'),
|
|
166
|
+
'primary-contrast': tokenRef('primitives.base.black'),
|
|
167
|
+
},
|
|
168
|
+
dark: {
|
|
169
|
+
primary: tokenRef('brand.primary.primary-500'),
|
|
170
|
+
'primary-mask': tokenRef('primitives.alpha.orange.100'),
|
|
171
|
+
'primary-hover': tokenRef('brand.primary.primary-600'),
|
|
172
|
+
'primary-contrast': tokenRef('primitives.base.white'),
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
```
|
|
88
176
|
|
|
89
|
-
###
|
|
177
|
+
### Responsive semantic data (`*.data.js`)
|
|
90
178
|
|
|
91
|
-
|
|
92
|
-
// tailwind.config.js
|
|
93
|
-
import typography from '@tailwindcss/typography';
|
|
94
|
-
import { tokenUtilities } from 'azion-theme/tokens/build/tailwind-plugin';
|
|
95
|
-
import colors from 'azion-theme/tokens';
|
|
179
|
+
Containers, spacings, and texts use a per-breakpoint table that `build-tokens.mjs` flattens into `@media` overrides plus matching component classes (`.gap-…`, `.p-…`, `.text-…`, `.px-container`, `.py-container`, `.max-container-width`).
|
|
96
180
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
...colors,
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
plugins: [tokenUtilities(), typography],
|
|
181
|
+
```js
|
|
182
|
+
// tokens/semantic/spacings.data.js
|
|
183
|
+
export const spacingsData = {
|
|
184
|
+
'gap-sm': { _: '8px', md: '12px', xl: '16px' },
|
|
185
|
+
'gap-md': { _: '12px', md: '16px', xl: '24px' },
|
|
186
|
+
// …
|
|
108
187
|
};
|
|
109
188
|
```
|
|
110
189
|
|
|
111
|
-
|
|
190
|
+
`_` is the base value emitted in `:root`; the breakpoint keys (`sm`, `md`, `lg`, `xl`, `2xl`) become media-query overrides.
|
|
112
191
|
|
|
113
|
-
|
|
114
|
-
```javascript
|
|
115
|
-
// Primitive palettes (all with 50-950 shades)
|
|
116
|
-
colors.orange[500]; // #fe601f
|
|
117
|
-
colors.violet[500]; // #8a84ec
|
|
118
|
-
colors.neutral[900]; // #171717
|
|
192
|
+
---
|
|
119
193
|
|
|
120
|
-
|
|
121
|
-
colors.brand.black; // #0a0a0a
|
|
122
|
-
colors.brand.white; // #fafafa
|
|
123
|
-
colors.brand.orange; // #fe601f
|
|
194
|
+
## 🔧 Building & consuming
|
|
124
195
|
|
|
125
|
-
|
|
126
|
-
colors.primary[500]; // orange palette
|
|
127
|
-
colors.accent[500]; // violet palette
|
|
196
|
+
### Building the package
|
|
128
197
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
198
|
+
```bash
|
|
199
|
+
# emit both v3 and v4 bundles
|
|
200
|
+
pnpm --filter @aziontech/theme build:tokens
|
|
132
201
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
// Background colors - theme-aware layers
|
|
141
|
-
colors.background.layer1; // surface-0 (light) / surface-800 (dark)
|
|
142
|
-
colors.background.layer2; // surface-50 (light) / surface-700 (dark)
|
|
143
|
-
colors.background.canvas; // surface-100 (light) / surface-950 (dark)
|
|
144
|
-
|
|
145
|
-
// Border colors - theme-aware borders
|
|
146
|
-
colors.border.base; // surface-200 (light) / surface-700 (dark)
|
|
147
|
-
colors.border.primary; // primary-500 (both modes)
|
|
148
|
-
colors.border.accent; // accent-500 (both modes)
|
|
202
|
+
# only one target
|
|
203
|
+
pnpm --filter @aziontech/theme build:tokens:v3
|
|
204
|
+
pnpm --filter @aziontech/theme build:tokens:v4
|
|
205
|
+
|
|
206
|
+
# v3 + compile final CSS with tailwindcss
|
|
207
|
+
pnpm --filter @aziontech/theme build:css:v3
|
|
149
208
|
```
|
|
150
209
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
<!-- Semantic borders -->
|
|
166
|
-
<div class="border border-base">
|
|
167
|
-
Border adapts to current theme
|
|
168
|
-
</div>
|
|
169
|
-
|
|
170
|
-
<!-- Semantic interactive states -->
|
|
171
|
-
<button class="bg-layer1 hover:bg-layer1-hover border border-primary text-primary">
|
|
172
|
-
Themed button
|
|
173
|
-
</button>
|
|
210
|
+
Outputs land in `packages/theme/dist/v3/` and `packages/theme/dist/v4/`.
|
|
211
|
+
|
|
212
|
+
### Consuming in a Tailwind v3 project
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
// tailwind.config.js
|
|
216
|
+
import themePreset from '@aziontech/theme/tailwind-preset/v3'
|
|
217
|
+
|
|
218
|
+
export default {
|
|
219
|
+
presets: [themePreset],
|
|
220
|
+
content: ['./src/**/*.{vue,js,ts,jsx,tsx}'],
|
|
221
|
+
darkMode: ['class'],
|
|
222
|
+
}
|
|
174
223
|
```
|
|
175
224
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
<div class="bg-neutral-50 dark:bg-neutral-950">
|
|
180
|
-
Adaptive background
|
|
181
|
-
</div>
|
|
182
|
-
|
|
183
|
-
<!-- Text colors with dark variant -->
|
|
184
|
-
<p class="text-neutral-900 dark:text-neutral-100">
|
|
185
|
-
Primary text color
|
|
186
|
-
</p>
|
|
187
|
-
|
|
188
|
-
<!-- Border colors with dark variant -->
|
|
189
|
-
<div class="border border-neutral-200 dark:border-neutral-800">
|
|
190
|
-
Card with adaptive border
|
|
191
|
-
</div>
|
|
192
|
-
|
|
193
|
-
<!-- Using brand colors (no dark variant needed) -->
|
|
194
|
-
<button class="bg-orange-500 text-white hover:bg-orange-600">
|
|
195
|
-
Action Button
|
|
196
|
-
</button>
|
|
225
|
+
```css
|
|
226
|
+
/* main.css */
|
|
227
|
+
@import '@aziontech/theme/v3/globals.css';
|
|
197
228
|
```
|
|
198
229
|
|
|
199
|
-
|
|
230
|
+
Utilities like `text-default`, `bg-surface`, `border-default`, `text-primary`, `gap-md`, `p-md`, `.text-heading-lg`, etc. are then available everywhere.
|
|
200
231
|
|
|
201
|
-
|
|
202
|
-
- **Neutrals:** `neutral-50` → `neutral-950` (surface backgrounds, text, borders)
|
|
203
|
-
- **Brand:** `orange-50` → `orange-950` (primary actions)
|
|
204
|
-
- **Accent:** `violet-50` → `violet-950` (secondary highlights)
|
|
205
|
-
- **Status:** `red-*`, `green-*`, `yellow-*`, `blue-*` (semantic status colors)
|
|
232
|
+
### Consuming in a Tailwind v4 project
|
|
206
233
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
234
|
+
```css
|
|
235
|
+
/* main.css */
|
|
236
|
+
@import '@aziontech/theme/v4/globals.css';
|
|
237
|
+
```
|
|
211
238
|
|
|
212
|
-
|
|
239
|
+
No `tailwind.config.js` needed — v4 reads `@theme { … }` directly from the imported CSS.
|
|
213
240
|
|
|
214
|
-
|
|
241
|
+
### As JS objects (Node / build steps)
|
|
215
242
|
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
|
|
243
|
+
```js
|
|
244
|
+
import { createCssVars, cssVarsString } from '@aziontech/theme';
|
|
245
|
+
|
|
246
|
+
createCssVars(); // → { light: { '--text-default': '#1A1A1A', … }, dark: { … } }
|
|
247
|
+
cssVarsString(); // → ':root, [data-theme=light], .azion.azion-light { … } [data-theme=dark], … { … }'
|
|
219
248
|
```
|
|
220
249
|
|
|
221
|
-
###
|
|
222
|
-
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
brandColors,
|
|
228
|
-
brandPrimitives,
|
|
229
|
-
surfacePrimitives,
|
|
230
|
-
preset,
|
|
231
|
-
createTailwindConfig,
|
|
232
|
-
tokenUtilities
|
|
233
|
-
} from 'azion-theme/tokens';
|
|
250
|
+
### Injecting at runtime (browser)
|
|
251
|
+
|
|
252
|
+
```js
|
|
253
|
+
import { injectCssVars } from '@aziontech/theme';
|
|
254
|
+
|
|
255
|
+
injectCssVars(); // appends a <style data-azion-tokens> element to <head>
|
|
234
256
|
```
|
|
235
257
|
|
|
236
|
-
|
|
258
|
+
Only useful if you can't precompile and import `globals.css` — production usage should prefer the static stylesheet.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## ➕ How to add a new token
|
|
263
|
+
|
|
264
|
+
### Add a new primitive
|
|
265
|
+
|
|
266
|
+
1. Open the relevant file (e.g., `tokens/primitives/shape/spacing.js`).
|
|
267
|
+
2. Add the key/value:
|
|
268
|
+
|
|
269
|
+
```js
|
|
270
|
+
export const spacing = {
|
|
271
|
+
/* … */
|
|
272
|
+
128: '512px', // new
|
|
273
|
+
};
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
3. Rebuild (`pnpm --filter @aziontech/theme build:tokens`). The compiler picks it up and emits `--spacing-128: 512px`.
|
|
277
|
+
|
|
278
|
+
### Add a new semantic (theme) token
|
|
279
|
+
|
|
280
|
+
1. Pick the right file (`tokens/theme/*.js` or `tokens/theme/feedback/*.js`).
|
|
281
|
+
2. Add the key with `tokenRef(...)` for both `light` and `dark`:
|
|
282
|
+
|
|
283
|
+
```js
|
|
284
|
+
// tokens/theme/border.js
|
|
285
|
+
export const border = {
|
|
286
|
+
light: {
|
|
287
|
+
/* … */
|
|
288
|
+
'border-emphasis': tokenRef('primitives.gray.400'),
|
|
289
|
+
},
|
|
290
|
+
dark: {
|
|
291
|
+
/* … */
|
|
292
|
+
'border-emphasis': tokenRef('primitives.gray.500'),
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
3. Rebuild. The new variable lands in both `:root` and `[data-theme=dark]` blocks.
|
|
298
|
+
|
|
299
|
+
### Add a new responsive semantic token
|
|
300
|
+
|
|
301
|
+
1. Add an entry to the relevant `*.data.js` file in `tokens/semantic/`:
|
|
302
|
+
|
|
303
|
+
```js
|
|
304
|
+
// tokens/semantic/spacings.data.js
|
|
305
|
+
export const spacingsData = {
|
|
306
|
+
/* … */
|
|
307
|
+
'gap-2xl': { _: '32px', md: '40px', xl: '56px' },
|
|
308
|
+
};
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
2. Rebuild. `build-tokens.mjs` emits the base var in `:root`, per-breakpoint `@media` overrides, **and** a matching `.gap-2xl { gap: var(--gap-2xl) }` utility.
|
|
312
|
+
|
|
313
|
+
---
|
|
237
314
|
|
|
238
|
-
|
|
315
|
+
## 🔗 Token references (`tokenRef`)
|
|
239
316
|
|
|
240
|
-
|
|
241
|
-
- Ensure **Global** and **Semantic** variables are updated and organized correctly (naming, groups, modes, and values).
|
|
317
|
+
`tokenRef(path)` returns a marker object `{ __ref: path }` that the compiler resolves at build time. Supported path prefixes (see `scripts/resolve.js`):
|
|
242
318
|
|
|
243
|
-
|
|
319
|
+
| Prefix | Looks up |
|
|
320
|
+
|---|---|
|
|
321
|
+
| `primitives.X.Y.Z` | `tokens/primitives/colors/colors.js` tree (e.g., `primitives.gray.900`, `primitives.alpha.orange.100`) |
|
|
322
|
+
| `surfacePrimitives.surface.N` | the surface palette (used internally; usually referenced via `brand.surfaces.…`) |
|
|
323
|
+
| `brand.surfaces.surface-N` | `surfacePrimitives.surface[N]` (e.g., `brand.surfaces.surface-100` → `#F5F5F5`) |
|
|
324
|
+
| `brand.primary.primary-N` | `brandPrimitives.primary[N]` (e.g., `brand.primary.primary-500` → `#FE601F`) |
|
|
325
|
+
| `brand.accent.accent-N` | `brandPrimitives.accent[N]` |
|
|
326
|
+
| `brand.absolute.X` | `brandPrimitives.absolute.X` (`black` / `white`) |
|
|
244
327
|
|
|
245
|
-
|
|
246
|
-
- Use Tokens Studio’s import-from-variables flow to bring the current Variables state into the token sets.
|
|
328
|
+
Refs of unknown prefixes are left as the raw path string in the output — flag for "this needs resolver support".
|
|
247
329
|
|
|
248
|
-
|
|
249
|
-
- Export using **Multiple files**.
|
|
330
|
+
---
|
|
250
331
|
|
|
251
|
-
|
|
252
|
-
- Place them under [`src/tokens/figma-reference-tokens-studio/`](src/tokens/figma-reference-tokens-studio:1) (replace existing contents).
|
|
332
|
+
## 🧪 Test pages
|
|
253
333
|
|
|
254
|
-
|
|
255
|
-
- Run:
|
|
334
|
+
Local visual harnesses (require a static server because of ESM imports):
|
|
256
335
|
|
|
257
336
|
```bash
|
|
258
|
-
|
|
337
|
+
npx http-server packages/theme/src -p 8080
|
|
259
338
|
```
|
|
260
339
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
Files affected by the script:
|
|
265
|
-
- [`src/tokens/primitives/colors.js`](src/tokens/primitives/colors.js)
|
|
266
|
-
- [`src/tokens/primitives/brand.js`](src/tokens/primitives/brand.js)
|
|
267
|
-
- [`src/tokens/semantic/text.js`](src/tokens/semantic/text.js)
|
|
268
|
-
- [`src/tokens/semantic/backgrounds.js`](src/tokens/semantic/backgrounds.js)
|
|
269
|
-
- [`src/tokens/semantic/borders.js`](src/tokens/semantic/borders.js)
|
|
270
|
-
|
|
271
|
-
### 🧰 Manual Maintenance (Without Script)
|
|
272
|
-
|
|
273
|
-
When updating or adding tokens manually, edit the files below depending on the token type:
|
|
274
|
-
|
|
275
|
-
- **Primitive palettes:** [`src/tokens/primitives/colors.js`](src/tokens/primitives/colors.js)
|
|
276
|
-
- **Brand + surface primitives:** [`src/tokens/primitives/brand.js`](src/tokens/primitives/brand.js)
|
|
277
|
-
- **Semantic text (light/dark):** [`src/tokens/semantic/text.js`](src/tokens/semantic/text.js)
|
|
278
|
-
- **Semantic backgrounds (light/dark):** [`src/tokens/semantic/backgrounds.js`](src/tokens/semantic/backgrounds.js)
|
|
279
|
-
- **Semantic borders (light/dark):** [`src/tokens/semantic/borders.js`](src/tokens/semantic/borders.js)
|
|
280
|
-
- **Brand aliases:** [`src/tokens/colors-brand.js`](src/tokens/colors-brand.js)
|
|
281
|
-
- **Tailwind mappings (class names):** [`src/tokens/build/preset.js`](src/tokens/build/preset.js)
|
|
282
|
-
- **CSS vars output/selectors:** [`src/tokens/build/css-vars.js`](src/tokens/build/css-vars.js)
|
|
283
|
-
|
|
284
|
-
Checklist when adding a new token manually:
|
|
285
|
-
1) Add/update the primitive or surface scale value (if needed).
|
|
286
|
-
2) Add matching semantic entries for both `light` and `dark`.
|
|
287
|
-
3) Update Tailwind mappings if you want a class for the token.
|
|
288
|
-
4) Regenerate or verify CSS vars output for both themes.
|
|
289
|
-
|
|
290
|
-
### 🎨 Available Colors
|
|
291
|
-
|
|
292
|
-
#### Main Palette (Orange)
|
|
293
|
-
- `orange-50` → `orange-950`
|
|
294
|
-
- **Primary**: `orange-500` (#fe601f)
|
|
295
|
-
|
|
296
|
-
#### Brand Palette
|
|
297
|
-
- `brand-black` (#0a0a0a)
|
|
298
|
-
- `brand-white` (#fafafa)
|
|
299
|
-
- `brand-dark-gray` (#171717)
|
|
300
|
-
- `brand-medium-gray` (#737373)
|
|
301
|
-
|
|
302
|
-
#### Other Complete Palettes
|
|
303
|
-
- **Violet, Slate, Gray, Neutral, Blue, Red, Yellow, Green**
|
|
304
|
-
- All with 11 shades (50 → 950)
|
|
305
|
-
|
|
306
|
-
#### Semantic Colors
|
|
307
|
-
- `primary` (orange-500)
|
|
308
|
-
- `success` (green-500)
|
|
309
|
-
- `warning` (yellow-500)
|
|
310
|
-
- `error` (red-500)
|
|
311
|
-
- `info` (blue-500)
|
|
312
|
-
|
|
313
|
-
### ⚠️ Troubleshooting
|
|
314
|
-
|
|
315
|
-
#### If you get import errors:
|
|
316
|
-
|
|
317
|
-
**ES Modules (recommended)**
|
|
318
|
-
```javascript
|
|
319
|
-
import colors from 'azion-theme/tokens';
|
|
320
|
-
```
|
|
340
|
+
- `http://localhost:8080/tests/primitives.html` — every primitive rendered as a swatch / scale.
|
|
341
|
+
- `http://localhost:8080/tests/theme.html` — semantic tokens with a **light/dark toggle**.
|
|
342
|
+
- `http://localhost:8080/tests/tokens.html` — combined view.
|
|
321
343
|
|
|
322
|
-
|
|
323
|
-
```javascript
|
|
324
|
-
import { primitives, brandColors, brandPrimitives, surfacePrimitives } from 'azion-theme/tokens';
|
|
325
|
-
```
|
|
344
|
+
---
|
|
326
345
|
|
|
327
|
-
|
|
328
|
-
```javascript
|
|
329
|
-
import { primitives } from 'azion-theme/tokens/primitives/colors.js';
|
|
330
|
-
import { brandColors } from 'azion-theme/tokens/colors-brand.js';
|
|
331
|
-
```
|
|
346
|
+
## 🌗 Theme switching
|
|
332
347
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
348
|
+
The compiled CSS targets multiple hooks so the runtime can pick whichever convention the consumer uses:
|
|
349
|
+
|
|
350
|
+
```css
|
|
351
|
+
:root, [data-theme=light], .azion.azion-light {
|
|
352
|
+
/* light theme vars */
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
[data-theme=dark], .dark, .azion.azion-dark {
|
|
356
|
+
/* dark theme vars */
|
|
340
357
|
}
|
|
341
358
|
```
|
|
342
359
|
|
|
360
|
+
Switching is a one-liner:
|
|
361
|
+
|
|
362
|
+
```js
|
|
363
|
+
// data-attribute strategy
|
|
364
|
+
document.documentElement.setAttribute('data-theme', 'dark'); // or 'light'
|
|
365
|
+
|
|
366
|
+
// Tailwind class strategy
|
|
367
|
+
document.documentElement.classList.toggle('dark');
|
|
368
|
+
|
|
369
|
+
// Azion namespaced classes (use one or the other)
|
|
370
|
+
document.documentElement.classList.add('azion', 'azion-dark');
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
All three strategies hit the same set of CSS variables.
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
343
377
|
## 🔗 Links
|
|
344
378
|
|
|
345
379
|
- [Figma Global Tokens](https://www.figma.com/design/t97pXRs7xME3SJDs5iZ5RF/Global-Tokens?node-id=0-1)
|