@cakejp/design-system 0.15.0 → 0.16.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.
@@ -1,5 +1,6 @@
1
1
  import "./index.css";
2
2
  export { cn } from "./lib/utils";
3
+ export { FOCUS_RING, FOCUS_RING_WITHIN, FOCUS_RING_INSET } from "./lib/focus-ring";
3
4
  export { toast } from "sonner";
4
5
  export { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./components/foundations/accordion";
5
6
  export { Alert, AlertDescription, AlertTitle } from "./components/foundations/alert";
@@ -0,0 +1,42 @@
1
+ /**
2
+ * DS 正規のフォーカス可視化(フォーカスリング)。
3
+ *
4
+ * 入力系・操作系のコンポーネントは **必ず**このどちらかを適用する。
5
+ * 意匠は `--Focus-High-Emphasis`(緑)の 3px リング + 同色ボーダーで統一され、
6
+ * Button / Input / Select / Checkbox / RadioGroup / Switch / Slider /
7
+ * NumberInput / SearchBar / FileInput すべてが同じ見え方になる。
8
+ *
9
+ * ## hover と focus の優先順位
10
+ * Tailwind v4 の variant 出力順は `focus-within` → `hover` → `focus` →
11
+ * `focus-visible` の並びで固定されている。つまり
12
+ *
13
+ * - `focus-visible:*` は同一プロパティの `hover:*` を**常に上書きする**(後勝ち)
14
+ * - `focus-within:*` は `hover:*` に**負ける**
15
+ *
16
+ * そのため {@link FOCUS_RING_WITHIN} を使う(=ラッパーが枠を描く)
17
+ * コンポーネントでは、同じプロパティを触る hover を
18
+ * `hover:not-focus-within:*` と書いてフォーカス中は hover を抑制すること。
19
+ * この順序は `__tests__/focus-visible-contract.test.ts` で固定している。
20
+ */
21
+ /**
22
+ * 要素自身がフォーカスを受け取るコントロール用(input / button / trigger 等)。
23
+ *
24
+ * @example
25
+ * <input className={cn("border ...", FOCUS_RING)} />
26
+ */
27
+ export declare const FOCUS_RING = "focus-visible:border-[var(--Focus-High-Emphasis)] focus-visible:ring-[3px] focus-visible:ring-[var(--Focus-High-Emphasis)]/50";
28
+ /**
29
+ * ラッパーが枠を描き、内側の要素がフォーカスを受け取る合成コントロール用
30
+ * (SearchBar の枠、FileInput の label 等)。
31
+ *
32
+ * hover で同じプロパティを変える場合は `hover:not-focus-within:*` で書くこと。
33
+ *
34
+ * @example
35
+ * <div className={cn("border hover:not-focus-within:border-x", FOCUS_RING_WITHIN)}>
36
+ */
37
+ export declare const FOCUS_RING_WITHIN = "focus-within:border-[var(--Focus-High-Emphasis)] focus-within:ring-[3px] focus-within:ring-[var(--Focus-High-Emphasis)]/50";
38
+ /**
39
+ * `overflow-hidden` なコンテナの内側にある要素用(リングが外にはみ出すと
40
+ * 切り取られてしまうため内側に描く)。SearchBar の検索ボタン等。
41
+ */
42
+ export declare const FOCUS_RING_INSET = "focus-visible:ring-[3px] focus-visible:ring-inset focus-visible:ring-[var(--Focus-High-Emphasis)]/50";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cakejp/design-system",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "description": "Cake.jp Design System — UI コンポーネント・カラートークン・タイポグラフィ",
6
6
  "license": "UNLICENSED",
@@ -136,7 +136,7 @@
136
136
  | OrderSection | `@/components/ec/order-section` | — | 入力済み, 未入力, エラー, 購入確認画面 |
137
137
  | OrderSummary | `@/components/ec/order-summary` | — | カート合計, チェックアウト合計, クーポン適用時, 合計のみ |
138
138
  | PaymentMethodDisplay, CreditCardIcon | `@/components/ec/payment-method` | — | 登録済み, 未登録, 期限切れ, 対応ブランド一覧, カードブランドアイコン |
139
- | ProductCard, BookmarkRibbonIcon | `@/components/ec/product-card` | — | ストロベリーショートケーキ 5号(15cm), お気に入りボタン付き, タグ付き, ランキング, 配送日表示, 規格・仕様キャプション, 横向き, グリッドレイアウト(標準コンテナクエリ), 割引バッジ, カートボタン付き, ショップ名リンク付き, 最小構成 |
139
+ | ProductCard, BookmarkRibbonIcon | `@/components/ec/product-card` | — | ストロベリーショートケーキ 5号(15cm), お気に入りボタン付き, タグ付き, ランキング, 配送日表示, 規格・仕様キャプション, 横向き, グリッドレイアウト(標準コンテナクエリ), 割引バッジ, カートボタン付き, ショップ名リンク付き, 最小構成, 回帰: 列はみ出し / 価格の縦位置揃え (#210) |
140
140
  | ProductCarousel | `@/components/ec/product-carousel` | — | Default, WithRanking, LargeCards, WithSectionImage, WithDescription, WithCartButton |
141
141
  | ProductCTA | `@/components/ec/product-cta` | — | カートに追加, タイムセール中, 完売, 全バリエーション |
142
142
  | ProductDetailBar | `@/components/ec/product-detail-bar` | — | — |
@@ -480,3 +480,18 @@
480
480
  height: max(100%, 2.75rem);
481
481
  transform: translate(-50%, -50%);
482
482
  }
483
+
484
+ /* --- Base layer(ルート地色 / #208) ---
485
+ * Tailwind を使わない consumer でも、html を透明のままにしない。
486
+ * 透明だとダークモード設定のブラウザでキャンバス既定色(黒)が透け、
487
+ * ページ全体が真っ黒に見える。preset.css の @layer base と同じ宣言。
488
+ * 背景を body ではなく html にだけ置く理由も preset.css 側のコメント参照。
489
+ * @layer に入れているのは、consumer 側の非レイヤー CSS が常に勝つようにするため。 */
490
+ @layer base {
491
+ html {
492
+ background-color: var(--background);
493
+ }
494
+ body {
495
+ color: var(--foreground);
496
+ }
497
+ }
package/src/preset.css CHANGED
@@ -374,7 +374,21 @@
374
374
  * {
375
375
  @apply border-border outline-ring/50;
376
376
  }
377
+ /* ルート地色(#208)
378
+ * html を透明のままにすると、ダークモード設定のブラウザではキャンバス既定色(黒)が
379
+ * 透けてページ全体が真っ黒になる。面トークンで明示的に確定させる。
380
+ *
381
+ * 背景は html にだけ置き、body には置かない。ルート要素に背景があれば
382
+ * キャンバスへはそこから伝播するので body で塗り直す必要が無く、
383
+ * ダークの面トークン(--Surface-Primary が半透明の黒)を二重に重ねて
384
+ * body の高さで濃さが変わる継ぎ目が出るのを避けられる。
385
+ *
386
+ * @apply ではなく素の CSS で書くのは、Tailwind を通さない経路
387
+ * (preset-standalone.css)と同じ宣言を両ファイルで保てるようにするため。 */
388
+ html {
389
+ background-color: var(--background);
390
+ }
377
391
  body {
378
- @apply bg-background text-foreground;
392
+ color: var(--foreground);
379
393
  }
380
394
  }