sparkle-design 0.9.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.
Files changed (125) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +5 -0
  3. package/README.en.md +275 -0
  4. package/README.md +328 -0
  5. package/dist/components/ui/badge/index.d.ts +67 -0
  6. package/dist/components/ui/badge/index.figma.d.ts +1 -0
  7. package/dist/components/ui/badge/index.figma.js +28 -0
  8. package/dist/components/ui/badge/index.js +129 -0
  9. package/dist/components/ui/breadcrumb/index.d.ts +70 -0
  10. package/dist/components/ui/breadcrumb/index.figma.d.ts +1 -0
  11. package/dist/components/ui/breadcrumb/index.figma.js +28 -0
  12. package/dist/components/ui/breadcrumb/index.js +96 -0
  13. package/dist/components/ui/button/index.d.ts +145 -0
  14. package/dist/components/ui/button/index.figma.d.ts +1 -0
  15. package/dist/components/ui/button/index.figma.js +59 -0
  16. package/dist/components/ui/button/index.js +375 -0
  17. package/dist/components/ui/card/index.d.ts +193 -0
  18. package/dist/components/ui/card/index.figma.d.ts +1 -0
  19. package/dist/components/ui/card/index.figma.js +28 -0
  20. package/dist/components/ui/card/index.js +219 -0
  21. package/dist/components/ui/checkbox/index.d.ts +62 -0
  22. package/dist/components/ui/checkbox/index.figma.d.ts +1 -0
  23. package/dist/components/ui/checkbox/index.figma.js +34 -0
  24. package/dist/components/ui/checkbox/index.js +192 -0
  25. package/dist/components/ui/dialog/index.d.ts +106 -0
  26. package/dist/components/ui/dialog/index.figma.d.ts +1 -0
  27. package/dist/components/ui/dialog/index.figma.js +21 -0
  28. package/dist/components/ui/dialog/index.js +157 -0
  29. package/dist/components/ui/divider/index.d.ts +44 -0
  30. package/dist/components/ui/divider/index.figma.d.ts +1 -0
  31. package/dist/components/ui/divider/index.figma.js +39 -0
  32. package/dist/components/ui/divider/index.js +81 -0
  33. package/dist/components/ui/form/index.d.ts +171 -0
  34. package/dist/components/ui/form/index.figma.d.ts +1 -0
  35. package/dist/components/ui/form/index.figma.js +129 -0
  36. package/dist/components/ui/form/index.js +214 -0
  37. package/dist/components/ui/form/label.d.ts +4 -0
  38. package/dist/components/ui/form/label.js +20 -0
  39. package/dist/components/ui/icon/index.d.ts +71 -0
  40. package/dist/components/ui/icon/index.figma.d.ts +1 -0
  41. package/dist/components/ui/icon/index.figma.js +1858 -0
  42. package/dist/components/ui/icon/index.js +57 -0
  43. package/dist/components/ui/icon-button/index.d.ts +77 -0
  44. package/dist/components/ui/icon-button/index.figma.d.ts +1 -0
  45. package/dist/components/ui/icon-button/index.figma.js +43 -0
  46. package/dist/components/ui/icon-button/index.js +341 -0
  47. package/dist/components/ui/inline-message/index.d.ts +83 -0
  48. package/dist/components/ui/inline-message/index.figma.d.ts +1 -0
  49. package/dist/components/ui/inline-message/index.figma.js +26 -0
  50. package/dist/components/ui/inline-message/index.js +154 -0
  51. package/dist/components/ui/input/index.d.ts +118 -0
  52. package/dist/components/ui/input/index.figma.d.ts +1 -0
  53. package/dist/components/ui/input/index.figma.js +36 -0
  54. package/dist/components/ui/input/index.js +256 -0
  55. package/dist/components/ui/input-password/index.d.ts +27 -0
  56. package/dist/components/ui/input-password/index.figma.d.ts +1 -0
  57. package/dist/components/ui/input-password/index.figma.js +36 -0
  58. package/dist/components/ui/input-password/index.js +35 -0
  59. package/dist/components/ui/link/index.d.ts +68 -0
  60. package/dist/components/ui/link/index.figma.d.ts +1 -0
  61. package/dist/components/ui/link/index.figma.js +22 -0
  62. package/dist/components/ui/link/index.js +92 -0
  63. package/dist/components/ui/modal/index.d.ts +83 -0
  64. package/dist/components/ui/modal/index.figma.d.ts +1 -0
  65. package/dist/components/ui/modal/index.figma.js +61 -0
  66. package/dist/components/ui/modal/index.js +143 -0
  67. package/dist/components/ui/overlay/index.d.ts +19 -0
  68. package/dist/components/ui/overlay/index.figma.d.ts +1 -0
  69. package/dist/components/ui/overlay/index.figma.js +14 -0
  70. package/dist/components/ui/overlay/index.js +39 -0
  71. package/dist/components/ui/radio/index.d.ts +94 -0
  72. package/dist/components/ui/radio/index.figma.d.ts +1 -0
  73. package/dist/components/ui/radio/index.figma.js +63 -0
  74. package/dist/components/ui/radio/index.js +204 -0
  75. package/dist/components/ui/select/index.d.ts +175 -0
  76. package/dist/components/ui/select/index.figma.d.ts +1 -0
  77. package/dist/components/ui/select/index.figma.js +30 -0
  78. package/dist/components/ui/select/index.js +281 -0
  79. package/dist/components/ui/skeleton/index.d.ts +21 -0
  80. package/dist/components/ui/skeleton/index.figma.d.ts +1 -0
  81. package/dist/components/ui/skeleton/index.figma.js +14 -0
  82. package/dist/components/ui/skeleton/index.js +32 -0
  83. package/dist/components/ui/slider/index.d.ts +75 -0
  84. package/dist/components/ui/slider/index.figma.d.ts +1 -0
  85. package/dist/components/ui/slider/index.figma.js +28 -0
  86. package/dist/components/ui/slider/index.js +113 -0
  87. package/dist/components/ui/slider/utils.d.ts +16 -0
  88. package/dist/components/ui/slider/utils.js +56 -0
  89. package/dist/components/ui/spinner/index.d.ts +42 -0
  90. package/dist/components/ui/spinner/index.figma.d.ts +1 -0
  91. package/dist/components/ui/spinner/index.figma.js +16 -0
  92. package/dist/components/ui/spinner/index.js +51 -0
  93. package/dist/components/ui/switch/index.d.ts +46 -0
  94. package/dist/components/ui/switch/index.figma.d.ts +1 -0
  95. package/dist/components/ui/switch/index.figma.js +27 -0
  96. package/dist/components/ui/switch/index.js +75 -0
  97. package/dist/components/ui/tabs/index.d.ts +53 -0
  98. package/dist/components/ui/tabs/index.figma.d.ts +1 -0
  99. package/dist/components/ui/tabs/index.figma.js +55 -0
  100. package/dist/components/ui/tabs/index.js +164 -0
  101. package/dist/components/ui/tag/index.d.ts +50 -0
  102. package/dist/components/ui/tag/index.figma.d.ts +1 -0
  103. package/dist/components/ui/tag/index.figma.js +32 -0
  104. package/dist/components/ui/tag/index.js +177 -0
  105. package/dist/components/ui/textarea/index.d.ts +49 -0
  106. package/dist/components/ui/textarea/index.figma.d.ts +1 -0
  107. package/dist/components/ui/textarea/index.figma.js +27 -0
  108. package/dist/components/ui/textarea/index.js +94 -0
  109. package/dist/components/ui/toast/index.d.ts +60 -0
  110. package/dist/components/ui/toast/index.figma.d.ts +1 -0
  111. package/dist/components/ui/toast/index.figma.js +26 -0
  112. package/dist/components/ui/toast/index.js +57 -0
  113. package/dist/components/ui/tooltip/index.d.ts +52 -0
  114. package/dist/components/ui/tooltip/index.figma.d.ts +1 -0
  115. package/dist/components/ui/tooltip/index.figma.js +23 -0
  116. package/dist/components/ui/tooltip/index.js +65 -0
  117. package/dist/index.d.ts +27 -0
  118. package/dist/index.js +27 -0
  119. package/dist/lib/utils.d.ts +2 -0
  120. package/dist/lib/utils.js +5 -0
  121. package/dist/test/helpers.d.ts +56 -0
  122. package/dist/test/helpers.js +182 -0
  123. package/dist/test/setup.d.ts +1 -0
  124. package/dist/test/setup.js +38 -0
  125. package/package.json +253 -0
