@anyknown/ui 0.1.0 → 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.
- package/README.md +21 -18
- package/dist/themes.stylex.d.ts +279 -2
- package/dist/themes.stylex.js +149 -7
- package/dist/tokens.css +10 -3
- package/dist/tokens.stylex.d.ts +2 -0
- package/dist/tokens.stylex.js +5 -1
- package/package.json +11 -2
- package/dist/lib/format.test.d.ts +0 -1
- package/dist/lib/format.test.js +0 -37
package/README.md
CHANGED
|
@@ -6,12 +6,12 @@ AnyKnown 全產品線共用的 design system,以 [StyleX](https://stylexjs.com)
|
|
|
6
6
|
|
|
7
7
|
- `src/tokens.stylex.ts` — semantic tokens(color / font / text / space / radius / motion / shadow)。light 為預設,dark 跟隨 OS。**唯一真相**。
|
|
8
8
|
- `src/tokens.css` — 同一組值的純 CSS variables(`--ak-*`),給非 StyleX 的使用端(desktop 的 Tailwind v4 `@theme` 直接引用)。import 路徑:`@anyknown/ui/tokens.css`。
|
|
9
|
-
- `src/themes.stylex.ts` — `light` / `dark` theme,給有手動切換主題的 app(
|
|
9
|
+
- `src/themes.stylex.ts` — `light` / `dark` theme,給有手動切換主題的 app:`<div {...stylex.props(...light)}>`。**由 `pnpm gen:themes` 從 tokens 生成**,不要手改(`themes.test.ts` 會擋住不同步)。
|
|
10
10
|
- `src/scrollbar.css` — 客製捲軸(全域套用)。StyleX 做不了 `::-webkit-scrollbar` 偽元素,所以獨立成 css 檔。
|
|
11
|
-
- `src/components/` — 34 個元件,每個一個 folder(`<Name>.tsx` + `<Name>.test.tsx`
|
|
12
|
-
- `src/lib/` — 共用 hooks 與生成邏輯(reduced-motion、controllable state、clipboard、
|
|
11
|
+
- `src/components/` — 34 個元件,每個一個 folder(`<Name>.tsx` + `<Name>.test.tsx`)。清單與共同決策見 [components/README.md](./src/components/README.md),定案理由與走過的彎路見 [components/COMPONENTS.md](./src/components/COMPONENTS.md)。
|
|
12
|
+
- `src/lib/` — 共用 hooks 與生成邏輯(reduced-motion、controllable state、clipboard、diff、`styled` 與 `reset.control`)。織體幾何在 `weave.ts`(靜態)與 `silk.ts`(動態),規格見 [components/TEXTURE-GUIDE.md](./src/components/TEXTURE-GUIDE.md)。
|
|
13
13
|
- `playground/` — demo app,**不進發佈產物**。
|
|
14
|
-
- `site/` — 文檔網站(全部示範 +
|
|
14
|
+
- `site/` — 文檔網站(全部示範 + 四份指南),部署到 Cloudflare Workers,**不進發佈產物**。
|
|
15
15
|
|
|
16
16
|
## 開發
|
|
17
17
|
|
|
@@ -21,20 +21,20 @@ pnpm check # turbo run typecheck lint fmt:check(平行 + 快取)
|
|
|
21
21
|
pnpm build # dist:ESM + d.ts + tokens.css + scrollbar.css
|
|
22
22
|
pnpm verify:pack # build 後打包,從套件外部解析 exports map 每個入口
|
|
23
23
|
pnpm playground # http://localhost:5199,用打包後的 dist 渲染全部元件
|
|
24
|
-
pnpm site # http://localhost:5200,文檔網站(示範 +
|
|
24
|
+
pnpm site # http://localhost:5200,文檔網站(示範 + 指南)
|
|
25
25
|
pnpm site:test # 文檔網站的 jsdom 冒煙測試
|
|
26
|
-
pnpm site:deploy # build 後
|
|
26
|
+
pnpm site:deploy # build 後 deploy 到 https://ui.anyknown.com(需先 wrangler login)
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
playground
|
|
29
|
+
playground 與文檔站用同一組 section id,`#/demo/<name>` 直接跳到該元件。
|
|
30
30
|
|
|
31
|
-
`check` / `test` / `build` 等都由 [turborepo](https://turborepo.dev) 驅動(single-package 模式,設定在 `turbo.json`),快取推到自架的 remote cache `https://turbo.anyknown.com`(team `anyknown`)。要吃到遠端快取就 export token:
|
|
31
|
+
`check` / `test` / `build` 等都由 [turborepo](https://turborepo.dev) 驅動(single-package 模式,設定在 `turbo.json`),快取推到自架的 remote cache `https://turbo.anyknown.com`(team `anyknown-ui`)。要吃到遠端快取就 export token:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
export TURBO_TOKEN=<token> # 見 turbo-cache-worker/GITHUB-SECRETS.md
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
沒設也不會壞,只是退回本機快取。`turbo.json` 裡 `build` / `lint` / `typecheck` / `test` 的 inputs 刻意排除了 `*.md
|
|
37
|
+
沒設也不會壞,只是退回本機快取。`turbo.json` 裡 `build` / `lint` / `typecheck` / `test` 的 inputs 刻意排除了 `*.md`,所以改文件不會讓這些 task 重跑;`site:build` / `site:test` 用預設 inputs,因為文檔網站會讀那些 md。
|
|
38
38
|
|
|
39
39
|
## 發佈
|
|
40
40
|
|
|
@@ -43,7 +43,7 @@ export TURBO_TOKEN=<token> # 見 turbo-cache-worker/GITHUB-SECRETS.md
|
|
|
43
43
|
版本由 **git tag 決定**。推一個 `v*` tag 上去,`.github/workflows/release.yml` 跑完整條 gate 再 publish;tag 與 `package.json` 的 `version` 對不上會直接失敗,不會發出去。
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
# 1. 改 package.json 的 version(semver
|
|
46
|
+
# 1. 改 package.json 的 version(semver)
|
|
47
47
|
# 2. commit + 打 tag + 推
|
|
48
48
|
git commit -am "release: v0.2.0"
|
|
49
49
|
git tag v0.2.0
|
|
@@ -52,17 +52,20 @@ git push origin main --tags
|
|
|
52
52
|
|
|
53
53
|
CI 跑的是 `typecheck / lint / fmt:check / test / site:test` → `verify:pack` → `npm publish`。前五項走 turbo remote cache,PR 上跑過的多半直接命中;`verify:pack` 不快取,它就是要每次重打一次 tarball、從套件外部解析 exports map。
|
|
54
54
|
|
|
55
|
-
publish
|
|
55
|
+
publish 走 **npm trusted publishing (OIDC)**,repo 裡不存任何 npm 憑證 —— trusted publisher 綁在 npmjs.com 的 `@anyknown/ui` → `anyknown-com/ui` / `release.yml`。CI 用的是 `npm publish` 而不是 `pnpm publish`,因為 pnpm 的 OIDC 支援還沒好([pnpm#9812](https://github.com/pnpm/pnpm/issues/9812))。
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
v0.1.0 是本機手動發的:npm 的 trusted publisher 只能綁在**已存在的套件**上,第一版繞不掉。之後都走 tag。
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
CI 驗不了的只剩視覺:發之前 `pnpm playground` 開一輪看視覺與動效沒跑掉,順手開 macOS 的「減少動態效果」再看一次。
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
### 基礎設施現況
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
| | |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| repo | <https://github.com/anyknown-com/ui>(public、MIT) |
|
|
66
|
+
| npm | `@anyknown/ui`,trusted publisher 綁 `anyknown-com/ui` → `release.yml` |
|
|
67
|
+
| 文檔站 | <https://ui.anyknown.com>(Cloudflare Workers) |
|
|
68
|
+
| remote cache | `turbo.anyknown.com`,team `anyknown-ui`;token 在 repo secret `TURBO_TOKEN`,本機 `export TURBO_TOKEN=<token>`(worker 端的來源是 `anyknown-com/turbo-cache` 的 secret binding) |
|
|
66
69
|
|
|
67
70
|
## 在各 app 使用(Vite)
|
|
68
71
|
|
|
@@ -118,4 +121,4 @@ app 自己的樣式一律引用 tokens,不寫死色值。`playground/` 就是照
|
|
|
118
121
|
pnpm add @fontsource-variable/newsreader @fontsource-variable/geist @fontsource-variable/geist-mono
|
|
119
122
|
```
|
|
120
123
|
|
|
121
|
-
Texture(線/織的品牌語言)
|
|
124
|
+
Texture(線/織的品牌語言)只用在等待、過渡、儀式時刻與主要互動面,精確區不加花 —— 規格與適配指引見 [components/TEXTURE-GUIDE.md](./src/components/TEXTURE-GUIDE.md)。
|
package/dist/themes.stylex.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as stylex from "@stylexjs/stylex";
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const lightColor: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
3
3
|
bg: string;
|
|
4
4
|
surface: string;
|
|
5
5
|
surfaceRaised: string;
|
|
@@ -17,13 +17,73 @@ export declare const light: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
|
17
17
|
successSubtle: string;
|
|
18
18
|
warning: string;
|
|
19
19
|
warningSubtle: string;
|
|
20
|
+
info: string;
|
|
21
|
+
infoSubtle: string;
|
|
20
22
|
focusRing: string;
|
|
21
23
|
bone: string;
|
|
22
24
|
sheen: string;
|
|
23
25
|
successHl: string;
|
|
24
26
|
dangerHl: string;
|
|
25
27
|
}>, symbol>, symbol>;
|
|
26
|
-
export declare const
|
|
28
|
+
export declare const lightYarn: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
29
|
+
un: string;
|
|
30
|
+
sh: string;
|
|
31
|
+
y0: string;
|
|
32
|
+
y1: string;
|
|
33
|
+
y2: string;
|
|
34
|
+
y3: string;
|
|
35
|
+
y4: string;
|
|
36
|
+
hi: string;
|
|
37
|
+
shadow: string;
|
|
38
|
+
}>, symbol>, symbol>;
|
|
39
|
+
export declare const lightYarnSecondary: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
40
|
+
un: string;
|
|
41
|
+
sh: string;
|
|
42
|
+
y0: string;
|
|
43
|
+
y1: string;
|
|
44
|
+
y2: string;
|
|
45
|
+
y3: string;
|
|
46
|
+
y4: string;
|
|
47
|
+
hi: string;
|
|
48
|
+
shadow: string;
|
|
49
|
+
}>, symbol>, symbol>;
|
|
50
|
+
export declare const lightYarnGhost: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
51
|
+
un: string;
|
|
52
|
+
sh: string;
|
|
53
|
+
y0: string;
|
|
54
|
+
y1: string;
|
|
55
|
+
y2: string;
|
|
56
|
+
y3: string;
|
|
57
|
+
y4: string;
|
|
58
|
+
hi: string;
|
|
59
|
+
shadow: string;
|
|
60
|
+
}>, symbol>, symbol>;
|
|
61
|
+
export declare const lightYarnDanger: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
62
|
+
un: string;
|
|
63
|
+
sh: string;
|
|
64
|
+
y0: string;
|
|
65
|
+
y1: string;
|
|
66
|
+
y2: string;
|
|
67
|
+
y3: string;
|
|
68
|
+
y4: string;
|
|
69
|
+
hi: string;
|
|
70
|
+
shadow: string;
|
|
71
|
+
}>, symbol>, symbol>;
|
|
72
|
+
export declare const lightYarnSubtle: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
73
|
+
un: string;
|
|
74
|
+
sh: string;
|
|
75
|
+
y0: string;
|
|
76
|
+
y1: string;
|
|
77
|
+
y2: string;
|
|
78
|
+
y3: string;
|
|
79
|
+
y4: string;
|
|
80
|
+
hi: string;
|
|
81
|
+
}>, symbol>, symbol>;
|
|
82
|
+
export declare const lightShadow: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
83
|
+
popover: string;
|
|
84
|
+
raised: string;
|
|
85
|
+
}>, symbol>, symbol>;
|
|
86
|
+
export declare const darkColor: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
27
87
|
bg: string;
|
|
28
88
|
surface: string;
|
|
29
89
|
surfaceRaised: string;
|
|
@@ -41,9 +101,226 @@ export declare const dark: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
|
41
101
|
successSubtle: string;
|
|
42
102
|
warning: string;
|
|
43
103
|
warningSubtle: string;
|
|
104
|
+
info: string;
|
|
105
|
+
infoSubtle: string;
|
|
44
106
|
focusRing: string;
|
|
45
107
|
bone: string;
|
|
46
108
|
sheen: string;
|
|
47
109
|
successHl: string;
|
|
48
110
|
dangerHl: string;
|
|
49
111
|
}>, symbol>, symbol>;
|
|
112
|
+
export declare const darkYarn: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
113
|
+
un: string;
|
|
114
|
+
sh: string;
|
|
115
|
+
y0: string;
|
|
116
|
+
y1: string;
|
|
117
|
+
y2: string;
|
|
118
|
+
y3: string;
|
|
119
|
+
y4: string;
|
|
120
|
+
hi: string;
|
|
121
|
+
shadow: string;
|
|
122
|
+
}>, symbol>, symbol>;
|
|
123
|
+
export declare const darkYarnSecondary: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
124
|
+
un: string;
|
|
125
|
+
sh: string;
|
|
126
|
+
y0: string;
|
|
127
|
+
y1: string;
|
|
128
|
+
y2: string;
|
|
129
|
+
y3: string;
|
|
130
|
+
y4: string;
|
|
131
|
+
hi: string;
|
|
132
|
+
shadow: string;
|
|
133
|
+
}>, symbol>, symbol>;
|
|
134
|
+
export declare const darkYarnGhost: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
135
|
+
un: string;
|
|
136
|
+
sh: string;
|
|
137
|
+
y0: string;
|
|
138
|
+
y1: string;
|
|
139
|
+
y2: string;
|
|
140
|
+
y3: string;
|
|
141
|
+
y4: string;
|
|
142
|
+
hi: string;
|
|
143
|
+
shadow: string;
|
|
144
|
+
}>, symbol>, symbol>;
|
|
145
|
+
export declare const darkYarnDanger: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
146
|
+
un: string;
|
|
147
|
+
sh: string;
|
|
148
|
+
y0: string;
|
|
149
|
+
y1: string;
|
|
150
|
+
y2: string;
|
|
151
|
+
y3: string;
|
|
152
|
+
y4: string;
|
|
153
|
+
hi: string;
|
|
154
|
+
shadow: string;
|
|
155
|
+
}>, symbol>, symbol>;
|
|
156
|
+
export declare const darkYarnSubtle: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
157
|
+
un: string;
|
|
158
|
+
sh: string;
|
|
159
|
+
y0: string;
|
|
160
|
+
y1: string;
|
|
161
|
+
y2: string;
|
|
162
|
+
y3: string;
|
|
163
|
+
y4: string;
|
|
164
|
+
hi: string;
|
|
165
|
+
}>, symbol>, symbol>;
|
|
166
|
+
export declare const darkShadow: stylex.Theme<stylex.VarGroup<Readonly<{
|
|
167
|
+
popover: string;
|
|
168
|
+
raised: string;
|
|
169
|
+
}>, symbol>, symbol>;
|
|
170
|
+
/** 套在 root element 上:`<div {...stylex.props(...light)}>` */
|
|
171
|
+
export declare const light: readonly [stylex.Theme<stylex.VarGroup<Readonly<{
|
|
172
|
+
bg: string;
|
|
173
|
+
surface: string;
|
|
174
|
+
surfaceRaised: string;
|
|
175
|
+
border: string;
|
|
176
|
+
borderStrong: string;
|
|
177
|
+
text: string;
|
|
178
|
+
textMuted: string;
|
|
179
|
+
textFaint: string;
|
|
180
|
+
accent: string;
|
|
181
|
+
accentText: string;
|
|
182
|
+
accentSubtle: string;
|
|
183
|
+
danger: string;
|
|
184
|
+
dangerSubtle: string;
|
|
185
|
+
success: string;
|
|
186
|
+
successSubtle: string;
|
|
187
|
+
warning: string;
|
|
188
|
+
warningSubtle: string;
|
|
189
|
+
info: string;
|
|
190
|
+
infoSubtle: string;
|
|
191
|
+
focusRing: string;
|
|
192
|
+
bone: string;
|
|
193
|
+
sheen: string;
|
|
194
|
+
successHl: string;
|
|
195
|
+
dangerHl: string;
|
|
196
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
197
|
+
un: string;
|
|
198
|
+
sh: string;
|
|
199
|
+
y0: string;
|
|
200
|
+
y1: string;
|
|
201
|
+
y2: string;
|
|
202
|
+
y3: string;
|
|
203
|
+
y4: string;
|
|
204
|
+
hi: string;
|
|
205
|
+
shadow: string;
|
|
206
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
207
|
+
un: string;
|
|
208
|
+
sh: string;
|
|
209
|
+
y0: string;
|
|
210
|
+
y1: string;
|
|
211
|
+
y2: string;
|
|
212
|
+
y3: string;
|
|
213
|
+
y4: string;
|
|
214
|
+
hi: string;
|
|
215
|
+
shadow: string;
|
|
216
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
217
|
+
un: string;
|
|
218
|
+
sh: string;
|
|
219
|
+
y0: string;
|
|
220
|
+
y1: string;
|
|
221
|
+
y2: string;
|
|
222
|
+
y3: string;
|
|
223
|
+
y4: string;
|
|
224
|
+
hi: string;
|
|
225
|
+
shadow: string;
|
|
226
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
227
|
+
un: string;
|
|
228
|
+
sh: string;
|
|
229
|
+
y0: string;
|
|
230
|
+
y1: string;
|
|
231
|
+
y2: string;
|
|
232
|
+
y3: string;
|
|
233
|
+
y4: string;
|
|
234
|
+
hi: string;
|
|
235
|
+
shadow: string;
|
|
236
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
237
|
+
un: string;
|
|
238
|
+
sh: string;
|
|
239
|
+
y0: string;
|
|
240
|
+
y1: string;
|
|
241
|
+
y2: string;
|
|
242
|
+
y3: string;
|
|
243
|
+
y4: string;
|
|
244
|
+
hi: string;
|
|
245
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
246
|
+
popover: string;
|
|
247
|
+
raised: string;
|
|
248
|
+
}>, symbol>, symbol>];
|
|
249
|
+
export declare const dark: readonly [stylex.Theme<stylex.VarGroup<Readonly<{
|
|
250
|
+
bg: string;
|
|
251
|
+
surface: string;
|
|
252
|
+
surfaceRaised: string;
|
|
253
|
+
border: string;
|
|
254
|
+
borderStrong: string;
|
|
255
|
+
text: string;
|
|
256
|
+
textMuted: string;
|
|
257
|
+
textFaint: string;
|
|
258
|
+
accent: string;
|
|
259
|
+
accentText: string;
|
|
260
|
+
accentSubtle: string;
|
|
261
|
+
danger: string;
|
|
262
|
+
dangerSubtle: string;
|
|
263
|
+
success: string;
|
|
264
|
+
successSubtle: string;
|
|
265
|
+
warning: string;
|
|
266
|
+
warningSubtle: string;
|
|
267
|
+
info: string;
|
|
268
|
+
infoSubtle: string;
|
|
269
|
+
focusRing: string;
|
|
270
|
+
bone: string;
|
|
271
|
+
sheen: string;
|
|
272
|
+
successHl: string;
|
|
273
|
+
dangerHl: string;
|
|
274
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
275
|
+
un: string;
|
|
276
|
+
sh: string;
|
|
277
|
+
y0: string;
|
|
278
|
+
y1: string;
|
|
279
|
+
y2: string;
|
|
280
|
+
y3: string;
|
|
281
|
+
y4: string;
|
|
282
|
+
hi: string;
|
|
283
|
+
shadow: string;
|
|
284
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
285
|
+
un: string;
|
|
286
|
+
sh: string;
|
|
287
|
+
y0: string;
|
|
288
|
+
y1: string;
|
|
289
|
+
y2: string;
|
|
290
|
+
y3: string;
|
|
291
|
+
y4: string;
|
|
292
|
+
hi: string;
|
|
293
|
+
shadow: string;
|
|
294
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
295
|
+
un: string;
|
|
296
|
+
sh: string;
|
|
297
|
+
y0: string;
|
|
298
|
+
y1: string;
|
|
299
|
+
y2: string;
|
|
300
|
+
y3: string;
|
|
301
|
+
y4: string;
|
|
302
|
+
hi: string;
|
|
303
|
+
shadow: string;
|
|
304
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
305
|
+
un: string;
|
|
306
|
+
sh: string;
|
|
307
|
+
y0: string;
|
|
308
|
+
y1: string;
|
|
309
|
+
y2: string;
|
|
310
|
+
y3: string;
|
|
311
|
+
y4: string;
|
|
312
|
+
hi: string;
|
|
313
|
+
shadow: string;
|
|
314
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
315
|
+
un: string;
|
|
316
|
+
sh: string;
|
|
317
|
+
y0: string;
|
|
318
|
+
y1: string;
|
|
319
|
+
y2: string;
|
|
320
|
+
y3: string;
|
|
321
|
+
y4: string;
|
|
322
|
+
hi: string;
|
|
323
|
+
}>, symbol>, symbol>, stylex.Theme<stylex.VarGroup<Readonly<{
|
|
324
|
+
popover: string;
|
|
325
|
+
raised: string;
|
|
326
|
+
}>, symbol>, symbol>];
|
package/dist/themes.stylex.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
// 這個檔案由 scripts/themes.mjs 從 tokens.stylex.ts 生成 —— 不要手改。
|
|
2
|
+
// 重生成:pnpm gen:themes(themes.test.ts 會擋住不同步)
|
|
3
|
+
//
|
|
4
|
+
// 給有使用者切換主題的 app(例如 next-themes)。tokens 本身跟隨 OS,套上 theme 才會鎖定。
|
|
5
|
+
// **要套就整組套**:只套 color 會讓布停在另一個主題,深色布配深色字。
|
|
1
6
|
import * as stylex from "@stylexjs/stylex";
|
|
2
|
-
import { color } from "./tokens.stylex.js";
|
|
3
|
-
|
|
4
|
-
// Apply on the root element: <div {...stylex.props(dark)}>.
|
|
5
|
-
export const light = stylex.createTheme(color, {
|
|
7
|
+
import { color, yarn, yarnSecondary, yarnGhost, yarnDanger, yarnSubtle, shadow } from "./tokens.stylex.js";
|
|
8
|
+
export const lightColor = stylex.createTheme(color, {
|
|
6
9
|
bg: "#FAFAF6",
|
|
7
10
|
surface: "#FFFFFF",
|
|
8
11
|
surfaceRaised: "#FFFFFF",
|
|
9
12
|
border: "#E3E0D5",
|
|
10
13
|
borderStrong: "#C8C3B4",
|
|
11
14
|
text: "#23211D",
|
|
12
|
-
textMuted: "#
|
|
15
|
+
textMuted: "#635D52",
|
|
13
16
|
textFaint: "#9C958A",
|
|
14
17
|
accent: "#23705A",
|
|
15
18
|
accentText: "#FCFCF9",
|
|
@@ -20,20 +23,80 @@ export const light = stylex.createTheme(color, {
|
|
|
20
23
|
successSubtle: "#E7F0EB",
|
|
21
24
|
warning: "#9A6A1B",
|
|
22
25
|
warningSubtle: "#F5EBD9",
|
|
26
|
+
info: "#2C5C86",
|
|
27
|
+
infoSubtle: "#E4EDF5",
|
|
23
28
|
focusRing: "#23705A",
|
|
24
29
|
bone: "#ECE9DF",
|
|
25
30
|
sheen: "#F6F4EC",
|
|
26
31
|
successHl: "#C6E0C6",
|
|
27
32
|
dangerHl: "#EFCEC3",
|
|
28
33
|
});
|
|
29
|
-
export const
|
|
34
|
+
export const lightYarn = stylex.createTheme(yarn, {
|
|
35
|
+
un: "#11362C",
|
|
36
|
+
sh: "#123C31",
|
|
37
|
+
y0: "#1E6250",
|
|
38
|
+
y1: "#216A55",
|
|
39
|
+
y2: "#23705A",
|
|
40
|
+
y3: "#28795F",
|
|
41
|
+
y4: "#2E8266",
|
|
42
|
+
hi: "#5CAA89",
|
|
43
|
+
shadow: "drop-shadow(0 1px 1.5px rgba(18, 60, 49, 0.3))",
|
|
44
|
+
});
|
|
45
|
+
export const lightYarnSecondary = stylex.createTheme(yarnSecondary, {
|
|
46
|
+
un: "#CBC5B4",
|
|
47
|
+
sh: "#C9C4B4",
|
|
48
|
+
y0: "#E4E0D3",
|
|
49
|
+
y1: "#E8E5D9",
|
|
50
|
+
y2: "#EDEAE0",
|
|
51
|
+
y3: "#F1EEE6",
|
|
52
|
+
y4: "#F5F3EC",
|
|
53
|
+
hi: "#FFFFFF",
|
|
54
|
+
shadow: "drop-shadow(0 1px 1.5px rgba(80, 74, 60, 0.22))",
|
|
55
|
+
});
|
|
56
|
+
export const lightYarnGhost = stylex.createTheme(yarnGhost, {
|
|
57
|
+
un: "transparent",
|
|
58
|
+
sh: "transparent",
|
|
59
|
+
y0: "#DCD8CA",
|
|
60
|
+
y1: "#DFDBCE",
|
|
61
|
+
y2: "#E3E0D5",
|
|
62
|
+
y3: "#E7E4D9",
|
|
63
|
+
y4: "#EBE8DE",
|
|
64
|
+
hi: "#C8C3B4",
|
|
65
|
+
shadow: "none",
|
|
66
|
+
});
|
|
67
|
+
export const lightYarnDanger = stylex.createTheme(yarnDanger, {
|
|
68
|
+
un: "#401209",
|
|
69
|
+
sh: "#4A170D",
|
|
70
|
+
y0: "#8F3122",
|
|
71
|
+
y1: "#A13928",
|
|
72
|
+
y2: "#B3402E",
|
|
73
|
+
y3: "#BC4F3C",
|
|
74
|
+
y4: "#C55E4A",
|
|
75
|
+
hi: "#E39781",
|
|
76
|
+
shadow: "drop-shadow(0 1px 1.5px rgba(74, 23, 13, 0.3))",
|
|
77
|
+
});
|
|
78
|
+
export const lightYarnSubtle = stylex.createTheme(yarnSubtle, {
|
|
79
|
+
un: "#CFE2D9",
|
|
80
|
+
sh: "#CBDFD5",
|
|
81
|
+
y0: "#DFEBE5",
|
|
82
|
+
y1: "#E3EEE8",
|
|
83
|
+
y2: "#E7F0EB",
|
|
84
|
+
y3: "#ECF3EF",
|
|
85
|
+
y4: "#F1F7F3",
|
|
86
|
+
hi: "#FFFFFF",
|
|
87
|
+
});
|
|
88
|
+
export const lightShadow = stylex.createTheme(shadow, {
|
|
89
|
+
popover: "0 8px 24px rgba(35, 33, 29, 0.1)",
|
|
90
|
+
raised: "0 1px 2px rgba(35, 33, 29, 0.08)",
|
|
91
|
+
});
|
|
92
|
+
export const darkColor = stylex.createTheme(color, {
|
|
30
93
|
bg: "#181613",
|
|
31
94
|
surface: "#201D18",
|
|
32
95
|
surfaceRaised: "#282420",
|
|
33
96
|
border: "#35302A",
|
|
34
97
|
borderStrong: "#4A443C",
|
|
35
98
|
text: "#EAE6DC",
|
|
36
|
-
textMuted: "#
|
|
99
|
+
textMuted: "#B0A697",
|
|
37
100
|
textFaint: "#736A5D",
|
|
38
101
|
accent: "#4FA184",
|
|
39
102
|
accentText: "#14120F",
|
|
@@ -44,9 +107,88 @@ export const dark = stylex.createTheme(color, {
|
|
|
44
107
|
successSubtle: "#22352E",
|
|
45
108
|
warning: "#D9A254",
|
|
46
109
|
warningSubtle: "#3A2F1D",
|
|
110
|
+
info: "#6FA3CE",
|
|
111
|
+
infoSubtle: "#1E2C38",
|
|
47
112
|
focusRing: "#4FA184",
|
|
48
113
|
bone: "#2A2620",
|
|
49
114
|
sheen: "#35302A",
|
|
50
115
|
successHl: "#2F4A2E",
|
|
51
116
|
dangerHl: "#573328",
|
|
52
117
|
});
|
|
118
|
+
export const darkYarn = stylex.createTheme(yarn, {
|
|
119
|
+
un: "#173629",
|
|
120
|
+
sh: "#1B4437",
|
|
121
|
+
y0: "#3F8A70",
|
|
122
|
+
y1: "#47957A",
|
|
123
|
+
y2: "#4FA184",
|
|
124
|
+
y3: "#56A98B",
|
|
125
|
+
y4: "#5EB193",
|
|
126
|
+
hi: "#8FD2B4",
|
|
127
|
+
shadow: "drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45))",
|
|
128
|
+
});
|
|
129
|
+
export const darkYarnSecondary = stylex.createTheme(yarnSecondary, {
|
|
130
|
+
un: "#0E0C09",
|
|
131
|
+
sh: "#15120E",
|
|
132
|
+
y0: "#2B2620",
|
|
133
|
+
y1: "#2F2A23",
|
|
134
|
+
y2: "#332E26",
|
|
135
|
+
y3: "#38322A",
|
|
136
|
+
y4: "#3D372E",
|
|
137
|
+
hi: "#5E5546",
|
|
138
|
+
shadow: "drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5))",
|
|
139
|
+
});
|
|
140
|
+
export const darkYarnGhost = stylex.createTheme(yarnGhost, {
|
|
141
|
+
un: "transparent",
|
|
142
|
+
sh: "transparent",
|
|
143
|
+
y0: "#2A251F",
|
|
144
|
+
y1: "#2F2A23",
|
|
145
|
+
y2: "#35302A",
|
|
146
|
+
y3: "#39342D",
|
|
147
|
+
y4: "#3E3830",
|
|
148
|
+
hi: "#57503F",
|
|
149
|
+
shadow: "none",
|
|
150
|
+
});
|
|
151
|
+
export const darkYarnDanger = stylex.createTheme(yarnDanger, {
|
|
152
|
+
un: "#38130B",
|
|
153
|
+
sh: "#451A10",
|
|
154
|
+
y0: "#C25842",
|
|
155
|
+
y1: "#D0644E",
|
|
156
|
+
y2: "#DD7059",
|
|
157
|
+
y3: "#E17E68",
|
|
158
|
+
y4: "#E58C77",
|
|
159
|
+
hi: "#F4BCA9",
|
|
160
|
+
shadow: "drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45))",
|
|
161
|
+
});
|
|
162
|
+
export const darkYarnSubtle = stylex.createTheme(yarnSubtle, {
|
|
163
|
+
un: "#141F1B",
|
|
164
|
+
sh: "#17231E",
|
|
165
|
+
y0: "#1D2E27",
|
|
166
|
+
y1: "#20312B",
|
|
167
|
+
y2: "#22352E",
|
|
168
|
+
y3: "#263A32",
|
|
169
|
+
y4: "#2A4038",
|
|
170
|
+
hi: "#3E5F50",
|
|
171
|
+
});
|
|
172
|
+
export const darkShadow = stylex.createTheme(shadow, {
|
|
173
|
+
popover: "0 8px 24px rgba(0, 0, 0, 0.4)",
|
|
174
|
+
raised: "0 1px 2px rgba(0, 0, 0, 0.3)",
|
|
175
|
+
});
|
|
176
|
+
/** 套在 root element 上:`<div {...stylex.props(...light)}>` */
|
|
177
|
+
export const light = [
|
|
178
|
+
lightColor,
|
|
179
|
+
lightYarn,
|
|
180
|
+
lightYarnSecondary,
|
|
181
|
+
lightYarnGhost,
|
|
182
|
+
lightYarnDanger,
|
|
183
|
+
lightYarnSubtle,
|
|
184
|
+
lightShadow,
|
|
185
|
+
];
|
|
186
|
+
export const dark = [
|
|
187
|
+
darkColor,
|
|
188
|
+
darkYarn,
|
|
189
|
+
darkYarnSecondary,
|
|
190
|
+
darkYarnGhost,
|
|
191
|
+
darkYarnDanger,
|
|
192
|
+
darkYarnSubtle,
|
|
193
|
+
darkShadow,
|
|
194
|
+
];
|
package/dist/tokens.css
CHANGED
|
@@ -14,7 +14,7 @@ html {
|
|
|
14
14
|
--ak-border: #e3e0d5;
|
|
15
15
|
--ak-border-strong: #c8c3b4;
|
|
16
16
|
--ak-text: #23211d;
|
|
17
|
-
--ak-text-muted: #
|
|
17
|
+
--ak-text-muted: #635d52;
|
|
18
18
|
--ak-text-faint: #9c958a;
|
|
19
19
|
--ak-accent: #23705a;
|
|
20
20
|
--ak-accent-text: #fcfcf9;
|
|
@@ -25,6 +25,8 @@ html {
|
|
|
25
25
|
--ak-success-subtle: #e7f0eb;
|
|
26
26
|
--ak-warning: #9a6a1b;
|
|
27
27
|
--ak-warning-subtle: #f5ebd9;
|
|
28
|
+
--ak-info: #2c5c86;
|
|
29
|
+
--ak-info-subtle: #e4edf5;
|
|
28
30
|
--ak-focus-ring: #23705a;
|
|
29
31
|
--ak-bone: #ece9df;
|
|
30
32
|
--ak-sheen: #f6f4ec;
|
|
@@ -48,6 +50,7 @@ html {
|
|
|
48
50
|
--ak-motion-slow: 400ms;
|
|
49
51
|
--ak-motion-ease: cubic-bezier(0.25, 0.1, 0.25, 1);
|
|
50
52
|
--ak-motion-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
|
|
53
|
+
/* 過衝曲線:全站規則是「動畫不回彈」,沒有元件在用,新的也不要用 */
|
|
51
54
|
--ak-motion-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
52
55
|
}
|
|
53
56
|
|
|
@@ -59,7 +62,7 @@ html {
|
|
|
59
62
|
--ak-border: #35302a;
|
|
60
63
|
--ak-border-strong: #4a443c;
|
|
61
64
|
--ak-text: #eae6dc;
|
|
62
|
-
--ak-text-muted: #
|
|
65
|
+
--ak-text-muted: #b0a697;
|
|
63
66
|
--ak-text-faint: #736a5d;
|
|
64
67
|
--ak-accent: #4fa184;
|
|
65
68
|
--ak-accent-text: #14120f;
|
|
@@ -70,6 +73,8 @@ html {
|
|
|
70
73
|
--ak-success-subtle: #22352e;
|
|
71
74
|
--ak-warning: #d9a254;
|
|
72
75
|
--ak-warning-subtle: #3a2f1d;
|
|
76
|
+
--ak-info: #6fa3ce;
|
|
77
|
+
--ak-info-subtle: #1e2c38;
|
|
73
78
|
--ak-focus-ring: #4fa184;
|
|
74
79
|
--ak-bone: #2a2620;
|
|
75
80
|
--ak-sheen: #35302a;
|
|
@@ -94,7 +99,7 @@ html {
|
|
|
94
99
|
--ak-border: #35302a;
|
|
95
100
|
--ak-border-strong: #4a443c;
|
|
96
101
|
--ak-text: #eae6dc;
|
|
97
|
-
--ak-text-muted: #
|
|
102
|
+
--ak-text-muted: #b0a697;
|
|
98
103
|
--ak-text-faint: #736a5d;
|
|
99
104
|
--ak-accent: #4fa184;
|
|
100
105
|
--ak-accent-text: #14120f;
|
|
@@ -105,5 +110,7 @@ html {
|
|
|
105
110
|
--ak-success-subtle: #22352e;
|
|
106
111
|
--ak-warning: #d9a254;
|
|
107
112
|
--ak-warning-subtle: #3a2f1d;
|
|
113
|
+
--ak-info: #6fa3ce;
|
|
114
|
+
--ak-info-subtle: #1e2c38;
|
|
108
115
|
--ak-focus-ring: #4fa184;
|
|
109
116
|
}
|
package/dist/tokens.stylex.d.ts
CHANGED
package/dist/tokens.stylex.js
CHANGED
|
@@ -10,7 +10,7 @@ export const color = stylex.defineVars({
|
|
|
10
10
|
border: { default: "#E3E0D5", [DARK]: "#35302A" },
|
|
11
11
|
borderStrong: { default: "#C8C3B4", [DARK]: "#4A443C" },
|
|
12
12
|
text: { default: "#23211D", [DARK]: "#EAE6DC" },
|
|
13
|
-
textMuted: { default: "#
|
|
13
|
+
textMuted: { default: "#635D52", [DARK]: "#B0A697" },
|
|
14
14
|
textFaint: { default: "#9C958A", [DARK]: "#736A5D" },
|
|
15
15
|
accent: { default: "#23705A", [DARK]: "#4FA184" },
|
|
16
16
|
accentText: { default: "#FCFCF9", [DARK]: "#14120F" },
|
|
@@ -21,6 +21,8 @@ export const color = stylex.defineVars({
|
|
|
21
21
|
successSubtle: { default: "#E7F0EB", [DARK]: "#22352E" },
|
|
22
22
|
warning: { default: "#9A6A1B", [DARK]: "#D9A254" },
|
|
23
23
|
warningSubtle: { default: "#F5EBD9", [DARK]: "#3A2F1D" },
|
|
24
|
+
info: { default: "#2C5C86", [DARK]: "#6FA3CE" },
|
|
25
|
+
infoSubtle: { default: "#E4EDF5", [DARK]: "#1E2C38" },
|
|
24
26
|
focusRing: { default: "#23705A", [DARK]: "#4FA184" },
|
|
25
27
|
bone: { default: "#ECE9DF", [DARK]: "#2A2620" },
|
|
26
28
|
sheen: { default: "#F6F4EC", [DARK]: "#35302A" },
|
|
@@ -145,5 +147,7 @@ export const motion = stylex.defineVars({
|
|
|
145
147
|
slow: "400ms",
|
|
146
148
|
ease: "cubic-bezier(0.25, 0.1, 0.25, 1)",
|
|
147
149
|
easeOut: "cubic-bezier(0.16, 1, 0.3, 1)",
|
|
150
|
+
// 過衝曲線。全站規則是「動畫不回彈」,所以這條目前沒有任何元件在用 ——
|
|
151
|
+
// 新元件不要挑它,滑動類一律 240ms easeOut。保留只是因為它已經在發佈的 API 裡。
|
|
148
152
|
spring: "cubic-bezier(0.34, 1.56, 0.64, 1)",
|
|
149
153
|
});
|
package/package.json
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anyknown/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "AnyKnown design system — StyleX tokens, themes, and 34 components",
|
|
5
|
+
"homepage": "https://ui.anyknown.com",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/anyknown-com/ui/issues"
|
|
8
|
+
},
|
|
5
9
|
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/anyknown-com/ui.git"
|
|
13
|
+
},
|
|
6
14
|
"files": [
|
|
7
15
|
"dist",
|
|
8
16
|
"LICENSE"
|
|
@@ -34,12 +42,13 @@
|
|
|
34
42
|
"lint": "oxlint src",
|
|
35
43
|
"fmt": "oxfmt",
|
|
36
44
|
"fmt:check": "oxfmt --check",
|
|
45
|
+
"gen:themes": "node -e \"import('./scripts/themes.mjs').then(async m => (await import('node:fs')).writeFileSync('src/themes.stylex.ts', m.generate()))\" && oxfmt src/themes.stylex.ts",
|
|
37
46
|
"check": "turbo run typecheck lint fmt:check",
|
|
38
47
|
"test": "vitest run",
|
|
39
48
|
"playground": "vite --config playground/vite.config.ts",
|
|
40
49
|
"site": "vite --config site/vite.config.ts",
|
|
41
50
|
"site:test": "vitest run --config site/smoke.config.ts",
|
|
42
|
-
"site:build": "pnpm build && vite build --config site/vite.config.ts",
|
|
51
|
+
"site:build": "pnpm build && vite build --config site/vite.config.ts && node scripts/llms-txt.mjs",
|
|
43
52
|
"site:deploy": "pnpm site:build && npx wrangler deploy --config site/wrangler.jsonc",
|
|
44
53
|
"prepublishOnly": "pnpm check && pnpm test && pnpm verify:pack",
|
|
45
54
|
"verify:pack": "pnpm build && node scripts/verify-pack.mjs"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/lib/format.test.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { formatBytes, formatDuration } from "./format.js";
|
|
3
|
-
describe("formatBytes", () => {
|
|
4
|
-
test("formats each unit", () => {
|
|
5
|
-
expect(formatBytes(512)).toBe("512 B");
|
|
6
|
-
expect(formatBytes(2400)).toBe("2.3 KB");
|
|
7
|
-
expect(formatBytes(2_400_000)).toBe("2.3 MB");
|
|
8
|
-
expect(formatBytes(40_000_000)).toBe("38 MB");
|
|
9
|
-
});
|
|
10
|
-
test("picks the unit after rounding, not before", () => {
|
|
11
|
-
expect(formatBytes(1_048_575)).toBe("1.0 MB");
|
|
12
|
-
expect(formatBytes(1_073_741_823)).toBe("1.0 GB");
|
|
13
|
-
});
|
|
14
|
-
test("survives degenerate input", () => {
|
|
15
|
-
expect(formatBytes(0)).toBe("0 B");
|
|
16
|
-
expect(formatBytes(0.5)).toBe("1 B");
|
|
17
|
-
expect(formatBytes(-1)).toBe("0 B");
|
|
18
|
-
expect(formatBytes(Number.NaN)).toBe("0 B");
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
describe("formatDuration", () => {
|
|
22
|
-
test("formats milliseconds, seconds and minutes", () => {
|
|
23
|
-
expect(formatDuration(300)).toBe("300ms");
|
|
24
|
-
expect(formatDuration(8100)).toBe("8.1s");
|
|
25
|
-
expect(formatDuration(125_000)).toBe("2m 5s");
|
|
26
|
-
});
|
|
27
|
-
test("never puts 60 in the seconds slot", () => {
|
|
28
|
-
expect(formatDuration(119_500)).toBe("2m 0s");
|
|
29
|
-
expect(formatDuration(3_599_999)).toBe("60m 0s");
|
|
30
|
-
expect(formatDuration(59_950)).toBe("1m 0s");
|
|
31
|
-
});
|
|
32
|
-
test("survives degenerate input", () => {
|
|
33
|
-
expect(formatDuration(0)).toBe("0ms");
|
|
34
|
-
expect(formatDuration(-1)).toBe("0ms");
|
|
35
|
-
expect(formatDuration(Number.NaN)).toBe("0ms");
|
|
36
|
-
});
|
|
37
|
-
});
|