kaze-design-system 0.4.2 → 0.6.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 +95 -32
- package/components.css +73 -34
- package/dist/components/Disclosure/Disclosure.js +17 -3
- package/dist/components/Dropdown/Dropdown.js +0 -5
- package/dist/components/Toast/Toast.js +19 -0
- 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/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/Tabs/Tabs.d.ts +1 -1
- package/dist/types/components/Toast/Toast.d.ts +1 -1
- package/dist/types/components/index.d.ts +1 -1
- package/dist/types/components/marketing.d.ts +22 -0
- package/dist/types/tokens/tokens.d.ts +13 -0
- package/package.json +18 -9
- 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 {
|
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
3
|
import { forwardRef, useState, useCallback, useId, useMemo } from "react";
|
|
4
|
-
import { ChevronRight, Plus } from "lucide-react";
|
|
5
4
|
import { cn } from "../../lib/utils.js";
|
|
5
|
+
const iconSvgProps = {
|
|
6
|
+
width: 16,
|
|
7
|
+
height: 16,
|
|
8
|
+
viewBox: "0 0 24 24",
|
|
9
|
+
fill: "none",
|
|
10
|
+
stroke: "currentColor",
|
|
11
|
+
strokeWidth: 2,
|
|
12
|
+
strokeLinecap: "round",
|
|
13
|
+
strokeLinejoin: "round",
|
|
14
|
+
className: "disclosure__icon-svg",
|
|
15
|
+
"aria-hidden": true
|
|
16
|
+
};
|
|
6
17
|
function renderIcon(icon) {
|
|
7
18
|
if (icon === "chevron" || icon == null) {
|
|
8
|
-
return /* @__PURE__ */ jsx(
|
|
19
|
+
return /* @__PURE__ */ jsx("svg", { ...iconSvgProps, children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) });
|
|
9
20
|
}
|
|
10
21
|
if (icon === "plus") {
|
|
11
|
-
return /* @__PURE__ */
|
|
22
|
+
return /* @__PURE__ */ jsxs("svg", { ...iconSvgProps, children: [
|
|
23
|
+
/* @__PURE__ */ jsx("path", { d: "M5 12h14" }),
|
|
24
|
+
/* @__PURE__ */ jsx("path", { d: "M12 5v14" })
|
|
25
|
+
] });
|
|
12
26
|
}
|
|
13
27
|
return icon;
|
|
14
28
|
}
|
|
@@ -33,9 +33,6 @@ const Dropdown = forwardRef(
|
|
|
33
33
|
},
|
|
34
34
|
[isControlled, onOpenChange]
|
|
35
35
|
);
|
|
36
|
-
const registerItem = useCallback(() => {
|
|
37
|
-
return itemCountRef.current++;
|
|
38
|
-
}, []);
|
|
39
36
|
const resetItems = useCallback(() => {
|
|
40
37
|
itemCountRef.current = 0;
|
|
41
38
|
}, []);
|
|
@@ -48,8 +45,6 @@ const Dropdown = forwardRef(
|
|
|
48
45
|
triggerRef,
|
|
49
46
|
highlightedIndex,
|
|
50
47
|
setHighlightedIndex,
|
|
51
|
-
itemCount: itemCountRef.current,
|
|
52
|
-
registerItem,
|
|
53
48
|
resetItems
|
|
54
49
|
},
|
|
55
50
|
children: /* @__PURE__ */ jsx("div", { ref, style: { display: "contents" }, children })
|
|
@@ -92,6 +92,25 @@ function ToastItem(props) {
|
|
|
92
92
|
/* @__PURE__ */ jsx("path", { d: "M12 17h.01" })
|
|
93
93
|
]
|
|
94
94
|
}
|
|
95
|
+
),
|
|
96
|
+
data.variant === "info" && /* @__PURE__ */ jsxs(
|
|
97
|
+
"svg",
|
|
98
|
+
{
|
|
99
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
100
|
+
width: "16",
|
|
101
|
+
height: "16",
|
|
102
|
+
viewBox: "0 0 24 24",
|
|
103
|
+
fill: "none",
|
|
104
|
+
stroke: "currentColor",
|
|
105
|
+
strokeWidth: "2",
|
|
106
|
+
strokeLinecap: "round",
|
|
107
|
+
strokeLinejoin: "round",
|
|
108
|
+
children: [
|
|
109
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
110
|
+
/* @__PURE__ */ jsx("path", { d: "M12 16v-4" }),
|
|
111
|
+
/* @__PURE__ */ jsx("path", { d: "M12 8h.01" })
|
|
112
|
+
]
|
|
113
|
+
}
|
|
95
114
|
)
|
|
96
115
|
] }),
|
|
97
116
|
/* @__PURE__ */ jsxs("div", { className: "toast__content", children: [
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { CTABanner } from "./components/CTABanner/CTABanner.js";
|
|
3
|
+
import { FAQ, FAQItem } from "./components/FAQ/FAQ.js";
|
|
4
|
+
import { FeatureCard, FeatureGrid } from "./components/FeatureGrid/FeatureGrid.js";
|
|
5
|
+
import { Hero } from "./components/Hero/Hero.js";
|
|
6
|
+
import { LPFooter } from "./components/LPFooter/LPFooter.js";
|
|
7
|
+
import { Navbar, NavbarLink, NavbarLinks } from "./components/Navbar/Navbar.js";
|
|
8
|
+
import { PricingCard, PricingGrid } from "./components/Pricing/Pricing.js";
|
|
9
|
+
import { Section, SectionHeader } from "./components/Section/Section.js";
|
|
10
|
+
import { SplitSection } from "./components/SplitSection/SplitSection.js";
|
|
11
|
+
import { StatItem, Stats } from "./components/Stats/Stats.js";
|
|
12
|
+
import { TestimonialCard, TestimonialGrid } from "./components/Testimonial/Testimonial.js";
|
|
13
|
+
export {
|
|
14
|
+
CTABanner,
|
|
15
|
+
FAQ,
|
|
16
|
+
FAQItem,
|
|
17
|
+
FeatureCard,
|
|
18
|
+
FeatureGrid,
|
|
19
|
+
Hero,
|
|
20
|
+
LPFooter,
|
|
21
|
+
Navbar,
|
|
22
|
+
NavbarLink,
|
|
23
|
+
NavbarLinks,
|
|
24
|
+
PricingCard,
|
|
25
|
+
PricingGrid,
|
|
26
|
+
Section,
|
|
27
|
+
SectionHeader,
|
|
28
|
+
SplitSection,
|
|
29
|
+
StatItem,
|
|
30
|
+
Stats,
|
|
31
|
+
TestimonialCard,
|
|
32
|
+
TestimonialGrid
|
|
33
|
+
};
|
package/dist/tokens.js
CHANGED
|
@@ -78,9 +78,21 @@ const radius = {
|
|
|
78
78
|
"2xl": "var(--radius-2xl)",
|
|
79
79
|
full: "var(--radius-full)"
|
|
80
80
|
};
|
|
81
|
+
const density = {
|
|
82
|
+
controlHeight: "var(--density-control-height)",
|
|
83
|
+
rowPy: "var(--density-row-py)",
|
|
84
|
+
rowPx: "var(--density-row-px)",
|
|
85
|
+
fontSizeUi: "var(--density-font-size-ui)",
|
|
86
|
+
lineHeightUi: "var(--density-line-height-ui)",
|
|
87
|
+
navPy: "var(--density-nav-py)",
|
|
88
|
+
navGap: "var(--density-nav-gap)",
|
|
89
|
+
dropdownPy: "var(--density-dropdown-py)",
|
|
90
|
+
tabPy: "var(--density-tab-py)"
|
|
91
|
+
};
|
|
81
92
|
export {
|
|
82
93
|
chart,
|
|
83
94
|
color,
|
|
95
|
+
density,
|
|
84
96
|
radius,
|
|
85
97
|
space
|
|
86
98
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReactNode, type HTMLAttributes } from "react";
|
|
2
|
-
export type AlertVariant = "
|
|
2
|
+
export type AlertVariant = "default" | "positive" | "negative" | "warning" | "info";
|
|
3
3
|
export interface AlertProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
variant?: AlertVariant;
|
|
5
5
|
icon?: ReactNode;
|
|
@@ -3,7 +3,7 @@ export type BadgeVariant = "default" | "positive" | "negative" | "warning" | "in
|
|
|
3
3
|
export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
|
|
4
4
|
variant?: BadgeVariant;
|
|
5
5
|
dot?: boolean;
|
|
6
|
-
/** Solid (inverted) style
|
|
6
|
+
/** Solid (inverted) style: filled background with white text */
|
|
7
7
|
solid?: boolean;
|
|
8
8
|
/** When true, adds role="status" for live-region announcements */
|
|
9
9
|
live?: boolean;
|
|
@@ -2,7 +2,7 @@ import { type HTMLAttributes, type RefObject } from "react";
|
|
|
2
2
|
export interface DialogProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
3
|
open: boolean;
|
|
4
4
|
onClose: () => void;
|
|
5
|
-
/** @deprecated useFocusTrap handles focus restoration automatically. Kept for backward compat
|
|
5
|
+
/** @deprecated useFocusTrap handles focus restoration automatically. Kept for backward compat: ignored. */
|
|
6
6
|
returnFocusRef?: RefObject<HTMLElement | null>;
|
|
7
7
|
}
|
|
8
8
|
export declare const Dialog: import("react").ForwardRefExoticComponent<DialogProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type HTMLAttributes } from "react";
|
|
2
|
-
import { space } from "
|
|
2
|
+
import { space } from "../../tokens/tokens";
|
|
3
3
|
export type GridColumns = 1 | 2 | 3 | 4 | 5 | 6;
|
|
4
4
|
type SpaceToken = keyof typeof space;
|
|
5
5
|
export type GridGap = "xs" | "sm" | "md" | "lg" | "xl" | SpaceToken | number | (string & {});
|
|
@@ -10,11 +10,11 @@ export interface GridProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
10
10
|
columnsMd?: GridColumns;
|
|
11
11
|
/** Column count at ≤640px */
|
|
12
12
|
columnsSm?: GridColumns;
|
|
13
|
-
/** Gap between items
|
|
13
|
+
/** Gap between items: semantic token ("sm", "md", etc.), space token (e.g. 4), or any CSS value */
|
|
14
14
|
gap?: GridGap;
|
|
15
|
-
/** Gap at ≤1024px
|
|
15
|
+
/** Gap at ≤1024px: falls back to gap */
|
|
16
16
|
gapMd?: GridGap;
|
|
17
|
-
/** Gap at ≤640px
|
|
17
|
+
/** Gap at ≤640px: falls back to gapMd, then gap */
|
|
18
18
|
gapSm?: GridGap;
|
|
19
19
|
}
|
|
20
20
|
export declare const Grid: import("react").ForwardRefExoticComponent<GridProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -3,9 +3,9 @@ export interface HeroProps extends HTMLAttributes<HTMLElement> {
|
|
|
3
3
|
badge?: string;
|
|
4
4
|
title: string;
|
|
5
5
|
subtitle?: string;
|
|
6
|
-
/** Background color
|
|
6
|
+
/** Background color: any CSS value, e.g. "var(--blue-500)" */
|
|
7
7
|
bg?: string;
|
|
8
|
-
/** Background image
|
|
8
|
+
/** Background image: URL or CSS gradient, e.g. "url(...)" or "linear-gradient(...)" */
|
|
9
9
|
bgImage?: string;
|
|
10
10
|
/** Dark overlay opacity (0–1). true = 0.5. Useful for readability on images. */
|
|
11
11
|
overlay?: boolean | number;
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import { type HTMLAttributes } from "react";
|
|
2
|
-
import type { LucideIcon } from "lucide-react";
|
|
1
|
+
import { type ComponentType, type HTMLAttributes } from "react";
|
|
3
2
|
export type IconSize = "xs" | "sm" | "md" | "lg" | "xl";
|
|
3
|
+
/** Any icon component accepting `size` / `strokeWidth` (e.g. a lucide-react icon).
|
|
4
|
+
* Typed structurally so the published types don't require lucide-react. */
|
|
5
|
+
export type IconComponent = ComponentType<{
|
|
6
|
+
size?: number | string;
|
|
7
|
+
strokeWidth?: number | string;
|
|
8
|
+
}>;
|
|
4
9
|
export interface IconProps extends HTMLAttributes<HTMLSpanElement> {
|
|
5
|
-
/**
|
|
6
|
-
icon:
|
|
10
|
+
/** An icon component such as a lucide-react icon */
|
|
11
|
+
icon: IconComponent;
|
|
7
12
|
/** Size of the icon */
|
|
8
13
|
size?: IconSize;
|
|
9
|
-
/** Accessible label
|
|
14
|
+
/** Accessible label. If omitted, the icon is decorative (aria-hidden) */
|
|
10
15
|
label?: string;
|
|
11
16
|
}
|
|
12
17
|
export declare const Icon: import("react").ForwardRefExoticComponent<IconProps & import("react").RefAttributes<HTMLSpanElement>>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Icon } from "./Icon";
|
|
2
|
-
export type { IconProps, IconSize } from "./Icon";
|
|
2
|
+
export type { IconComponent, IconProps, IconSize } from "./Icon";
|
|
@@ -23,7 +23,7 @@ export interface NumberFieldProps extends Omit<InputHTMLAttributes<HTMLInputElem
|
|
|
23
23
|
error?: boolean;
|
|
24
24
|
/** Error message */
|
|
25
25
|
errorMessage?: string;
|
|
26
|
-
/** Prefix text (e.g. "¥")
|
|
26
|
+
/** Prefix text (e.g. "¥"): auto-set by currency */
|
|
27
27
|
prefix?: string;
|
|
28
28
|
/** Suffix text (e.g. "%", "件") */
|
|
29
29
|
suffix?: string;
|
|
@@ -26,7 +26,7 @@ export declare const Tabs: import("react").ForwardRefExoticComponent<TabsProps &
|
|
|
26
26
|
export interface TabProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
27
27
|
active?: boolean;
|
|
28
28
|
id?: string;
|
|
29
|
-
/** Tab の value
|
|
29
|
+
/** Tab の value。aria-controls / id の自動生成に使用 */
|
|
30
30
|
value?: string;
|
|
31
31
|
}
|
|
32
32
|
export declare const Tab: import("react").ForwardRefExoticComponent<TabProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -57,7 +57,7 @@ export type { DropdownProps, DropdownTriggerProps, DropdownMenuProps, DropdownIt
|
|
|
57
57
|
export { CommandPalette } from "./CommandPalette";
|
|
58
58
|
export type { CommandPaletteProps, Command } from "./CommandPalette";
|
|
59
59
|
export { Icon } from "./Icon";
|
|
60
|
-
export type { IconProps, IconSize } from "./Icon";
|
|
60
|
+
export type { IconComponent, IconProps, IconSize } from "./Icon";
|
|
61
61
|
export { Heading } from "./Heading";
|
|
62
62
|
export type { HeadingProps, HeadingLevel } from "./Heading";
|
|
63
63
|
export { Text } from "./Text";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { Navbar, NavbarLinks, NavbarLink } from "./Navbar";
|
|
2
|
+
export type { NavbarProps, NavbarLinksProps, NavbarLinkProps } from "./Navbar";
|
|
3
|
+
export { Hero } from "./Hero";
|
|
4
|
+
export type { HeroProps } from "./Hero";
|
|
5
|
+
export { Section, SectionHeader } from "./Section";
|
|
6
|
+
export type { SectionProps, SectionHeaderProps, SectionSize, SectionBackground } from "./Section";
|
|
7
|
+
export { SplitSection } from "./SplitSection";
|
|
8
|
+
export type { SplitSectionProps } from "./SplitSection";
|
|
9
|
+
export { FeatureGrid, FeatureCard } from "./FeatureGrid";
|
|
10
|
+
export type { FeatureGridProps, FeatureCardProps, FeatureGridColumns } from "./FeatureGrid";
|
|
11
|
+
export { Stats, StatItem } from "./Stats";
|
|
12
|
+
export type { StatsProps, StatItemProps } from "./Stats";
|
|
13
|
+
export { PricingGrid, PricingCard } from "./Pricing";
|
|
14
|
+
export type { PricingGridProps, PricingCardProps } from "./Pricing";
|
|
15
|
+
export { TestimonialGrid, TestimonialCard } from "./Testimonial";
|
|
16
|
+
export type { TestimonialGridProps, TestimonialCardProps } from "./Testimonial";
|
|
17
|
+
export { FAQ, FAQItem } from "./FAQ";
|
|
18
|
+
export type { FAQProps, FAQItemProps } from "./FAQ";
|
|
19
|
+
export { CTABanner } from "./CTABanner";
|
|
20
|
+
export type { CTABannerProps } from "./CTABanner";
|
|
21
|
+
export { LPFooter } from "./LPFooter";
|
|
22
|
+
export type { LPFooterProps, FooterColumn } from "./LPFooter";
|
|
@@ -82,5 +82,18 @@ export declare const radius: {
|
|
|
82
82
|
readonly "2xl": "var(--radius-2xl)";
|
|
83
83
|
readonly full: "var(--radius-full)";
|
|
84
84
|
};
|
|
85
|
+
/** Switched by `data-density="compact"` on an ancestor. */
|
|
86
|
+
export declare const density: {
|
|
87
|
+
readonly controlHeight: "var(--density-control-height)";
|
|
88
|
+
readonly rowPy: "var(--density-row-py)";
|
|
89
|
+
readonly rowPx: "var(--density-row-px)";
|
|
90
|
+
readonly fontSizeUi: "var(--density-font-size-ui)";
|
|
91
|
+
readonly lineHeightUi: "var(--density-line-height-ui)";
|
|
92
|
+
readonly navPy: "var(--density-nav-py)";
|
|
93
|
+
readonly navGap: "var(--density-nav-gap)";
|
|
94
|
+
readonly dropdownPy: "var(--density-dropdown-py)";
|
|
95
|
+
readonly tabPy: "var(--density-tab-py)";
|
|
96
|
+
};
|
|
85
97
|
export type Theme = "light" | "dark";
|
|
86
98
|
export type Palette = "warm" | "cool";
|
|
99
|
+
export type Density = "default" | "compact";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kaze-design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/yuki930/kaze-design-system/issues"
|
|
14
14
|
},
|
|
15
|
-
"description": "Minimal React design system for dashboards and Japanese UI
|
|
15
|
+
"description": "Minimal React design system for dashboards, landing pages and Japanese UI: warm neutral grays, 63 components, light/dark themes, typography tuned for CJK text",
|
|
16
16
|
"keywords": [
|
|
17
17
|
"design-system",
|
|
18
18
|
"react",
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
"types": "./dist/types/components/index.d.ts",
|
|
33
33
|
"import": "./dist/index.js"
|
|
34
34
|
},
|
|
35
|
+
"./marketing": {
|
|
36
|
+
"types": "./dist/types/components/marketing.d.ts",
|
|
37
|
+
"import": "./dist/marketing.js"
|
|
38
|
+
},
|
|
35
39
|
"./hooks": {
|
|
36
40
|
"types": "./dist/types/hooks/index.d.ts",
|
|
37
41
|
"import": "./dist/hooks.js"
|
|
@@ -40,6 +44,7 @@
|
|
|
40
44
|
"types": "./dist/types/tokens/tokens.d.ts",
|
|
41
45
|
"import": "./dist/tokens.js"
|
|
42
46
|
},
|
|
47
|
+
"./package.json": "./package.json",
|
|
43
48
|
"./css/tokens": "./tokens.css",
|
|
44
49
|
"./css/reset": "./reset.css",
|
|
45
50
|
"./css/components": "./components.css",
|
|
@@ -54,6 +59,9 @@
|
|
|
54
59
|
"utilities.css",
|
|
55
60
|
"kaze.css"
|
|
56
61
|
],
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=18"
|
|
64
|
+
},
|
|
57
65
|
"sideEffects": [
|
|
58
66
|
"*.css"
|
|
59
67
|
],
|
|
@@ -63,7 +71,10 @@
|
|
|
63
71
|
"build": "next build",
|
|
64
72
|
"docs:llms": "node scripts/generate-llms.mjs",
|
|
65
73
|
"docs:stories": "node scripts/generate-stories.mjs",
|
|
66
|
-
"
|
|
74
|
+
"size": "npm run build:lib && node scripts/measure-size.mjs",
|
|
75
|
+
"test": "vitest run --project unit",
|
|
76
|
+
"test:storybook": "vitest run --project storybook",
|
|
77
|
+
"test:all": "vitest run",
|
|
67
78
|
"test:watch": "vitest",
|
|
68
79
|
"start": "next start",
|
|
69
80
|
"build:lib": "rm -rf dist && vite build --config vite.config.lib.ts && tsc -p tsconfig.build.json",
|
|
@@ -71,12 +82,6 @@
|
|
|
71
82
|
"build-storybook": "storybook build",
|
|
72
83
|
"typecheck": "tsc --noEmit"
|
|
73
84
|
},
|
|
74
|
-
"dependencies": {
|
|
75
|
-
"lucide-react": "^0.575.0",
|
|
76
|
-
"next": "^16.1.6",
|
|
77
|
-
"react": "^19.2.4",
|
|
78
|
-
"react-dom": "^19.2.4"
|
|
79
|
-
},
|
|
80
85
|
"peerDependencies": {
|
|
81
86
|
"lucide-react": "^0.575.0",
|
|
82
87
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -104,7 +109,11 @@
|
|
|
104
109
|
"@vitest/browser-playwright": "^4.0.18",
|
|
105
110
|
"@vitest/coverage-v8": "^4.0.18",
|
|
106
111
|
"jsdom": "^28.1.0",
|
|
112
|
+
"lucide-react": "^0.575.0",
|
|
113
|
+
"next": "^16.1.6",
|
|
107
114
|
"playwright": "^1.58.2",
|
|
115
|
+
"react": "^19.2.4",
|
|
116
|
+
"react-dom": "^19.2.4",
|
|
108
117
|
"rollup-plugin-preserve-directives": "^0.4.0",
|
|
109
118
|
"storybook": "^10.2.10",
|
|
110
119
|
"typescript": "^5.9.3",
|
package/tokens.css
CHANGED
|
@@ -296,6 +296,22 @@
|
|
|
296
296
|
--topbar-height: 3.5rem;
|
|
297
297
|
--content-max-width: 1280px;
|
|
298
298
|
|
|
299
|
+
/* ── Density (component sizing — orthogonal to color theme) ──
|
|
300
|
+
Two-stage system: normal values here, [data-density="compact"]
|
|
301
|
+
overrides below. Attach the attribute to :root or any container;
|
|
302
|
+
custom properties inherit down the subtree either way.
|
|
303
|
+
Every normal value below equals the literal it replaces, so the
|
|
304
|
+
default appearance does not change when this section is added. */
|
|
305
|
+
--density-control-height: 2.25rem; /* Input / Select / Button (default size) */
|
|
306
|
+
--density-row-py: var(--space-3); /* Table cell / List-item vertical padding */
|
|
307
|
+
--density-row-px: var(--space-4); /* Table cell horizontal padding */
|
|
308
|
+
--density-font-size-ui: var(--font-size-sm); /* Table / List / Tabs / Dropdown / Sidebar / controls */
|
|
309
|
+
--density-line-height-ui: var(--line-height-normal); /* Table / List row line-height */
|
|
310
|
+
--density-nav-py: var(--space-2); /* Sidebar nav-item vertical padding */
|
|
311
|
+
--density-nav-gap: var(--space-2-5); /* Sidebar nav-item icon gap */
|
|
312
|
+
--density-dropdown-py: var(--space-1-5); /* Dropdown item vertical padding */
|
|
313
|
+
--density-tab-py: var(--space-2); /* Tabs vertical padding */
|
|
314
|
+
|
|
299
315
|
/* ── Fluid Typography (inspired by Pico CSS) ─────────── */
|
|
300
316
|
/* Root font-size scales fluidly between 640px and 1280px viewport */
|
|
301
317
|
/* Components using rem will scale proportionally */
|
|
@@ -310,6 +326,24 @@
|
|
|
310
326
|
/* 2xl: 1536px — 超ワイド */
|
|
311
327
|
}
|
|
312
328
|
|
|
329
|
+
/* ── Density: compact ──────────────────────────────────────────
|
|
330
|
+
Tightens control height, row padding, UI font-size and line-height
|
|
331
|
+
by roughly one step. Works wherever the attribute is applied —
|
|
332
|
+
:root for a whole app, or a single container (e.g. a dense table
|
|
333
|
+
panel) — since custom properties inherit to descendants either way.
|
|
334
|
+
Orthogonal to [data-theme] / [data-palette]: combine freely. ──── */
|
|
335
|
+
[data-density="compact"] {
|
|
336
|
+
--density-control-height: 2rem;
|
|
337
|
+
--density-row-py: var(--space-2);
|
|
338
|
+
--density-row-px: var(--space-3);
|
|
339
|
+
--density-font-size-ui: var(--font-size-xs);
|
|
340
|
+
--density-line-height-ui: var(--line-height-snug);
|
|
341
|
+
--density-nav-py: var(--space-1-5);
|
|
342
|
+
--density-nav-gap: var(--space-2);
|
|
343
|
+
--density-dropdown-py: var(--space-1);
|
|
344
|
+
--density-tab-py: var(--space-1-5);
|
|
345
|
+
}
|
|
346
|
+
|
|
313
347
|
/* ── Dark Theme ────────────────────────────────────────────── */
|
|
314
348
|
[data-theme="dark"] {
|
|
315
349
|
--color-bg: var(--zinc-950);
|
|
@@ -446,8 +480,10 @@
|
|
|
446
480
|
/* ── Dark Theme Fallback (JS-disabled) ────────────────────── */
|
|
447
481
|
/* When JS is unavailable, respect OS dark mode preference.
|
|
448
482
|
If JS sets data-theme="light", this will NOT apply (thanks to :not()).
|
|
449
|
-
If JS sets data-theme="dark",
|
|
450
|
-
|
|
483
|
+
If JS sets data-theme="dark", this block applies too (same values as
|
|
484
|
+
[data-theme="dark"]; :root:not(...) is the higher specificity).
|
|
485
|
+
The cool palette needs its own fallback below, otherwise this block
|
|
486
|
+
(0,2,0, later in source) overrides [data-palette="cool"][data-theme="dark"]. */
|
|
451
487
|
@media (prefers-color-scheme: dark) {
|
|
452
488
|
:root:not([data-theme="light"]) {
|
|
453
489
|
--color-bg: var(--zinc-950);
|
|
@@ -515,3 +551,37 @@
|
|
|
515
551
|
--ring-color: rgba(168, 162, 158, 0.3);
|
|
516
552
|
}
|
|
517
553
|
}
|
|
554
|
+
|
|
555
|
+
/* Cool palette × OS dark fallback (specificity 0,3,0 beats the zinc fallback) */
|
|
556
|
+
@media (prefers-color-scheme: dark) {
|
|
557
|
+
:root[data-palette="cool"]:not([data-theme="light"]) {
|
|
558
|
+
--color-bg: var(--slate-950);
|
|
559
|
+
--color-bg-secondary: var(--slate-900);
|
|
560
|
+
--color-bg-tertiary: var(--slate-800);
|
|
561
|
+
--color-bg-inverse: #ffffff;
|
|
562
|
+
|
|
563
|
+
--color-fg: var(--slate-50);
|
|
564
|
+
--color-fg-secondary: var(--slate-400);
|
|
565
|
+
--color-fg-tertiary: var(--slate-400);
|
|
566
|
+
--color-fg-inverse: var(--slate-950);
|
|
567
|
+
--color-fg-muted: var(--slate-400);
|
|
568
|
+
|
|
569
|
+
--color-border: var(--slate-800);
|
|
570
|
+
--color-border-strong: var(--slate-700);
|
|
571
|
+
--color-border-subtle: var(--slate-900);
|
|
572
|
+
|
|
573
|
+
--color-surface: var(--slate-900);
|
|
574
|
+
--color-surface-hover: var(--slate-800);
|
|
575
|
+
--color-surface-active: var(--slate-700);
|
|
576
|
+
|
|
577
|
+
--color-primary: #ffffff;
|
|
578
|
+
--color-primary-fg: var(--slate-950);
|
|
579
|
+
--color-primary-hover: var(--slate-200);
|
|
580
|
+
|
|
581
|
+
--color-secondary: var(--slate-800);
|
|
582
|
+
--color-secondary-fg: var(--slate-100);
|
|
583
|
+
--color-secondary-hover: var(--slate-700);
|
|
584
|
+
|
|
585
|
+
--ring-color: rgba(204, 202, 216, 0.3);
|
|
586
|
+
}
|
|
587
|
+
}
|
package/utilities.css
CHANGED
|
@@ -404,6 +404,11 @@
|
|
|
404
404
|
[data-theme="dark"] .theme-photo {
|
|
405
405
|
filter: brightness(0.8) contrast(1.1);
|
|
406
406
|
}
|
|
407
|
+
@media (prefers-color-scheme: dark) {
|
|
408
|
+
:root:not([data-theme="light"]) .theme-photo {
|
|
409
|
+
filter: brightness(0.8) contrast(1.1);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
407
412
|
|
|
408
413
|
/* ============================================================
|
|
409
414
|
Responsive Utilities
|