@kazamitte/design-token 0.0.0-stage → 0.3.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.
@@ -0,0 +1,138 @@
1
+ {
2
+ "red": {
3
+ "secondary": ["indigo", "fuchsia", "purple", "violet"],
4
+ "base": {
5
+ "harmonized": ["taupe", "stone"],
6
+ "achromatic": ["neutral", "zinc", "gray"]
7
+ },
8
+ "link": ["indigo", "violet", "purple", "blue"]
9
+ },
10
+ "orange": {
11
+ "secondary": ["indigo", "purple", "violet", "fuchsia"],
12
+ "base": {
13
+ "harmonized": ["taupe", "stone"],
14
+ "achromatic": ["neutral", "zinc", "gray"]
15
+ },
16
+ "link": ["indigo", "violet", "purple", "blue"]
17
+ },
18
+ "amber": {
19
+ "secondary": ["indigo", "violet", "purple", "blue"],
20
+ "base": {
21
+ "harmonized": ["stone", "taupe", "olive"],
22
+ "achromatic": ["neutral", "zinc", "gray"]
23
+ },
24
+ "link": ["indigo", "violet", "purple", "blue"]
25
+ },
26
+ "yellow": {
27
+ "secondary": ["indigo", "violet", "purple", "blue"],
28
+ "base": {
29
+ "harmonized": ["olive", "stone"],
30
+ "achromatic": ["neutral", "zinc", "gray"]
31
+ },
32
+ "link": ["indigo", "violet", "purple", "blue"]
33
+ },
34
+ "lime": {
35
+ "secondary": ["indigo", "violet", "purple", "blue"],
36
+ "base": {
37
+ "harmonized": ["olive", "stone"],
38
+ "achromatic": ["neutral", "gray", "zinc"]
39
+ },
40
+ "link": ["indigo", "violet", "purple", "blue"]
41
+ },
42
+ "green": {
43
+ "secondary": ["indigo", "blue", "violet", "purple"],
44
+ "base": {
45
+ "harmonized": ["olive", "mist"],
46
+ "achromatic": ["neutral", "gray", "zinc"]
47
+ },
48
+ "link": ["indigo", "violet", "purple", "blue"]
49
+ },
50
+ "emerald": {
51
+ "secondary": ["indigo", "blue", "violet", "purple"],
52
+ "base": {
53
+ "harmonized": ["mist", "olive"],
54
+ "achromatic": ["neutral", "gray", "zinc"]
55
+ },
56
+ "link": ["indigo", "violet", "purple", "blue"]
57
+ },
58
+ "teal": {
59
+ "secondary": ["lime", "orange", "amber", "yellow"],
60
+ "base": {
61
+ "harmonized": ["mist", "slate"],
62
+ "achromatic": ["neutral", "gray", "zinc"]
63
+ },
64
+ "link": ["indigo", "violet", "purple", "blue"]
65
+ },
66
+ "cyan": {
67
+ "secondary": ["lime", "yellow", "amber", "orange"],
68
+ "base": {
69
+ "harmonized": ["mist", "slate"],
70
+ "achromatic": ["neutral", "gray", "zinc"]
71
+ },
72
+ "link": ["indigo", "violet", "purple", "blue"]
73
+ },
74
+ "sky": {
75
+ "secondary": ["lime", "yellow", "amber", "orange"],
76
+ "base": {
77
+ "harmonized": ["slate", "mist"],
78
+ "achromatic": ["neutral", "gray", "zinc"]
79
+ },
80
+ "link": ["indigo", "violet", "purple", "blue"]
81
+ },
82
+ "blue": {
83
+ "secondary": ["lime", "yellow", "amber", "orange"],
84
+ "base": {
85
+ "harmonized": ["slate", "mist"],
86
+ "achromatic": ["neutral", "gray", "zinc"]
87
+ },
88
+ "link": ["indigo", "violet", "purple", "blue"]
89
+ },
90
+ "indigo": {
91
+ "secondary": ["lime", "yellow", "amber", "orange"],
92
+ "base": {
93
+ "harmonized": ["slate", "mauve"],
94
+ "achromatic": ["neutral", "zinc", "gray"]
95
+ },
96
+ "link": ["indigo", "violet", "purple", "blue"]
97
+ },
98
+ "violet": {
99
+ "secondary": ["yellow", "lime", "amber", "orange"],
100
+ "base": {
101
+ "harmonized": ["mauve", "slate"],
102
+ "achromatic": ["neutral", "zinc", "gray"]
103
+ },
104
+ "link": ["indigo", "violet", "purple", "blue"]
105
+ },
106
+ "purple": {
107
+ "secondary": ["yellow", "amber", "lime", "orange"],
108
+ "base": {
109
+ "harmonized": ["mauve", "slate"],
110
+ "achromatic": ["neutral", "zinc", "gray"]
111
+ },
112
+ "link": ["indigo", "violet", "purple", "blue"]
113
+ },
114
+ "fuchsia": {
115
+ "secondary": ["amber", "yellow", "orange", "lime"],
116
+ "base": {
117
+ "harmonized": ["mauve", "slate"],
118
+ "achromatic": ["neutral", "zinc", "gray"]
119
+ },
120
+ "link": ["indigo", "violet", "purple", "blue"]
121
+ },
122
+ "pink": {
123
+ "secondary": ["orange", "amber", "yellow", "red"],
124
+ "base": {
125
+ "harmonized": ["mauve", "taupe"],
126
+ "achromatic": ["neutral", "zinc", "gray"]
127
+ },
128
+ "link": ["indigo", "violet", "purple", "blue"]
129
+ },
130
+ "rose": {
131
+ "secondary": ["indigo", "fuchsia", "purple", "violet"],
132
+ "base": {
133
+ "harmonized": ["taupe", "stone"],
134
+ "achromatic": ["neutral", "zinc", "gray"]
135
+ },
136
+ "link": ["indigo", "violet", "purple", "blue"]
137
+ }
138
+ }
@@ -0,0 +1,19 @@
1
+ # Color theme generation
2
+
3
+ `generateColorTheme` is a function that returns CSS as a string, allowing the application to generate its own custom themes. A sample showing how to write the output to a file is provided below.
4
+
5
+ ```js
6
+ import { writeFile } from 'node:fs/promises';
7
+ import { generateColorTheme } from '@kazamitte/design-token';
8
+
9
+ const css = generateColorTheme({
10
+ primary: 'teal',
11
+ secondary: 'violet',
12
+ base: 'mist',
13
+ link: 'blue',
14
+ });
15
+
16
+ await writeFile('src/styles/generated/theme.css', css);
17
+ ```
18
+
19
+ For information on color pairings, please refer to [color-pairings.md](./color-pairings.md). It lists recommended secondary, base, and link colors for each of the 17 primary colors.
@@ -0,0 +1,179 @@
1
+ # Fixing class conflicts with tailwind-merge
2
+
3
+ - Classes made with the `@utility` directive are invisible to tailwind-merge. By default `text-body-16` and `text-dense-14` do not cancel each other.
4
+ - Semantic names generated from a `@theme` namespace have the same problem. `rounded-surface`, `shadow-raised`, `ease-standard`, `animate-fade-in` and `z-modal` are not on a scale tailwind-merge knows.
5
+ - `conflictingClassGroups` copies what Tailwind's own `text-lg` does: a later `text-*` cancels an earlier `leading-*`.
6
+
7
+ ## Use tailwind-merge's own group names
8
+
9
+ Every key in `extend.classGroups` **must match an existing group name exactly**. A key that does not match adds a new group instead of extending the old one.
10
+
11
+ Say you write `'transition-duration'`. Then `duration-instant` and `duration-enter` do cancel each other, but they sit in a different group from Tailwind's `duration-200`, so `duration-200 duration-transition` keeps both classes. The correct key is `'duration'`.
12
+
13
+ Read the keys of `getDefaultConfig().classGroups` to check a name. These are the ones this package needs.
14
+
15
+ | Token | Group name |
16
+ | ---------------------------- | --------------- |
17
+ | `text-body-16` and the rest | `font-size` |
18
+ | `rounded-surface` and so on | `rounded` |
19
+ | `shadow-raised` and so on | `shadow` |
20
+ | `duration-enter` and so on | `duration` |
21
+ | `ease-standard` and so on | `ease` |
22
+ | `animate-fade-in` and so on | `animate` |
23
+ | `z-modal` and so on | `z` |
24
+ | `primary-bg-solid` and so on | `bg-color` |
25
+ | `primary-fg` and so on | `text-color` |
26
+ | `primary-border-solid` … | `border-color` |
27
+ | `primary-focus-ring` … | `outline-color` |
28
+
29
+ Two of these are easy to get wrong: the z-index group is `z`, not `z-index`, and the font size group is `font-size`, not `text`.
30
+
31
+ `animate-*` can also be registered through `extend.theme.animate`, which tailwind-merge reads as a scale. The config below uses `classGroups` for it so that every token is registered the same way. There is no theme key for z-index, so `z` has to go through `classGroups` in any case.
32
+
33
+ ## Color roles need their full class names
34
+
35
+ A color role utility is named `{role}-{token}`, so its prefix is not Tailwind's `bg-*` or `text-*`. The short form (`{ bg: [...] }`) cannot say that, so the full class names are listed instead.
36
+
37
+ Without them an override like `tv({ base: 'primary-bg-solid', variants: { disabled: { true: 'base-bg-muted' } } })` does nothing. Both classes stay, and the CSS order decides which one wins.
38
+
39
+ ## Config
40
+
41
+ ```ts
42
+ import { createTV, type VariantProps } from 'tailwind-variants';
43
+
44
+ const ROLES = [
45
+ 'base',
46
+ 'primary',
47
+ 'secondary',
48
+ 'error',
49
+ 'warning',
50
+ 'success',
51
+ 'info',
52
+ ];
53
+
54
+ const roleClasses = (suffixes: string[]) =>
55
+ ROLES.flatMap((role) => suffixes.map((suffix) => `${role}-${suffix}`));
56
+
57
+ export const tv = createTV({
58
+ twMerge: true,
59
+ twMergeConfig: {
60
+ extend: {
61
+ classGroups: {
62
+ 'font-size': [
63
+ {
64
+ text: [
65
+ 'display-64',
66
+ 'display-56',
67
+ 'display-48',
68
+ 'display-44',
69
+ 'highlight-36',
70
+ 'highlight-32',
71
+ 'highlight-28',
72
+ 'highlight-26',
73
+ 'highlight-24',
74
+ 'highlight-22',
75
+ 'body-20',
76
+ 'body-18',
77
+ 'body-16',
78
+ 'dense-18',
79
+ 'dense-16',
80
+ 'dense-14',
81
+ 'dense-18-compact',
82
+ 'dense-16-compact',
83
+ 'dense-14-compact',
84
+ 'oneline-18',
85
+ 'oneline-16',
86
+ 'oneline-14',
87
+ 'mono-18',
88
+ 'mono-16',
89
+ 'mono-14',
90
+ ],
91
+ },
92
+ ],
93
+ duration: [{ duration: ['instant', 'transition', 'enter'] }],
94
+ rounded: [
95
+ { rounded: ['tight', 'control', 'surface', 'overlay', 'pill'] },
96
+ ],
97
+ shadow: [
98
+ {
99
+ shadow: [
100
+ 'flat',
101
+ 'flat-hover',
102
+ 'raised',
103
+ 'raised-hover',
104
+ 'floating',
105
+ 'floating-hover',
106
+ 'overlay',
107
+ ],
108
+ },
109
+ ],
110
+ ease: [{ ease: ['standard', 'emphasized'] }],
111
+ animate: [
112
+ {
113
+ animate: [
114
+ 'fade-in',
115
+ 'fade-out',
116
+ 'scale-in',
117
+ 'scale-out',
118
+ 'slide-in-from-top',
119
+ 'slide-in-from-right',
120
+ 'slide-in-from-bottom',
121
+ 'slide-in-from-left',
122
+ 'slide-out-to-top',
123
+ 'slide-out-to-right',
124
+ 'slide-out-to-bottom',
125
+ 'slide-out-to-left',
126
+ ],
127
+ },
128
+ ],
129
+ z: [
130
+ {
131
+ z: [
132
+ 'hide',
133
+ 'base',
134
+ 'docked',
135
+ 'dropdown',
136
+ 'sticky',
137
+ 'banner',
138
+ 'overlay',
139
+ 'modal',
140
+ 'popover',
141
+ 'skip-nav',
142
+ 'toast',
143
+ 'tooltip',
144
+ 'max',
145
+ ],
146
+ },
147
+ ],
148
+
149
+ 'bg-color': roleClasses([
150
+ 'bg',
151
+ 'bg-subtle',
152
+ 'bg-muted',
153
+ 'bg-selected',
154
+ 'bg-solid',
155
+ ]),
156
+ 'text-color': [
157
+ ...roleClasses(['fg-strong', 'fg', 'fg-muted', 'fg-subtle', 'fg-contrast']),
158
+ 'link-fg',
159
+ 'link-fg-strong',
160
+ ],
161
+ 'border-color': roleClasses([
162
+ 'border-subtle',
163
+ 'border-muted',
164
+ 'border-selected',
165
+ 'border-solid',
166
+ ]),
167
+ 'outline-color': roleClasses(['focus-ring']),
168
+ },
169
+ conflictingClassGroups: {
170
+ 'font-size': ['leading'],
171
+ },
172
+ },
173
+ },
174
+ });
175
+
176
+ export type { VariantProps };
177
+ ```
178
+
179
+ `example/src/lib/tv.test.ts` checks two things for every group: that the classes in it cancel each other, and that pairs which must **not** cancel both survive — `text-red-500` with `text-body-16`, `shadow-red-500` with `shadow-raised`, `animate-slide-in-from-bottom` with `[--slide-distance:1rem]`.
package/package.json CHANGED
@@ -1,6 +1,46 @@
1
1
  {
2
2
  "name": "@kazamitte/design-token",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.3.0",
4
+ "description": "Tailwind CSS v4 design token — color, typography, and style themes.",
5
+ "license": "MIT",
6
+ "author": "kazaminn",
7
+ "homepage": "https://github.com/kazamitte/design-token#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/kazamitte/design-token.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/kazamitte/design-token/issues"
14
+ },
15
+ "type": "module",
16
+ "sideEffects": [
17
+ "*.css"
18
+ ],
19
+ "files": [
20
+ "dist",
21
+ "docs",
22
+ "tailwind",
23
+ "THIRD-PARTY-NOTICES.md"
24
+ ],
25
+ "types": "./dist/generate-theme.d.mts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/generate-theme.d.mts",
29
+ "import": "./dist/generate-theme.mjs"
30
+ },
31
+ "./index.css": "./tailwind/index.css",
32
+ "./base/initialize.css": "./tailwind/base/initialize.css",
33
+ "./base/color/*.css": "./tailwind/base/color/*.css",
34
+ "./base/typography/*.css": "./tailwind/base/typography/*.css",
35
+ "./base/style/*.css": "./tailwind/base/style/*.css",
36
+ "./theme/color/*.css": "./tailwind/theme/color/*.css",
37
+ "./theme/style/*.css": "./tailwind/theme/style/*.css",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "peerDependencies": {
41
+ "tailwindcss": "^4.0.0"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ }
46
+ }