kaze-design-system 0.4.2 → 0.6.1
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 +95 -32
- package/components.css +73 -34
- package/dist/components/Alert/Alert.js +7 -16
- package/dist/components/Badge/Badge.js +1 -6
- package/dist/components/BarChart/BarChart.js +19 -15
- package/dist/components/BarList/BarList.js +2 -16
- package/dist/components/Card/Card.js +5 -3
- package/dist/components/Checkbox/Checkbox.js +1 -10
- package/dist/components/CommandPalette/CommandPalette.js +3 -9
- package/dist/components/DescriptionList/DescriptionList.js +11 -14
- package/dist/components/Dialog/Dialog.js +1 -10
- package/dist/components/Disclosure/Disclosure.js +18 -7
- package/dist/components/DonutChart/DonutChart.js +54 -50
- package/dist/components/Dropdown/Dropdown.js +2 -16
- package/dist/components/FAQ/FAQ.js +36 -46
- package/dist/components/FeatureGrid/FeatureGrid.js +1 -5
- package/dist/components/FilterPill/FilterPill.js +1 -5
- package/dist/components/FormField/FormField.js +2 -15
- package/dist/components/Grid/Grid.js +1 -9
- package/dist/components/HelpButton/HelpButton.js +1 -9
- package/dist/components/LPFooter/LPFooter.js +1 -10
- package/dist/components/List/List.js +2 -15
- package/dist/components/Logo/Logo.js +1 -10
- package/dist/components/Meter/Meter.js +1 -4
- package/dist/components/Metric/Metric.js +2 -17
- package/dist/components/Navbar/Navbar.js +2 -10
- package/dist/components/NumberField/NumberField.js +30 -7
- package/dist/components/Pagination/Pagination.js +37 -46
- package/dist/components/Pricing/Pricing.js +2 -17
- package/dist/components/Progress/Progress.js +3 -18
- package/dist/components/Radio/Radio.js +2 -14
- package/dist/components/Search/Search.js +10 -1
- package/dist/components/Section/Section.js +4 -12
- package/dist/components/Sidebar/Sidebar.js +7 -31
- package/dist/components/SplitSection/SplitSection.js +1 -5
- package/dist/components/StatusBadge/StatusBadge.js +1 -11
- package/dist/components/Stepper/Stepper.js +29 -27
- package/dist/components/Table/Table.js +5 -3
- package/dist/components/Tabs/Tabs.js +29 -36
- package/dist/components/Testimonial/Testimonial.js +19 -23
- package/dist/components/Text/Text.js +1 -11
- package/dist/components/Toast/Toast.js +103 -97
- package/dist/components/Tooltip/Tooltip.js +89 -92
- package/dist/components/TopBar/TopBar.js +4 -12
- package/dist/hooks/useLegendToggle.js +1 -4
- package/dist/hooks/useTheme.js +1 -4
- package/dist/marketing.js +33 -0
- package/dist/tokens.js +12 -0
- package/dist/types/components/Alert/Alert.d.ts +1 -1
- package/dist/types/components/Badge/Badge.d.ts +1 -1
- package/dist/types/components/Dialog/Dialog.d.ts +1 -1
- package/dist/types/components/Dropdown/Dropdown.d.ts +2 -3
- package/dist/types/components/Grid/Grid.d.ts +4 -4
- package/dist/types/components/Hero/Hero.d.ts +2 -2
- package/dist/types/components/Icon/Icon.d.ts +10 -5
- package/dist/types/components/Icon/index.d.ts +1 -1
- package/dist/types/components/NumberField/NumberField.d.ts +1 -1
- package/dist/types/components/Sidebar/index.d.ts +1 -1
- package/dist/types/components/Tabs/Tabs.d.ts +1 -1
- package/dist/types/components/Toast/Toast.d.ts +2 -2
- package/dist/types/components/index.d.ts +2 -2
- package/dist/types/components/marketing.d.ts +22 -0
- package/dist/types/hooks/useTheme.d.ts +1 -1
- package/dist/types/lib/utils.d.ts +1 -1
- package/dist/types/tokens/tokens.d.ts +13 -0
- package/package.json +23 -10
- package/tokens.css +72 -2
- package/utilities.css +5 -0
package/README.md
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
**Kaze (風)** は、管理画面・ダッシュボード・金融系アプリのための React デザインシステムです。**白と温かみのあるグレーを基調にした静かな配色**と、日本語組版への丁寧な最適化(PALT・和欧混植・読みやすい行間)、そしてコピペで完結する 63 のコンポーネントを 1 パッケージにまとめています。派手な色や装飾ではなく「読みやすさ」「情報密度」「長時間見続けても疲れないこと」を設計の中心に置いています。
|
|
7
7
|
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
8
|
+
- **63 コンポーネント**: フォーム、テーブル、チャート、ダッシュボード UI、ランディングページ、マーケティングパーツまで
|
|
9
|
+
- **日本語組版に最適化**: PALT グローバル適用、和欧混植、括弧ツメ、適切な line-height
|
|
10
|
+
- **ライト / ダーク両対応**: `data-theme` 属性で切替、`prefers-color-scheme` 連動
|
|
11
|
+
- **素の CSS + カスケードレイヤー**: `@layer tokens, reset, components, utilities` でカスケード管理、Tailwind/CSS-in-JS 不要
|
|
12
|
+
- **ESM only + Tree-shakeable**: React 18 / 19 + TypeScript、peer deps は `react`, `react-dom`(`lucide-react` は任意)のみ
|
|
13
|
+
- **AI フレンドリー**: [`/llms.txt`](https://kaze-design-system.vercel.app/llms.txt) で全コンポーネント API を 1 ファイル配信
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Links
|
|
16
16
|
|
|
17
17
|
| | |
|
|
18
18
|
|---|---|
|
|
@@ -22,32 +22,32 @@
|
|
|
22
22
|
| **npm パッケージ** | https://www.npmjs.com/package/kaze-design-system |
|
|
23
23
|
| **GitHub** | https://github.com/yuki930/kaze-design-system |
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## Live Examples
|
|
26
26
|
|
|
27
27
|
実際のアプリケーション/ページ単位のサンプル実装。Vercel にデプロイされています:
|
|
28
28
|
|
|
29
29
|
### ダッシュボード / 管理画面
|
|
30
|
-
- [**分析ダッシュボード**](https://kaze-design-system.vercel.app/dashboard)
|
|
31
|
-
- [**Analytics**](https://kaze-design-system.vercel.app/analytics)
|
|
32
|
-
- [**SaaS Stats**](https://kaze-design-system.vercel.app/saas-stats)
|
|
33
|
-
- [**EC ダッシュボード**](https://kaze-design-system.vercel.app/ec-dashboard)
|
|
34
|
-
- [**設定画面**](https://kaze-design-system.vercel.app/settings)
|
|
30
|
+
- [**分析ダッシュボード**](https://kaze-design-system.vercel.app/dashboard): メトリック、チャート、テーブル組み合わせ
|
|
31
|
+
- [**Analytics**](https://kaze-design-system.vercel.app/analytics): KPI 一覧、BarList、Tracker
|
|
32
|
+
- [**SaaS Stats**](https://kaze-design-system.vercel.app/saas-stats): SaaS 系ダッシュボード
|
|
33
|
+
- [**EC ダッシュボード**](https://kaze-design-system.vercel.app/ec-dashboard): EC 管理画面
|
|
34
|
+
- [**設定画面**](https://kaze-design-system.vercel.app/settings): フォーム・FormField 活用例
|
|
35
35
|
|
|
36
36
|
### ランディング・マーケティング
|
|
37
|
-
- [**LP (SaaS)**](https://kaze-design-system.vercel.app/lp)
|
|
38
|
-
- [**LP 2**](https://kaze-design-system.vercel.app/lp2)
|
|
39
|
-
- [**Pricing**](https://kaze-design-system.vercel.app/pricing)
|
|
40
|
-
- [**Blog**](https://kaze-design-system.vercel.app/blog)
|
|
41
|
-
- [**Jobs**](https://kaze-design-system.vercel.app/jobs)
|
|
37
|
+
- [**LP (SaaS)**](https://kaze-design-system.vercel.app/lp): Hero, Features, Pricing, Testimonial, FAQ, CTA
|
|
38
|
+
- [**LP 2**](https://kaze-design-system.vercel.app/lp2): 異なる雰囲気の LP
|
|
39
|
+
- [**Pricing**](https://kaze-design-system.vercel.app/pricing): 料金プラン
|
|
40
|
+
- [**Blog**](https://kaze-design-system.vercel.app/blog): 記事一覧・記事詳細
|
|
41
|
+
- [**Jobs**](https://kaze-design-system.vercel.app/jobs): 求人ページ
|
|
42
42
|
|
|
43
43
|
### アプリケーション
|
|
44
|
-
- [**Login**](https://kaze-design-system.vercel.app/login)
|
|
45
|
-
- [**Todo**](https://kaze-design-system.vercel.app/todo)
|
|
46
|
-
- [**Shopping**](https://kaze-design-system.vercel.app/shopping)
|
|
47
|
-
- [**Article**](https://kaze-design-system.vercel.app/article)
|
|
48
|
-
- [**Help**](https://kaze-design-system.vercel.app/help)
|
|
44
|
+
- [**Login**](https://kaze-design-system.vercel.app/login): 認証画面
|
|
45
|
+
- [**Todo**](https://kaze-design-system.vercel.app/todo): シンプルな Todo アプリ
|
|
46
|
+
- [**Shopping**](https://kaze-design-system.vercel.app/shopping): EC 商品一覧
|
|
47
|
+
- [**Article**](https://kaze-design-system.vercel.app/article): 記事ページ
|
|
48
|
+
- [**Help**](https://kaze-design-system.vercel.app/help): ヘルプセンター
|
|
49
49
|
|
|
50
|
-
> **ESM only
|
|
50
|
+
> **ESM only**: このパッケージは ES Modules のみを提供します。
|
|
51
51
|
> `"type": "module"` が設定された環境、または ESM 対応バンドラー(Vite, Next.js, webpack 5+)で使用してください。
|
|
52
52
|
|
|
53
53
|
## For AI assistants (Claude / Cursor / ChatGPT)
|
|
@@ -57,7 +57,7 @@ AI コーディングアシスタントは以下のファイルからライブ
|
|
|
57
57
|
- **Short index**: https://kaze-design-system.vercel.app/llms.txt
|
|
58
58
|
- **Full API reference**: https://kaze-design-system.vercel.app/llms-full.txt
|
|
59
59
|
|
|
60
|
-
`llms-full.txt` には
|
|
60
|
+
`llms-full.txt` には 63 コンポーネントの `Props` / `Usage` / カテゴリが機械可読形式で含まれており、Storybook を参照しなくても正確なコード提案が可能です。[llmstxt.org](https://llmstxt.org) 準拠。
|
|
61
61
|
|
|
62
62
|
## インストール
|
|
63
63
|
|
|
@@ -65,7 +65,7 @@ AI コーディングアシスタントは以下のファイルからライブ
|
|
|
65
65
|
npm install kaze-design-system
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
Peer dependencies: `react@^19`, `react-dom@^19
|
|
68
|
+
Peer dependencies: `react@^18 || ^19`, `react-dom@^18 || ^19`。`lucide-react` は任意(`Icon` に lucide のアイコンを渡す場合やサンプルコードで使用。コンポーネント本体は lucide なしで動きます)
|
|
69
69
|
|
|
70
70
|
## CSS の読み込み
|
|
71
71
|
|
|
@@ -117,8 +117,26 @@ function App() {
|
|
|
117
117
|
}
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
+
## レイヤー構成
|
|
121
|
+
|
|
122
|
+
kaze は1パッケージ・3レイヤーで構成されています。
|
|
123
|
+
|
|
124
|
+
- **Foundation**: デザイントークン(カラー・タイポグラフィ・スペーシング)と CSS。両レイヤー共通の土台
|
|
125
|
+
- **Application UI**: 管理画面・アプリ向けの52コンポーネント。`kaze-design-system` から import
|
|
126
|
+
- **Marketing**: LP・キャンペーンページ向けの11コンポーネント。`kaze-design-system/marketing` から import
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
// Application UI
|
|
130
|
+
import { Table, Sidebar, CommandPalette } from "kaze-design-system";
|
|
131
|
+
|
|
132
|
+
// Marketing(ルートからの import も引き続き使えます)
|
|
133
|
+
import { Hero, PricingGrid, CTABanner } from "kaze-design-system/marketing";
|
|
134
|
+
```
|
|
135
|
+
|
|
120
136
|
## コンポーネント一覧(63 コンポーネント)
|
|
121
137
|
|
|
138
|
+
### Application UI(52)
|
|
139
|
+
|
|
122
140
|
| カテゴリ | コンポーネント |
|
|
123
141
|
|---|---|
|
|
124
142
|
| **フォーム** | Button, FAB, Input, NumberField, Select, Checkbox, Radio, Textarea, Switch, FormField, FilterPill |
|
|
@@ -129,6 +147,11 @@ function App() {
|
|
|
129
147
|
| **オーバーレイ** | Dialog, Tooltip, HelpButton, Dropdown, CommandPalette |
|
|
130
148
|
| **レイアウト** | AppLayout, Divider, Grid, Search, Logo, Icon, Heading, Text |
|
|
131
149
|
| **リスト** | List, DescriptionList, Timeline |
|
|
150
|
+
|
|
151
|
+
### Marketing(11)
|
|
152
|
+
|
|
153
|
+
| カテゴリ | コンポーネント |
|
|
154
|
+
|---|---|
|
|
132
155
|
| **マーケティング** | Navbar, Hero, Section, SplitSection, FeatureGrid, Stats, Pricing, Testimonial, FAQ, CTABanner, LPFooter |
|
|
133
156
|
|
|
134
157
|
詳細は [kaze-design-system.vercel.app/docs/components](https://kaze-design-system.vercel.app/docs/components) を参照してください。
|
|
@@ -136,13 +159,30 @@ function App() {
|
|
|
136
159
|
## Hooks
|
|
137
160
|
|
|
138
161
|
```tsx
|
|
139
|
-
import { ThemeProvider, useTheme
|
|
140
|
-
import { useLegendToggle } from "kaze-design-system/hooks";
|
|
162
|
+
import { ThemeProvider, useTheme } from "kaze-design-system";
|
|
163
|
+
import { useFocusTrap, useLegendToggle } from "kaze-design-system/hooks";
|
|
141
164
|
```
|
|
142
165
|
|
|
143
|
-
- `useTheme
|
|
144
|
-
- `useFocusTrap
|
|
145
|
-
- `useLegendToggle
|
|
166
|
+
- `useTheme`: ライト/ダークの切り替え
|
|
167
|
+
- `useFocusTrap`: モーダル向けフォーカストラップ
|
|
168
|
+
- `useLegendToggle`: Recharts の凡例クリックで系列 show/hide を切り替え
|
|
169
|
+
|
|
170
|
+
## バンドルサイズ
|
|
171
|
+
|
|
172
|
+
63 コンポーネント全部込みで **JS 38 kB gzip + CSS 23 kB gzip ≒ 61 kB gz**。ただし、個別 import すれば使った分だけが bundle に入ります。
|
|
173
|
+
|
|
174
|
+
| 区分 | 生サイズ | gzip |
|
|
175
|
+
|---|---:|---:|
|
|
176
|
+
| JS: 全コンポーネント合計 (tree-shake 対象) | 110 kB | **38 kB** |
|
|
177
|
+
| JS: 最大 (CommandPalette) | 6.4 kB | 1.9 kB |
|
|
178
|
+
| JS: 中央値 (StatusBadge) | 896 B | 476 B |
|
|
179
|
+
| JS: 最小 (Textarea) | 481 B | 280 B |
|
|
180
|
+
| CSS: `tokens.css` | 20.1 kB | 4.9 kB |
|
|
181
|
+
| CSS: `components.css` | 101 kB | 13.6 kB |
|
|
182
|
+
| CSS: `utilities.css` | 18.9 kB | 3.4 kB |
|
|
183
|
+
| CSS: `reset.css` | 3.7 kB | 1.1 kB |
|
|
184
|
+
|
|
185
|
+
`npm run size` でローカルで最新のサイズを計測できます。React / lucide-react 等の peer dependencies は含まれていません。
|
|
146
186
|
|
|
147
187
|
## デザイントークン
|
|
148
188
|
|
|
@@ -153,12 +193,33 @@ CSS カスタムプロパティベース:
|
|
|
153
193
|
- タイポグラフィ: `--font-size-*`, `--font-weight-*`
|
|
154
194
|
- ボーダー: `--radius-*`
|
|
155
195
|
- シャドウ: `--shadow-*`
|
|
196
|
+
- 密度: `--density-*`(コントロール高さ・行パディング・UI フォントサイズ。下記「密度」参照)
|
|
197
|
+
|
|
198
|
+
JS から値を参照したい場合は `kaze-design-system/tokens` から import できます。
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
import { space } from "kaze-design-system/tokens";
|
|
202
|
+
```
|
|
156
203
|
|
|
157
204
|
## テーマ(ライト / ダーク)
|
|
158
205
|
|
|
159
206
|
`data-theme="light"` / `data-theme="dark"` で切り替え。
|
|
160
207
|
`ThemeProvider` で自動管理。`prefers-color-scheme` による OS 設定連動にも対応。
|
|
161
208
|
|
|
209
|
+
`data-palette="cool"` を付けると warm zinc から cool slate のパレットに切り替わります(ライト / ダークどちらとも併用可)。
|
|
210
|
+
|
|
211
|
+
## 密度(Density)
|
|
212
|
+
|
|
213
|
+
`data-density="compact"` を祖先要素(`<html>` やパネル単位)に付けると、Input / Select / Table / List / Tabs / Dropdown / Sidebar などが詰まった表示になります。テーマ・パレットとは独立に組み合わせられます。
|
|
214
|
+
|
|
215
|
+
```html
|
|
216
|
+
<html data-theme="dark" data-density="compact">
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## CSS のレイヤーについて
|
|
220
|
+
|
|
221
|
+
`css/all`(`kaze.css`)は `@layer tokens, reset, components, utilities` でラップされています。`css/components` などを個別に読み込むとレイヤーは付きません。また、レイヤー外のスタイル(CSS Modules など)は常にレイヤー内のスタイルより優先されます。
|
|
222
|
+
|
|
162
223
|
## 開発
|
|
163
224
|
|
|
164
225
|
```bash
|
|
@@ -168,11 +229,13 @@ npm run build:lib # ライブラリビルド(dist/ に出力)
|
|
|
168
229
|
npm run docs:llms # llms.txt / llms-full.txt を再生成
|
|
169
230
|
npm run storybook # Storybook 起動
|
|
170
231
|
npm run typecheck # TypeScript 型チェック
|
|
232
|
+
npm run test # ユニットテスト(jsdom)
|
|
233
|
+
npm run test:storybook # Storybook ブラウザテスト(Playwright)
|
|
171
234
|
```
|
|
172
235
|
|
|
173
236
|
### リリース
|
|
174
237
|
|
|
175
|
-
main への push 時に GitHub Actions
|
|
238
|
+
main への push 時に GitHub Actions が Conventional Commits からバージョン(patch / minor / major)を判定し、build → `npm publish` → release コミットとタグの push を実行します。ライブラリ本体(`src/components/**`, `src/hooks/**`, CSS ファイル、`package.json` 等)への変更がある場合のみトリガーされます。詳しくは [CONTRIBUTING.md](./CONTRIBUTING.md) を参照してください。
|
|
176
239
|
|
|
177
240
|
## コントリビュート
|
|
178
241
|
|
package/components.css
CHANGED
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
.btn--md {
|
|
68
|
-
height:
|
|
68
|
+
height: var(--density-control-height);
|
|
69
69
|
padding-inline: var(--space-4);
|
|
70
|
-
font-size: var(--font-size-
|
|
70
|
+
font-size: var(--density-font-size-ui);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
.btn--lg {
|
|
@@ -290,9 +290,9 @@
|
|
|
290
290
|
.input {
|
|
291
291
|
display: flex;
|
|
292
292
|
width: 100%;
|
|
293
|
-
height:
|
|
293
|
+
height: var(--density-control-height);
|
|
294
294
|
padding-inline: var(--space-3);
|
|
295
|
-
font-size: var(--font-size-
|
|
295
|
+
font-size: var(--density-font-size-ui);
|
|
296
296
|
background-color: var(--color-bg-tertiary);
|
|
297
297
|
border: 1px solid transparent;
|
|
298
298
|
border-radius: var(--radius-field);
|
|
@@ -322,10 +322,10 @@
|
|
|
322
322
|
.select {
|
|
323
323
|
display: flex;
|
|
324
324
|
width: 100%;
|
|
325
|
-
height:
|
|
325
|
+
height: var(--density-control-height);
|
|
326
326
|
padding-inline: var(--space-3);
|
|
327
327
|
padding-right: var(--space-8);
|
|
328
|
-
font-size: var(--font-size-
|
|
328
|
+
font-size: var(--density-font-size-ui);
|
|
329
329
|
background-color: var(--color-bg-tertiary);
|
|
330
330
|
border: 1px solid transparent;
|
|
331
331
|
border-radius: var(--radius-field);
|
|
@@ -348,6 +348,11 @@
|
|
|
348
348
|
[data-theme="dark"] .select {
|
|
349
349
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a8a29e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
350
350
|
}
|
|
351
|
+
@media (prefers-color-scheme: dark) {
|
|
352
|
+
:root:not([data-theme="light"]) .select {
|
|
353
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a8a29e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
354
|
+
}
|
|
355
|
+
}
|
|
351
356
|
|
|
352
357
|
/* ── Textarea ────────────────────────────────────────────── */
|
|
353
358
|
.textarea {
|
|
@@ -355,7 +360,7 @@
|
|
|
355
360
|
width: 100%;
|
|
356
361
|
min-height: 5rem;
|
|
357
362
|
padding: var(--space-2) var(--space-3);
|
|
358
|
-
font-size: var(--font-size-
|
|
363
|
+
font-size: var(--density-font-size-ui);
|
|
359
364
|
line-height: var(--line-height-relaxed);
|
|
360
365
|
background-color: var(--color-bg-tertiary);
|
|
361
366
|
border: 1px solid transparent;
|
|
@@ -453,10 +458,20 @@
|
|
|
453
458
|
[data-theme="dark"] .checkbox__input:checked {
|
|
454
459
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23000000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
|
|
455
460
|
}
|
|
461
|
+
@media (prefers-color-scheme: dark) {
|
|
462
|
+
:root:not([data-theme="light"]) .checkbox__input:checked {
|
|
463
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23000000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
|
|
464
|
+
}
|
|
465
|
+
}
|
|
456
466
|
|
|
457
467
|
[data-theme="dark"] .checkbox__input:indeterminate {
|
|
458
468
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23000000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3C/svg%3E");
|
|
459
469
|
}
|
|
470
|
+
@media (prefers-color-scheme: dark) {
|
|
471
|
+
:root:not([data-theme="light"]) .checkbox__input:indeterminate {
|
|
472
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23000000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3C/svg%3E");
|
|
473
|
+
}
|
|
474
|
+
}
|
|
460
475
|
|
|
461
476
|
/* ── Radio ───────────────────────────────────────────────── */
|
|
462
477
|
.radio {
|
|
@@ -611,7 +626,8 @@
|
|
|
611
626
|
|
|
612
627
|
.table {
|
|
613
628
|
width: 100%;
|
|
614
|
-
font-size: var(--font-size-
|
|
629
|
+
font-size: var(--density-font-size-ui);
|
|
630
|
+
line-height: var(--density-line-height-ui);
|
|
615
631
|
}
|
|
616
632
|
|
|
617
633
|
.table th {
|
|
@@ -621,12 +637,12 @@
|
|
|
621
637
|
text-transform: uppercase;
|
|
622
638
|
letter-spacing: var(--letter-spacing-wider);
|
|
623
639
|
color: var(--color-fg-tertiary);
|
|
624
|
-
padding: var(--
|
|
640
|
+
padding: var(--density-row-py) var(--density-row-px);
|
|
625
641
|
border-bottom: 1px solid var(--color-border);
|
|
626
642
|
}
|
|
627
643
|
|
|
628
644
|
.table td {
|
|
629
|
-
padding: var(--
|
|
645
|
+
padding: var(--density-row-py) var(--density-row-px);
|
|
630
646
|
border-bottom: 1px solid var(--color-border-subtle);
|
|
631
647
|
color: var(--color-fg);
|
|
632
648
|
vertical-align: middle;
|
|
@@ -685,6 +701,11 @@
|
|
|
685
701
|
[data-theme="dark"] .avatar img {
|
|
686
702
|
filter: brightness(0.85) contrast(1.1);
|
|
687
703
|
}
|
|
704
|
+
@media (prefers-color-scheme: dark) {
|
|
705
|
+
:root:not([data-theme="light"]) .avatar img {
|
|
706
|
+
filter: brightness(0.85) contrast(1.1);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
688
709
|
|
|
689
710
|
/* ── Tabs ────────────────────────────────────────────────── */
|
|
690
711
|
.tabs {
|
|
@@ -697,8 +718,8 @@
|
|
|
697
718
|
display: inline-flex;
|
|
698
719
|
align-items: center;
|
|
699
720
|
justify-content: center;
|
|
700
|
-
padding: var(--
|
|
701
|
-
font-size: var(--font-size-
|
|
721
|
+
padding: var(--density-tab-py) var(--space-3);
|
|
722
|
+
font-size: var(--density-font-size-ui);
|
|
702
723
|
font-weight: var(--font-weight-normal);
|
|
703
724
|
color: var(--color-fg-tertiary);
|
|
704
725
|
cursor: pointer;
|
|
@@ -750,9 +771,9 @@
|
|
|
750
771
|
.nav-item {
|
|
751
772
|
display: flex;
|
|
752
773
|
align-items: center;
|
|
753
|
-
gap: var(--
|
|
754
|
-
padding: var(--
|
|
755
|
-
font-size: var(--font-size-
|
|
774
|
+
gap: var(--density-nav-gap);
|
|
775
|
+
padding: var(--density-nav-py) var(--space-3);
|
|
776
|
+
font-size: var(--density-font-size-ui);
|
|
756
777
|
font-weight: var(--font-weight-medium);
|
|
757
778
|
color: var(--color-fg-tertiary);
|
|
758
779
|
border-radius: var(--radius-md);
|
|
@@ -1398,12 +1419,7 @@
|
|
|
1398
1419
|
.feature-card__icon {
|
|
1399
1420
|
display: inline-flex;
|
|
1400
1421
|
align-items: center;
|
|
1401
|
-
|
|
1402
|
-
width: 2.5rem;
|
|
1403
|
-
height: 2.5rem;
|
|
1404
|
-
border-radius: var(--radius-lg);
|
|
1405
|
-
background: var(--color-bg-tertiary);
|
|
1406
|
-
color: var(--color-fg);
|
|
1422
|
+
color: var(--color-fg-secondary);
|
|
1407
1423
|
margin-bottom: var(--space-4);
|
|
1408
1424
|
}
|
|
1409
1425
|
|
|
@@ -2266,14 +2282,19 @@
|
|
|
2266
2282
|
|
|
2267
2283
|
/* ── Prose: mark ───────────────────────────────────────────── */
|
|
2268
2284
|
.prose mark {
|
|
2269
|
-
background: var(--
|
|
2285
|
+
background: var(--amber-100);
|
|
2270
2286
|
color: inherit;
|
|
2271
2287
|
padding: var(--space-0-5) var(--space-1);
|
|
2272
2288
|
border-radius: var(--radius-sm);
|
|
2273
2289
|
}
|
|
2274
2290
|
|
|
2275
2291
|
[data-theme="dark"] .prose mark {
|
|
2276
|
-
background: var(--
|
|
2292
|
+
background: var(--amber-900);
|
|
2293
|
+
}
|
|
2294
|
+
@media (prefers-color-scheme: dark) {
|
|
2295
|
+
:root:not([data-theme="light"]) .prose mark {
|
|
2296
|
+
background: var(--amber-900);
|
|
2297
|
+
}
|
|
2277
2298
|
}
|
|
2278
2299
|
|
|
2279
2300
|
/* ── Prose: kbd ────────────────────────────────────────────── */
|
|
@@ -2593,8 +2614,9 @@
|
|
|
2593
2614
|
display: flex;
|
|
2594
2615
|
align-items: center;
|
|
2595
2616
|
gap: var(--space-3);
|
|
2596
|
-
padding: var(--
|
|
2597
|
-
font-size: var(--font-size-
|
|
2617
|
+
padding: var(--density-row-py) 0;
|
|
2618
|
+
font-size: var(--density-font-size-ui);
|
|
2619
|
+
line-height: var(--density-line-height-ui);
|
|
2598
2620
|
color: var(--color-fg);
|
|
2599
2621
|
}
|
|
2600
2622
|
|
|
@@ -2634,7 +2656,7 @@
|
|
|
2634
2656
|
.list-item--interactive {
|
|
2635
2657
|
cursor: pointer;
|
|
2636
2658
|
border-radius: var(--radius-md);
|
|
2637
|
-
padding: var(--
|
|
2659
|
+
padding: var(--density-row-py) var(--space-3);
|
|
2638
2660
|
transition: background var(--duration-fast) var(--ease-default);
|
|
2639
2661
|
}
|
|
2640
2662
|
|
|
@@ -3204,6 +3226,13 @@
|
|
|
3204
3226
|
line-height: var(--line-height-relaxed);
|
|
3205
3227
|
}
|
|
3206
3228
|
|
|
3229
|
+
.alert--default {
|
|
3230
|
+
background: var(--color-surface);
|
|
3231
|
+
border-color: var(--color-border);
|
|
3232
|
+
}
|
|
3233
|
+
|
|
3234
|
+
.alert--default .alert__icon { color: var(--color-fg-secondary); }
|
|
3235
|
+
|
|
3207
3236
|
.alert--info {
|
|
3208
3237
|
background: var(--color-info-light);
|
|
3209
3238
|
border-color: var(--color-info);
|
|
@@ -3552,6 +3581,7 @@
|
|
|
3552
3581
|
align-items: center;
|
|
3553
3582
|
border: 1px solid var(--color-border);
|
|
3554
3583
|
border-radius: var(--radius-md);
|
|
3584
|
+
height: var(--density-control-height);
|
|
3555
3585
|
background: var(--color-surface);
|
|
3556
3586
|
transition: border-color var(--duration-normal) var(--ease-default),
|
|
3557
3587
|
box-shadow var(--duration-normal) var(--ease-default);
|
|
@@ -3576,11 +3606,12 @@
|
|
|
3576
3606
|
min-width: 0;
|
|
3577
3607
|
border: none;
|
|
3578
3608
|
background: transparent;
|
|
3609
|
+
height: 100%;
|
|
3579
3610
|
font-family: var(--font-mono);
|
|
3580
|
-
font-size: var(--font-size-
|
|
3611
|
+
font-size: var(--density-font-size-ui);
|
|
3581
3612
|
font-variant-numeric: tabular-nums;
|
|
3582
3613
|
color: var(--color-fg);
|
|
3583
|
-
padding:
|
|
3614
|
+
padding: 0 var(--space-2);
|
|
3584
3615
|
text-align: right;
|
|
3585
3616
|
outline: none;
|
|
3586
3617
|
}
|
|
@@ -3607,7 +3638,7 @@
|
|
|
3607
3638
|
align-items: center;
|
|
3608
3639
|
justify-content: center;
|
|
3609
3640
|
width: 32px;
|
|
3610
|
-
height:
|
|
3641
|
+
height: 100%;
|
|
3611
3642
|
border: none;
|
|
3612
3643
|
background: var(--color-bg-secondary);
|
|
3613
3644
|
color: var(--color-fg-secondary);
|
|
@@ -3880,6 +3911,14 @@
|
|
|
3880
3911
|
color: var(--color-warning);
|
|
3881
3912
|
}
|
|
3882
3913
|
|
|
3914
|
+
.toast--info {
|
|
3915
|
+
border-left: 3px solid var(--color-info);
|
|
3916
|
+
}
|
|
3917
|
+
|
|
3918
|
+
.toast--info .toast__icon {
|
|
3919
|
+
color: var(--color-info);
|
|
3920
|
+
}
|
|
3921
|
+
|
|
3883
3922
|
/* ── Dropdown ───────────────────────────────────────────── */
|
|
3884
3923
|
|
|
3885
3924
|
.dropdown__menu {
|
|
@@ -3902,8 +3941,8 @@
|
|
|
3902
3941
|
display: flex;
|
|
3903
3942
|
align-items: center;
|
|
3904
3943
|
gap: var(--space-2);
|
|
3905
|
-
padding: var(--
|
|
3906
|
-
font-size: var(--font-size-
|
|
3944
|
+
padding: var(--density-dropdown-py) var(--space-3);
|
|
3945
|
+
font-size: var(--density-font-size-ui);
|
|
3907
3946
|
border-radius: var(--radius-md);
|
|
3908
3947
|
cursor: pointer;
|
|
3909
3948
|
color: var(--color-fg);
|
|
@@ -4016,8 +4055,8 @@
|
|
|
4016
4055
|
.help-button:hover,
|
|
4017
4056
|
.help-button[aria-expanded="true"] {
|
|
4018
4057
|
color: var(--color-fg);
|
|
4019
|
-
border-color: var(--color-border-strong
|
|
4020
|
-
background: var(--color-
|
|
4058
|
+
border-color: var(--color-border-strong);
|
|
4059
|
+
background: var(--color-surface-hover);
|
|
4021
4060
|
}
|
|
4022
4061
|
|
|
4023
4062
|
.help-button:focus-visible {
|
|
@@ -4118,7 +4157,7 @@
|
|
|
4118
4157
|
}
|
|
4119
4158
|
|
|
4120
4159
|
.disclosure__trigger:hover:not(:disabled) {
|
|
4121
|
-
background: var(--color-
|
|
4160
|
+
background: var(--color-surface-hover);
|
|
4122
4161
|
}
|
|
4123
4162
|
|
|
4124
4163
|
.disclosure__trigger:focus-visible {
|
|
@@ -2,22 +2,13 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { cn } from "../../lib/utils.js";
|
|
4
4
|
const Alert = forwardRef(
|
|
5
|
-
({ variant = "info", icon, title, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(
|
|
6
|
-
"
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
children: [
|
|
13
|
-
icon && /* @__PURE__ */ jsx("span", { className: "alert__icon", children: icon }),
|
|
14
|
-
/* @__PURE__ */ jsxs("div", { className: "alert__content", children: [
|
|
15
|
-
title && /* @__PURE__ */ jsx("p", { className: "alert__title", children: title }),
|
|
16
|
-
/* @__PURE__ */ jsx("div", { className: "alert__description", children })
|
|
17
|
-
] })
|
|
18
|
-
]
|
|
19
|
-
}
|
|
20
|
-
)
|
|
5
|
+
({ variant = "info", icon, title, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs("div", { ref, role: "alert", className: cn("alert", `alert--${variant}`, className), ...rest, children: [
|
|
6
|
+
icon && /* @__PURE__ */ jsx("span", { className: "alert__icon", children: icon }),
|
|
7
|
+
/* @__PURE__ */ jsxs("div", { className: "alert__content", children: [
|
|
8
|
+
title && /* @__PURE__ */ jsx("p", { className: "alert__title", children: title }),
|
|
9
|
+
/* @__PURE__ */ jsx("div", { className: "alert__description", children })
|
|
10
|
+
] })
|
|
11
|
+
] })
|
|
21
12
|
);
|
|
22
13
|
Alert.displayName = "Alert";
|
|
23
14
|
export {
|
|
@@ -8,12 +8,7 @@ const Badge = forwardRef(
|
|
|
8
8
|
{
|
|
9
9
|
ref,
|
|
10
10
|
...live ? { role: "status" } : {},
|
|
11
|
-
className: cn(
|
|
12
|
-
"badge",
|
|
13
|
-
`badge--${variant}`,
|
|
14
|
-
solid && "badge--solid",
|
|
15
|
-
className
|
|
16
|
-
),
|
|
11
|
+
className: cn("badge", `badge--${variant}`, solid && "badge--solid", className),
|
|
17
12
|
...rest,
|
|
18
13
|
children: [
|
|
19
14
|
dot && /* @__PURE__ */ jsx("span", { className: "badge__dot", "aria-hidden": "true" }),
|
|
@@ -6,21 +6,25 @@ const BarChart = forwardRef(
|
|
|
6
6
|
({ data, max, formatValue, "aria-label": ariaLabel, className, ...rest }, ref) => {
|
|
7
7
|
const maxVal = max ?? Math.max(...data.map((d) => d.value));
|
|
8
8
|
const fmt = formatValue ?? ((v) => String(v));
|
|
9
|
-
return /* @__PURE__ */ jsx(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
return /* @__PURE__ */ jsx(
|
|
10
|
+
"div",
|
|
11
|
+
{
|
|
12
|
+
ref,
|
|
13
|
+
role: "img",
|
|
14
|
+
"aria-label": ariaLabel,
|
|
15
|
+
className: cn("bar-chart", className),
|
|
16
|
+
...rest,
|
|
17
|
+
children: data.map((item, i) => {
|
|
18
|
+
const pct = maxVal > 0 ? item.value / maxVal * 100 : 0;
|
|
19
|
+
const color = item.color ?? CHART_COLORS[i % CHART_COLORS.length];
|
|
20
|
+
return /* @__PURE__ */ jsxs("div", { className: "bar-chart__item", children: [
|
|
21
|
+
/* @__PURE__ */ jsx("span", { className: "bar-chart__label", children: item.label }),
|
|
22
|
+
/* @__PURE__ */ jsx("span", { className: "bar-chart__track", children: /* @__PURE__ */ jsx("span", { className: "bar-chart__fill", style: { width: `${pct}%`, background: color } }) }),
|
|
23
|
+
/* @__PURE__ */ jsx("span", { className: "bar-chart__value", children: fmt(item.value) })
|
|
24
|
+
] }, item.label);
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
);
|
|
24
28
|
}
|
|
25
29
|
);
|
|
26
30
|
BarChart.displayName = "BarChart";
|
|
@@ -2,13 +2,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { cn } from "../../lib/utils.js";
|
|
4
4
|
const BarList = forwardRef(
|
|
5
|
-
({
|
|
6
|
-
data,
|
|
7
|
-
sortOrder = "descending",
|
|
8
|
-
valueFormatter,
|
|
9
|
-
className,
|
|
10
|
-
...rest
|
|
11
|
-
}, ref) => {
|
|
5
|
+
({ data, sortOrder = "descending", valueFormatter, className, ...rest }, ref) => {
|
|
12
6
|
const sorted = sortOrder === "none" ? data : [...data].sort(
|
|
13
7
|
(a, b) => sortOrder === "ascending" ? a.value - b.value : b.value - a.value
|
|
14
8
|
);
|
|
@@ -33,15 +27,7 @@ const BarList = forwardRef(
|
|
|
33
27
|
/* @__PURE__ */ jsx("span", { className: "barlist__value", children: display })
|
|
34
28
|
] });
|
|
35
29
|
const LinkComponent = item.as ?? "a";
|
|
36
|
-
return item.href ? /* @__PURE__ */ jsx(
|
|
37
|
-
LinkComponent,
|
|
38
|
-
{
|
|
39
|
-
href: item.href,
|
|
40
|
-
className: "barlist__row barlist__row--link",
|
|
41
|
-
children: content
|
|
42
|
-
},
|
|
43
|
-
i
|
|
44
|
-
) : /* @__PURE__ */ jsx("div", { className: "barlist__row", children: content }, i);
|
|
30
|
+
return item.href ? /* @__PURE__ */ jsx(LinkComponent, { href: item.href, className: "barlist__row barlist__row--link", children: content }, i) : /* @__PURE__ */ jsx("div", { className: "barlist__row", children: content }, i);
|
|
45
31
|
}) });
|
|
46
32
|
}
|
|
47
33
|
);
|
|
@@ -33,9 +33,11 @@ const CardTitle = forwardRef(
|
|
|
33
33
|
}
|
|
34
34
|
);
|
|
35
35
|
CardTitle.displayName = "CardTitle";
|
|
36
|
-
const CardDescription = forwardRef(
|
|
37
|
-
|
|
38
|
-
});
|
|
36
|
+
const CardDescription = forwardRef(
|
|
37
|
+
({ className, children, ...rest }, ref) => {
|
|
38
|
+
return /* @__PURE__ */ jsx("p", { ref, className: cn("card__description", className), ...rest, children });
|
|
39
|
+
}
|
|
40
|
+
);
|
|
39
41
|
CardDescription.displayName = "CardDescription";
|
|
40
42
|
const CardBody = forwardRef(
|
|
41
43
|
({ className, children, ...rest }, ref) => {
|
|
@@ -6,16 +6,7 @@ const Checkbox = forwardRef(
|
|
|
6
6
|
const generatedId = useId();
|
|
7
7
|
const id = idProp ?? generatedId;
|
|
8
8
|
return /* @__PURE__ */ jsxs("label", { htmlFor: id, className: cn("checkbox", className), children: [
|
|
9
|
-
/* @__PURE__ */ jsx(
|
|
10
|
-
"input",
|
|
11
|
-
{
|
|
12
|
-
ref,
|
|
13
|
-
id,
|
|
14
|
-
type: "checkbox",
|
|
15
|
-
className: "checkbox__input",
|
|
16
|
-
...rest
|
|
17
|
-
}
|
|
18
|
-
),
|
|
9
|
+
/* @__PURE__ */ jsx("input", { ref, id, type: "checkbox", className: "checkbox__input", ...rest }),
|
|
19
10
|
label && /* @__PURE__ */ jsx("span", { children: label })
|
|
20
11
|
] });
|
|
21
12
|
}
|