package/README.md ADDED
@@ -0,0 +1,328 @@
1
+ <p align="center">
2
+ <a href="https://sparkle-design.goodpatch.com/">
3
+ <img src="https://raw.githubusercontent.com/goodpatch/sparkle-design/main/public/thumbnail.png" alt="Sparkle Design" width="1200">
4
+ </a>
5
+ </p>
6
+
7
+ # Sparkle Design for React
8
+
9
+ **[English](./README.en.md)** | 日本語
10
+
11
+ [![npm version](https://img.shields.io/npm/v/sparkle-design)](https://www.npmjs.com/package/sparkle-design)
12
+ [![Sparkle Design](https://img.shields.io/badge/made%20with-Sparkle%20Design-0969DA)](https://sparkle-design.goodpatch.com/)
13
+ [![ci](https://github.com/goodpatch/sparkle-design/actions/workflows/ci.yml/badge.svg)](https://github.com/goodpatch/sparkle-design/actions/workflows/ci.yml)
14
+ [![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
15
+
16
+
17
+ React.js + TypeScript を用いたコンポーネントライブラリです。<br />
18
+ shadcn/ui をベースに、[グッドパッチ](https://goodpatch.com/)のデザインシステム「Sparkle Design」を実装しています。
19
+
20
+ ## 特徴
21
+
22
+ - 🔧 **柔軟性** ... shadcn/ui をベースに shadcn/ui registry に対応しているため、1コンポーネントから導入が可能です。npm パッケージとしても公開しているため、プロジェクトごとに適した方法で導入していただくことが出来ます。
23
+ - ♿️ **アクセシビリティ** ... Sparkle Design はアクセシビリティを重視して設計されています。
24
+ - 🎨 **カスタマイズ性** ... 専用CLIツールを利用し、Figmaファイルと同等のカスタマイズを適用することが出来ます。これによりSparkle Designをベースとしたデザインシステムのコードを素早く用意することが出来ます。
25
+ - 🤖 **AI フレンドリー** ... Claude Code / Cursor / Codex 向けのスキルとガード設定を同梱。AI コーディングでもデザインシステムの品質を維持できます。
26
+
27
+ ## 使用方法
28
+
29
+ ### パッケージのインストール
30
+
31
+ npm パッケージとして公開済みです。以下の手順でインストールできます。
32
+
33
+ ```bash
34
+ npm install sparkle-design
35
+ # または
36
+ pnpm add sparkle-design
37
+ # または
38
+ yarn add sparkle-design
39
+ ```
40
+
41
+ > このパッケージには CSS は同梱されません。利用側で `sparkle-design-cli generate` を実行し、生成された `sparkle-design.css` / `SparkleHead.tsx` を自分のアプリに配置して利用してください。Tailwind エントリポイント CSS(`globals.css` 等)には `@source` ディレクティブが自動挿入されます。
42
+
43
+ > **Server Component で使う場合**: `"use client"` を含むコンポーネントは個別 import を推奨します。各コンポーネントの [README](src/components/ui/) に Server Component / Client Component の情報が記載されています。
44
+ >
45
+ > ```tsx
46
+ > import { Button } from "sparkle-design/button";
47
+ > ```
48
+
49
+ ### 個別コンポーネントの導入
50
+
51
+ Sparkle Design は shadcn/ui registry に対応しています。レジストリの URL は Storybook からコピーすることができます。<br />
52
+ shadcn/ui registry の詳細な情報は [公式ドキュメント](https://ui.shadcn.com/docs/registry/getting-started) を参照してください。
53
+
54
+ ```bash
55
+ pnpm dlx shadcn@latest add [registry URL]
56
+ ```
57
+
58
+ また[Namespaces](https://ui.shadcn.com/docs/registry/namespace)を`components.json`に指定することで、コンポーネント名でのインストールも可能になります。
59
+
60
+ ```json
61
+ {
62
+ "registries": {
63
+ "@sparkle-design": "https://sparkle-design.goodpatch.com/r/{name}.json"
64
+ }
65
+ }
66
+ ```
67
+
68
+ ```bash
69
+ pnpm dlx shadcn@latest add @sparkle-design/button
70
+ ```
71
+
72
+ ### 基本的な使用例
73
+
74
+ ```tsx
75
+ import React from "react";
76
+ import { Button, Badge, Card } from "sparkle-design";
77
+
78
+ function App() {
79
+ return (
80
+ <div>
81
+ <Card>
82
+ <h1>Sparkle Design を使った例</h1>
83
+ <Badge variant="primary">新機能</Badge>
84
+ <Button variant="primary" size="md">
85
+ ボタンをクリック
86
+ </Button>
87
+ </Card>
88
+ </div>
89
+ );
90
+ }
91
+
92
+ export default App;
93
+ ```
94
+
95
+ ### スタイルファイルについて
96
+
97
+ - **Tailwind エントリポイント CSS**(`globals.css` / `index.css` 等): 基本的な Tailwind CSS とリセットスタイル
98
+ - **`sparkle-design.css`**: Sparkle Design のデザイントークン(カラー、フォント、角丸、シャドウなど)
99
+ - **`SparkleHead.tsx`**: フォント読み込み用 React コンポーネント
100
+
101
+ これらのファイルをインポートすることで、Sparkle Design の全機能を利用できます。
102
+
103
+ #### npm パッケージとして利用する場合
104
+
105
+ `sparkle-design` を npm パッケージとしてインストールして利用する場合、TailwindCSS v4 がパッケージ内のユーティリティクラスを検出できるよう `@source` ディレクティブが必要です。
106
+
107
+ `sparkle-design-cli generate` を実行すると、`@import "tailwindcss"` を含む CSS ファイルを自動検出し、`@source` ディレクティブを挿入します。`globals.css` 以外のファイル名(Vite の `index.css` 等)にも対応しています。自動検出がうまく動かない場合は `sparkle.config.json` の `extend.globals-path` か CLI の `--globals-path` オプションで明示的に指定できます。
108
+
109
+ 手動で設定する場合は、Tailwind エントリポイント CSS に以下を追加してください:
110
+
111
+ ```css
112
+ @import "tailwindcss";
113
+ /* sparkle-design のクラスをスキャン対象にする */
114
+ /* パスは CSS ファイルの配置に応じて調整(src/app/globals.css なら ../../node_modules/...) */
115
+ @source "../../node_modules/sparkle-design/dist";
116
+ /* Sparkle Design のカスタム定義(Tailwindの後にインポート) */
117
+ @import "./sparkle-design.css";
118
+ ```
119
+
120
+ > **注意**: `@source` の相対パスは CSS ファイルの配置場所に依存します。上記は `src/app/globals.css` の場合の例です。
121
+
122
+ #### Sparkle Design CSS と SparkleHead の生成
123
+
124
+ `sparkle.config.json` の設定に基づいて、デザインシステムに準拠した CSS とフォント読み込み用コンポーネントを生成します。
125
+
126
+ ```bash
127
+ npx sparkle-design-cli generate
128
+ ```
129
+
130
+ このコマンドは以下のファイルを生成します:
131
+ - `sparkle-design.css` — デザイントークン CSS
132
+ - `SparkleHead.tsx` — フォント読み込み用 React コンポーネント
133
+
134
+ `SparkleHead` はルートレイアウトの `<head>` 内に配置してください:
135
+
136
+ ```tsx
137
+ import { SparkleHead } from "./SparkleHead";
138
+
139
+ export default function RootLayout({ children }) {
140
+ return (
141
+ <html>
142
+ <head>
143
+ <SparkleHead />
144
+ </head>
145
+ <body>{children}</body>
146
+ </html>
147
+ );
148
+ }
149
+ ```
150
+
151
+ > **Next.js App Router で `@next/next/no-head-element` が出る場合**: `next/core-web-vitals` を使用しているプロジェクトでは、`layout.tsx` に `<head>` を直接書くと lint エラーになることがあります。その場合は `eslint-disable` で該当行を除外するか、`next/font` による代替方法を検討してください。
152
+
153
+ > `SparkleHead` は `<link rel="preconnect">` と `<link rel="stylesheet">` でフォントを読み込みます。CSS の `@import` に比べてフォントの発見が早く、特にモバイル環境でのアイコン表示が改善されます。
154
+
155
+ 設定ファイル (`sparkle.config.json`) の基本設定:
156
+
157
+ - `primary`: プライマリカラー(blue, red, orange, green, purple, pink, yellow)
158
+ - `font-pro`: プロポーショナルフォント([Google Fonts](https://fonts.google.com/) の名前)
159
+ - `font-mono`: モノスペースフォント([Google Fonts](https://fonts.google.com/) の名前)
160
+ - `radius`: 角丸設定(none, sm, md, lg, xl, full)
161
+
162
+ 設定ファイルは [Sparkle Design Theme Settings](https://www.figma.com/community/plugin/1443500367756891364/sparkle-design-theme-settings) Figma プラグインから書き出すことができます。
163
+
164
+ フォントウェイトのカスタマイズ、フォールバックチェーン、カスタムトークン CSS などの拡張設定は `sparkle.config.json` の `extend` セクションで指定できます。詳細は `sparkle-design-cli generate --help` を参照してください。
165
+
166
+ ```bash
167
+ # CSS を生成
168
+ npx sparkle-design-cli generate
169
+
170
+ # アンチパターンを検査
171
+ npx sparkle-design-cli check src --strict
172
+
173
+ # AI アシスタント向けの guard 設定を導入先プロジェクトに差し込む
174
+ npx sparkle-design-cli setup --assistant claude
175
+ ```
176
+
177
+ `setup` は導入先の `package.json` に `lint:sparkle` スクリプトを追加し、AI アシスタント向けの指示ファイル(`CLAUDE.md` / `AGENTS.md` / `.cursor/rules/` 等)に Sparkle Design の品質チェックガイドを差し込みます。詳細は `sparkle-design-cli setup --help` を参照してください。
178
+
179
+ ## 開発ガイド
180
+
181
+ ### 開発環境
182
+
183
+ - Node.js 22.14.0 以上
184
+ - pnpm 10 以上
185
+
186
+ ### ディレクトリ構成
187
+
188
+ ```text
189
+ ├─ src/
190
+ │ ├─ app/ # Sparkle Designのページとスタイルファイル
191
+ │ ├─ components/ # React コンポーネント
192
+ │ └─ lib/ # 共有ユーティリティ
193
+ ├─ scripts/ # 各種スクリプト
194
+ ├─ docs/
195
+ │ └─ ai-instructions/ # 開発・テスト・AI向けガイドライン(ソース)
196
+ └─ .github/ # GitHub関連の設定ファイル
197
+ ```
198
+
199
+ ### Package のビルド
200
+
201
+ ```bash
202
+ pnpm build:package
203
+ ```
204
+
205
+ ### Storybook の起動
206
+
207
+ ```bash
208
+ pnpm storybook
209
+ ```
210
+
211
+ ### テストの実行
212
+
213
+ ```bash
214
+ pnpm test
215
+ ```
216
+
217
+ テストガイドラインについては `docs/ai-instructions/testing.md` を参照してください。
218
+
219
+ ### コードフォーマット
220
+
221
+ ```bash
222
+ # フォーマットチェック
223
+ pnpm format:check
224
+
225
+ # 自動フォーマット
226
+ pnpm format
227
+
228
+ # ESLint チェック (Next.js 経由)
229
+ pnpm lint:check
230
+ # または
231
+ pnpm lint
232
+
233
+ # ESLint 自動修正 (Next.js 経由)
234
+ pnpm lint:fix
235
+
236
+ # 型チェック
237
+ pnpm type-check
238
+ ```
239
+
240
+ **注意**: ESLintは`next lint`コマンドを使用しており、Next.jsプロジェクトに最適化された設定とルールが適用されます。
241
+
242
+ ### Makefile について
243
+
244
+ Makefile では次のターゲットが定義されています。
245
+
246
+ - `registry` ... レジストリの生成と公開ファイルへのコピー
247
+ - `new-component` ... 対話形式で新規コンポーネントを作成
248
+
249
+ `make help` で詳細は確認してください。
250
+
251
+ ### Sparkle Design バッジ
252
+
253
+ Sparkle Design のバッジは、コンポーネントが Sparkle Design を使用していることを示します。README に次のように追加してください。
254
+
255
+ ```markdown
256
+ [![Sparkle Design](https://img.shields.io/badge/made%20with-Sparkle%20Design-0969DA)](https://sparkle-design.goodpatch.com/)
257
+ ```
258
+
259
+ ### その他
260
+
261
+ - コメントの書き方は `docs/ai-instructions/comment-style.md` を参照してください。
262
+ - コミットメッセージの形式は `.github/copilot-commit-message-instructions.md` のルールに従います。
263
+ - 変更履歴は `CHANGELOG.md` を参照してください。
264
+ - 公開用ドメインを切り替える場合は `pnpm update:public-domain -- --to https://new-domain.example.com --dry-run` で影響範囲を確認し、その後 `--dry-run` を外して一括更新できます。
265
+ - その他開発・テスト・AI関連のガイドラインは `docs/ai-instructions/` ディレクトリを参照してください。
266
+
267
+ ## コンポーネント公開状況
268
+
269
+ 現在公開されているコンポーネントの一覧です。
270
+ ✅ 公開中
271
+ ❌ 非公開・開発前
272
+
273
+ | コンポーネント | 実装 | Storybook | レジストリ | Figma Code Connect | A11y チェック |
274
+ | ----------------- | ---- | --------- | ---------- | ------------------ | ------------- |
275
+ | Avatar | ❌ | ❌ | ❌ | ❌ | ❌ |
276
+ | Badge | ✅ | ✅ | ✅ | ✅ | ✅ |
277
+ | Breadcrumb | ✅ | ✅ | ✅ | ✅ | ✅ |
278
+ | Button | ✅ | ✅ | ✅ | ✅ | ✅ |
279
+ | Calendar | ❌ | ❌ | ❌ | ❌ | ❌ |
280
+ | Card | ✅ | ✅ | ✅ | ✅ | ✅ |
281
+ | Checkbox | ✅ | ✅ | ✅ | ✅ | ✅ |
282
+ | Dialog | ✅ | ✅ | ✅ | ✅ | ✅ |
283
+ | Divider | ✅ | ✅ | ✅ | ✅ | ✅ |
284
+ | Filter Chip | ❌ | ❌ | ❌ | ❌ | ❌ |
285
+ | Form | ✅ | ✅ | ✅ | ✅ | ✅ |
286
+ | Icon | ✅ | ✅ | ✅ | ✅ | ✅ |
287
+ | Icon Button | ✅ | ✅ | ✅ | ✅ | ✅ |
288
+ | Image | ❌ | ❌ | ❌ | ❌ | ❌ |
289
+ | Inline Message | ✅ | ✅ | ✅ | ✅ | ✅ |
290
+ | Input | ✅ | ✅ | ✅ | ✅ | ✅ |
291
+ | Input Chip | ❌ | ❌ | ❌ | ❌ | ❌ |
292
+ | Input Date | ❌ | ❌ | ❌ | ❌ | ❌ |
293
+ | Input File | ❌ | ❌ | ❌ | ❌ | ❌ |
294
+ | Input Number | ❌ | ❌ | ❌ | ❌ | ❌ |
295
+ | Input Password | ✅ | ✅ | ✅ | ✅ | ✅ |
296
+ | Input Search | ❌ | ❌ | ❌ | ❌ | ❌ |
297
+ | Input Time | ❌ | ❌ | ❌ | ❌ | ❌ |
298
+ | Link | ✅ | ✅ | ✅ | ✅ | ✅ |
299
+ | List | ❌ | ❌ | ❌ | ❌ | ❌ |
300
+ | Menu | ❌ | ❌ | ❌ | ❌ | ❌ |
301
+ | Modal | ✅ | ✅ | ✅ | ✅ | ✅ |
302
+ | Overlay | ✅ | ✅ | ✅ | ✅ | ✅ |
303
+ | Pagination | ❌ | ❌ | ❌ | ❌ | ❌ |
304
+ | Popover | ❌ | ❌ | ❌ | ❌ | ❌ |
305
+ | Radio | ✅ | ✅ | ✅ | ✅ | ✅ |
306
+ | Segmented Control | ❌ | ❌ | ❌ | ❌ | ❌ |
307
+ | Select | ✅ | ✅ | ✅ | ✅ | ✅ |
308
+ | Side Navigation | ❌ | ❌ | ❌ | ❌ | ❌ |
309
+ | Skeleton | ✅ | ✅ | ✅ | ✅ | ✅ |
310
+ | Slider | ✅ | ✅ | ✅ | ✅ | ✅ |
311
+ | Slot | ❌ | ❌ | ❌ | ❌ | ❌ |
312
+ | Spinner | ✅ | ✅ | ✅ | ✅ | ✅ |
313
+ | Stack | ❌ | ❌ | ❌ | ❌ | ❌ |
314
+ | Stepper | ❌ | ❌ | ❌ | ❌ | ❌ |
315
+ | Switch | ✅ | ✅ | ✅ | ✅ | ✅ |
316
+ | Table | ❌ | ❌ | ❌ | ❌ | ❌ |
317
+ | Tabs | ✅ | ✅ | ✅ | ✅ | ✅ |
318
+ | Tag | ✅ | ✅ | ✅ | ✅ | ✅ |
319
+ | Textarea | ✅ | ✅ | ✅ | ✅ | ✅ |
320
+ | Toast | ✅ | ✅ | ✅ | ✅ | ✅ |
321
+ | Tooltip | ✅ | ✅ | ✅ | ✅ | ✅ |
322
+ | Vertical Tabs | ❌ | ❌ | ❌ | ❌ | ❌ |
323
+
324
+ ## ライセンス
325
+
326
+ [Apache License 2.0](LICENSE)
327
+
328
+ Copyright 2026 [Goodpatch Inc.](https://goodpatch.com/)
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Copyright 2026 Goodpatch Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import * as React from "react";
6
+ import { type VariantProps } from "class-variance-authority";
7
+ declare const badgeVariants: (props?: ({
8
+ variant?: "normal" | "emphasis" | null | undefined;
9
+ isNumberVisible?: boolean | null | undefined;
10
+ size?: "xs" | "sm" | "md" | "lg" | null | undefined;
11
+ isGapped?: boolean | null | undefined;
12
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
13
+ type BadgeVariants = VariantProps<typeof badgeVariants>;
14
+ export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {
15
+ /**
16
+ * バッジのサイズ
17
+ * en: Size of the badge
18
+ */
19
+ size?: BadgeVariants["size"];
20
+ /**
21
+ * バッジのバリエーション
22
+ * en: Variation of the badge
23
+ */
24
+ variant?: BadgeVariants["variant"];
25
+ /**
26
+ * 数字表示するかどうか
27
+ * en: Whether to display numbers
28
+ */
29
+ isNumberVisible?: boolean;
30
+ /**
31
+ * 隙間を設けるかどうか
32
+ * en: Whether to add gaps
33
+ */
34
+ isGapped?: boolean;
35
+ }
36
+ /**
37
+ * **概要 / Overview**
38
+ *
39
+ * - バッジは特定の要素に対して通知の数やタスクの数などの数値情報を付与するために使用するコンポーネントです。
40
+ * - en: The Badge component is used to attach numerical information such as notification counts or task counts to specific elements.
41
+ *
42
+ * **アンチパターン / Anti-patterns**
43
+ *
44
+ * - ステータス表示や分類ラベルには `Badge` を使わず、`Tag` を使ってください。
45
+ * en: Do not use `Badge` for status display or category labels. Use `Tag` instead.
46
+ *
47
+ * ```tsx
48
+ * // ✅ Correct
49
+ * <>
50
+ * <Badge>3</Badge>
51
+ * <Tag status="warning" variant="outline">未紐付け</Tag>
52
+ * </>
53
+ *
54
+ * // ❌ Wrong - ステータスラベルに Badge を使わない
55
+ * <Badge>未紐付け</Badge>
56
+ * ```
57
+
58
+ * **使用例 / Usage Example**
59
+ *
60
+ * ```tsx
61
+ * <Badge size="md" variant="normal">5</Badge>
62
+ * ```
63
+ *
64
+ * @param {BadgeProps} props
65
+ */
66
+ declare function Badge({ className, isNumberVisible, size, variant, isGapped, children, role, ...props }: BadgeProps): import("react/jsx-runtime").JSX.Element;
67
+ export { Badge, badgeVariants };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import figma from "@figma/code-connect";
3
+ import { Badge } from "./index.js";
4
+ /**
5
+ * -- This file was auto-generated by Code Connect --
6
+ * `props` includes a mapping from your code props to Figma properties.
7
+ * You should check this is correct, and update the `example` function
8
+ * to return the code example you'd like to see in Figma
9
+ */
10
+ figma.connect(Badge, "https://www.figma.com/design/7alBZXZf65YgcII41TWT0r/Sparkle-Design?node-id=1274%3A1622", {
11
+ props: {
12
+ // These props were automatically mapped based on your linked code:
13
+ size: figma.enum("size", {
14
+ xs: "xs",
15
+ sm: "sm",
16
+ md: "md",
17
+ lg: "lg",
18
+ }),
19
+ variant: figma.enum("variant", {
20
+ normal: "normal",
21
+ emphasis: "emphasis",
22
+ }),
23
+ isGapped: figma.boolean("isGapped"),
24
+ // No matching props could be found for these Figma properties:
25
+ number: figma.string("number"),
26
+ },
27
+ example: props => (_jsx(Badge, { size: props.size, variant: props.variant, isGapped: props.isGapped, children: props.number })),
28
+ });
@@ -0,0 +1,129 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { cva } from "class-variance-authority";
14
+ import { cn } from "../../../lib/utils.js";
15
+ const badgeVariants = cva("inline-flex items-center text-white text-center justify-center rounded-full transition-colors focus:outline-hidden focus:ring-2 focus:ring-[var(--color-ring-normal)] focus:ring-offset-2", {
16
+ variants: {
17
+ variant: {
18
+ normal: "bg-info-500",
19
+ emphasis: "bg-negative-500",
20
+ },
21
+ isNumberVisible: {
22
+ true: "",
23
+ false: "",
24
+ },
25
+ size: {
26
+ xs: "w-2 h-2 min-w-2",
27
+ sm: "w-4 h-4 min-w-4",
28
+ md: "min-w-6 py-0.5 px-1.5 character-1-bold-mono",
29
+ lg: "min-w-8 py-1 px-1.5 character-3-bold-mono",
30
+ },
31
+ isGapped: {
32
+ true: "",
33
+ false: "",
34
+ },
35
+ },
36
+ compoundVariants: [
37
+ // isGappedのボーダー設定
38
+ {
39
+ isGapped: true,
40
+ size: "xs",
41
+ class: "outline-white outline-2",
42
+ },
43
+ {
44
+ isGapped: true,
45
+ size: "sm",
46
+ class: "outline-white outline-4",
47
+ },
48
+ {
49
+ isGapped: true,
50
+ size: "md",
51
+ class: "outline-white outline-4",
52
+ },
53
+ {
54
+ isGapped: true,
55
+ size: "lg",
56
+ class: "outline-white outline-4",
57
+ },
58
+ // 数字がない場合はheightを指定
59
+ {
60
+ isNumberVisible: false,
61
+ size: "md",
62
+ class: "h-6",
63
+ },
64
+ {
65
+ isNumberVisible: false,
66
+ size: "lg",
67
+ class: "h-8",
68
+ },
69
+ ],
70
+ defaultVariants: {
71
+ isNumberVisible: true,
72
+ size: "md",
73
+ variant: "normal",
74
+ isGapped: false,
75
+ },
76
+ });
77
+ /**
78
+ * **概要 / Overview**
79
+ *
80
+ * - バッジは特定の要素に対して通知の数やタスクの数などの数値情報を付与するために使用するコンポーネントです。
81
+ * - en: The Badge component is used to attach numerical information such as notification counts or task counts to specific elements.
82
+ *
83
+ * **アンチパターン / Anti-patterns**
84
+ *
85
+ * - ステータス表示や分類ラベルには `Badge` を使わず、`Tag` を使ってください。
86
+ * en: Do not use `Badge` for status display or category labels. Use `Tag` instead.
87
+ *
88
+ * ```tsx
89
+ * // ✅ Correct
90
+ * <>
91
+ * <Badge>3</Badge>
92
+ * <Tag status="warning" variant="outline">未紐付け</Tag>
93
+ * </>
94
+ *
95
+ * // ❌ Wrong - ステータスラベルに Badge を使わない
96
+ * <Badge>未紐付け</Badge>
97
+ * ```
98
+
99
+ * **使用例 / Usage Example**
100
+ *
101
+ * ```tsx
102
+ * <Badge size="md" variant="normal">5</Badge>
103
+ * ```
104
+ *
105
+ * @param {BadgeProps} props
106
+ */
107
+ function Badge(_a) {
108
+ var { className, isNumberVisible = true, size, variant = "normal", isGapped = false, children, role = "status" } = _a, props = __rest(_a, ["className", "isNumberVisible", "size", "variant", "isGapped", "children", "role"]);
109
+ // sm以下のサイズの場合は、文字を非表示にする
110
+ // en: Hide text for sizes sm and below
111
+ if (size === "sm" || size === "xs") {
112
+ isNumberVisible = false;
113
+ }
114
+ // childrenがない場合はisNumberVisibleがfalseの扱いにする
115
+ // en: Treat as isNumberVisible=false when children is absent
116
+ if (!children) {
117
+ isNumberVisible = false;
118
+ }
119
+ // 視覚的テキストが非表示の場合、aria-label が必要(WCAG 1.1.1)
120
+ // en: When visible text is hidden, aria-label is required (WCAG 1.1.1)
121
+ if (process.env.NODE_ENV !== "production") {
122
+ if (!isNumberVisible && !props["aria-label"] && !props["aria-labelledby"]) {
123
+ console.warn("[Badge] 視覚的テキストが非表示の場合は aria-label を指定してください(WCAG 1.1.1)。" +
124
+ " / When visible text is hidden, please provide aria-label (WCAG 1.1.1).");
125
+ }
126
+ }
127
+ return (_jsx("div", Object.assign({ role: role, className: cn(badgeVariants({ isNumberVisible, size, variant, isGapped }), className) }, props, { children: isNumberVisible && children })));
128
+ }
129
+ export { Badge, badgeVariants };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Copyright 2026 Goodpatch Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import * as React from "react";
6
+ import { Link } from "@/components/ui/link";
7
+ /**
8
+ * **概要 / Overview**
9
+ *
10
+ * - パンくずはユーザーが現在のページ階層を理解し、親の階層へ戻るためのナビゲーションとして機能するコンポーネントです。
11
+ * - en: The Breadcrumb component helps users understand the current page hierarchy and navigate back to parent levels.
12
+ *
13
+ * **使用例 / Usage Example**
14
+ *
15
+ * ```tsx
16
+ * <Breadcrumb>
17
+ * <BreadcrumbList>
18
+ * <BreadcrumbItem>
19
+ * <BreadcrumbLink href="/">Home</BreadcrumbLink>
20
+ * </BreadcrumbItem>
21
+ * <BreadcrumbSeparator />
22
+ * <BreadcrumbItem>
23
+ * <BreadcrumbLink href="/">Link</BreadcrumbLink>
24
+ * </BreadcrumbItem>
25
+ * <BreadcrumbSeparator />
26
+ * <BreadcrumbItem>
27
+ * <BreadcrumbPage>Current Page</BreadcrumbPage>
28
+ * </BreadcrumbItem>
29
+ * </BreadcrumbList>
30
+ * </Breadcrumb>
31
+ * ```
32
+ *
33
+ * @param {BreadcrumbProps} props
34
+ */
35
+ export declare function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">): import("react/jsx-runtime").JSX.Element;
36
+ /**
37
+ * パンくずリスト(ol)
38
+ * en: Breadcrumb list (ol)
39
+ *
40
+ * @param {React.ComponentProps<"ol">} props
41
+ */
42
+ export declare function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">): import("react/jsx-runtime").JSX.Element;
43
+ /**
44
+ * パンくずアイテム(li)
45
+ * en: Breadcrumb item (li)
46
+ *
47
+ * @param {React.ComponentProps<"li">} props
48
+ */
49
+ export declare function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">): import("react/jsx-runtime").JSX.Element;
50
+ /**
51
+ * パンくずリンク
52
+ * en: Breadcrumb link
53
+ *
54
+ * @param {React.ComponentProps<typeof Link>} props
55
+ */
56
+ export declare function BreadcrumbLink({ className, ...props }: React.ComponentProps<typeof Link>): import("react/jsx-runtime").JSX.Element;
57
+ /**
58
+ * パンくずの区切り(/など)
59
+ * en: Breadcrumb separator (e.g. /)
60
+ *
61
+ * @param {React.ComponentProps<"span">} props
62
+ */
63
+ export declare function BreadcrumbSeparator({ className, children, ...props }: React.ComponentProps<"span">): import("react/jsx-runtime").JSX.Element;
64
+ /**
65
+ * 現在ページ表示用
66
+ * en: Current page label (not a link)
67
+ *
68
+ * @param {React.ComponentProps<"span">} props
69
+ */
70
+ export declare function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import figma from "@figma/code-connect";
3
+ import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from "./index.js";
4
+ /**
5
+ * -- This file was auto-generated by Code Connect --
6
+ * None of your props could be automatically mapped to Figma properties.
7
+ * You should update the `props` object to include a mapping from your
8
+ * code props to Figma properties, and update the `example` function to
9
+ * return the code example you'd like to see in Figma
10
+ */
11
+ figma.connect(Breadcrumb, "https://www.figma.com/design/7alBZXZf65YgcII41TWT0r/Sparkle-Design?node-id=2755%3A25149", {
12
+ props: {},
13
+ example: props => (_jsx(Breadcrumb, { children: _jsxs(BreadcrumbList, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "/", children: "Home" }) }), _jsx(BreadcrumbSeparator, { children: "/" }), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: "Current Page" }) })] }) })),
14
+ });
15
+ /**
16
+ * -- This file was auto-generated by Code Connect --
17
+ * None of your props could be automatically mapped to Figma properties.
18
+ * You should update the `props` object to include a mapping from your
19
+ * code props to Figma properties, and update the `example` function to
20
+ * return the code example you'd like to see in Figma
21
+ */
22
+ figma.connect(BreadcrumbItem, "https://www.figma.com/design/7alBZXZf65YgcII41TWT0r/Sparkle-Design?node-id=252%3A8944", {
23
+ props: {
24
+ // No matching props could be found for these Figma properties:
25
+ // "isCurrent": figma.boolean('isCurrent')
26
+ },
27
+ example: props => (_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: "Current Page" }) })),
28
+ });