@insession/design-system 1.3.1 → 1.5.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/package.json CHANGED
@@ -1,27 +1,34 @@
1
1
  {
2
2
  "name": "@insession/design-system",
3
- "version": "1.3.1",
3
+ "version": "1.5.0",
4
4
  "description": "InSession / loophub 共通のデザインシステム。純粋 leaf UI プリミティブ + デザイントークン(アプリ依存なし。i18n 等は props で注入する)",
5
- "license": "UNLICENSED",
5
+ "license": "MIT",
6
6
  "type": "module",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/insession-space/design-system.git"
10
10
  },
11
- "//": "ビルド成果物(dist)を配布する。theme.css はパッケージ直下に置いたまま ./theme.css として公開する(tsup は CSS を処理しないため)。react はホストと同一インスタンスを使うため peerDependency。",
11
+ "//": "ビルド成果物(dist)を配布する。CSS はパッケージ直下に置いたまま公開する(tsup は CSS を処理しないため)。react はホストと同一インスタンスを使うため peerDependency。",
12
+ "//exports": "CSS の入口は3つ。./styles.css が既定(トークン + 部品 CSS + このパッケージが使うユーティリティを全部含むプリビルド。消費側に Tailwind は不要)。./theme.css はトークンだけ(消費側が Tailwind で自分のマークアップに DS トークンを使いたい場合の @theme 統合用)。./components.css は部品 CSS だけ(Tailwind + @source 方式を続ける消費側が、ユーティリティで表現できない部品 CSS だけを足すため)。",
12
13
  "exports": {
13
14
  ".": {
14
15
  "types": "./dist/index.d.ts",
15
16
  "import": "./dist/index.js"
16
17
  },
17
- "./theme.css": "./theme.css"
18
+ "./styles.css": "./dist/styles.css",
19
+ "./theme.css": "./theme.css",
20
+ "./base.css": "./base.css",
21
+ "./components.css": "./components.css"
18
22
  },
19
23
  "module": "./dist/index.js",
20
24
  "types": "./dist/index.d.ts",
21
25
  "files": [
22
26
  "dist",
23
27
  "theme.css",
24
- "CHANGELOG.md"
28
+ "base.css",
29
+ "components.css",
30
+ "CHANGELOG.md",
31
+ "LICENSE"
25
32
  ],
26
33
  "sideEffects": [
27
34
  "*.css"
@@ -31,6 +38,7 @@
31
38
  "access": "public",
32
39
  "registry": "https://registry.npmjs.org"
33
40
  },
41
+ "//scripts": "build は js/d.ts(tsup) と配布 CSS(Tailwind CLI) の2本立て。build:css は minify しない — dist を @source で走査する従来方式の消費側がまだ居るため、クラス名の文字列リテラルを壊さない。check:styles は「DOM に出るのに CSS が無い」欠損を検出する回帰ネット。",
34
42
  "peerDependencies": {
35
43
  "react": "^19.0.0",
36
44
  "react-dom": "^19.0.0"
@@ -41,6 +49,7 @@
41
49
  "@fontsource/jetbrains-mono": "^5.2.8",
42
50
  "@storybook/addon-docs": "^10.5.0",
43
51
  "@storybook/react-vite": "^10.5.0",
52
+ "@tailwindcss/cli": "^4.3.3",
44
53
  "@tailwindcss/vite": "^4.3.2",
45
54
  "@types/node": "^22.10.0",
46
55
  "@types/react": "^19.2.0",
@@ -57,12 +66,15 @@
57
66
  "node": ">=22.18"
58
67
  },
59
68
  "scripts": {
60
- "build": "tsup",
69
+ "build": "pnpm build:js && pnpm build:css",
70
+ "build:js": "tsup",
71
+ "build:css": "tailwindcss -i styles.src.css -o dist/styles.css",
61
72
  "typecheck": "tsc --noEmit -p tsconfig.json",
62
73
  "check": "biome check .",
74
+ "check:styles": "node scripts/check-styles.mjs",
63
75
  "format": "biome format --write .",
64
- "storybook": "storybook dev -p 6006",
65
- "build-storybook": "storybook build -o storybook-static",
76
+ "storybook": "pnpm build:css && storybook dev -p 6006",
77
+ "build-storybook": "pnpm build:css && storybook build -o storybook-static",
66
78
  "changeset": "changeset",
67
79
  "changeset:version": "changeset version"
68
80
  }
package/theme.css CHANGED
@@ -6,23 +6,33 @@
6
6
  * ── 消費側アプリのセットアップ ──────────────────────────────
7
7
  * @import "tailwindcss";
8
8
  * @import "@insession/design-system/theme.css";
9
- * @source "../../node_modules/@insession/design-system/dist";
9
+ * @source "../node_modules/@insession/design-system/dist";
10
10
  *
11
11
  * ⚠ `@source` は必須。これが無いとコンポーネント内のクラス名から Tailwind
12
- * ユーティリティが生成されず、**ビルドは通るのにスタイルだけが静かに消える**。
13
- * パスは各アプリの style.css から node_modules への相対パスに合わせること。
14
- * pnpm では node_modules 配下が symlink になるため、初回セットアップ時は
15
- * 実際にビルドして見た目を目視確認すること。
12
+ * ユーティリティが生成されず、**ビルドは通るのにスタイルが部分的に欠ける**
13
+ * (エラーもワーニングも出ない。Vite のモジュールグラフ経由で一部のクラスは
14
+ * 拾われるので「全崩れ」にならず、一見それらしく描画されるため気づきにくい。
15
+ * 実測では CSS の約4割が欠けた状態でビルドが緑になった)。
16
16
  *
17
- * ── ライトテーマについて ────────────────────────────────
18
- * このファイルはダーク単一トーンで、[data-theme] のライトテーマオーバーレイを含まない。
19
- * ライト/ダークを切り替えるアプリは自分側で [data-theme] オーバーレイを持つ。
17
+ * pnpm workspace では **リポジトリルートの node_modules を指してはいけない**。
18
+ * pnpm は依存をそれを宣言したパッケージ自身の node_modules にリンクし、ルートには
19
+ * 置かない。apps/<app>/src/style.css からの正しいパスは `../node_modules/...`
20
+ * (= apps/<app>/node_modules/...)で、ルートを指すと空振りする。
20
21
  *
21
- * ── insession-app との関係(歴史的経緯) ─────────────────────
22
- * insession-app の apps/web は巨大な legacy CSS と共存させるため、同じトークンを
23
- * src/style.css にインラインで持ち、このファイルを import しない。両者の値は
24
- * 揃えて保守する(insession-app 側が増やしたトークンのうち、このパッケージの
25
- * コンポーネントが参照しないものはここに持ち込まない)。
22
+ * CI でビルド成果物を検査すること。生成CSSに DS 由来のユーティリティ
23
+ * (アプリのソースには書かれていないもの。例 bg-accent / rounded-card)が
24
+ * 入っているかを確かめれば機械的に防げる。
25
+ *
26
+ * ── ライト/ダークについて ───────────────────────────────
27
+ * **ダークが既定**で、下の @theme の値がそのままダークのトーン。ライトは
28
+ * `<html data-theme="light">` のときだけ効くオーバーレイ(ファイル末尾)で与える。
29
+ * したがって:
30
+ * - ダーク固定のプロダクトは何もしなくてよい(オーバーレイは不活性)
31
+ * - ライト/ダークを切り替えるプロダクトは html の data-theme を書き換えるだけ
32
+ * - `data-theme="dark"` と「属性なし」はどちらもダークになる(:root の @theme 値)
33
+ *
34
+ * ⚠ ダーク側の再宣言は**置かない**。@theme の値が既定として効くので、同じ値を
35
+ * `[data-theme="dark"]` にも書くと保守箇所が二重になるだけで、得るものが無い。
26
36
  */
27
37
 
28
38
  @theme {
@@ -202,6 +212,9 @@
202
212
  --radius-card: 16px;
203
213
  --radius-panel: 16px;
204
214
  --radius-pill: 999px;
215
+ /* ボトムシート上端の角丸。BottomSheet の .bottom-sheet が参照する(components.css)。
216
+ insession-app 側の同名トークンと値を揃えて保守する。 */
217
+ --radius-sheet: 22px;
205
218
 
206
219
  /* グロー(旧 #457 ブランドの hover 発光)は新 DS で廃止(#463)。新 DS の hover は「ふわっと光る」
207
220
  ではなく surface-hover への面変化 / filled は brightness(.93) / カード等は translateY(-2px) の
@@ -316,10 +329,96 @@
316
329
  /* エレベーションの実値(#950)。上の @theme 内コメントのとおり、Tailwind v4 が --shadow-* を
317
330
  ビルド時にリテラル展開するため実値はここ(@theme の外・unlayered な素の :root)に置き、
318
331
  @theme 側は var() 参照だけを持つ(insession-app の apps/web/src/style.css の #867 対応と同じ形)。
319
- ダーク単一値(このパッケージはダーク前提。ファイル冒頭コメント参照)。値は元 @theme に
320
- 書かれていたものをそのまま移設しただけで変更なし。 */
332
+ ここはダーク(既定)値。ライト値は下のオーバーレイで上書きする。 */
321
333
  :root {
322
334
  --elev-soft: 0 2px 6px -2px rgba(0, 0, 0, 0.5);
323
335
  --elev-popover: 0 16px 30px -16px rgba(0, 0, 0, 0.7);
324
336
  --elev-overlay: 0 26px 64px -32px rgba(0, 0, 0, 0.85);
325
337
  }
338
+
339
+ /* ── ライトテーマのオーバーレイ ─────────────────────────────
340
+ *
341
+ * `<html data-theme="light">` のときだけ効く。属性が無いか "dark" のときは
342
+ * 上の @theme / :root の値(= ダーク)がそのまま使われるので、**ダーク固定の
343
+ * プロダクトはこのブロックを意識しなくてよい**(不活性なまま)。
344
+ *
345
+ * ── なぜセレクタで上書きできるのか ────────────────────────
346
+ * @theme の出力は静的な CSS 変数宣言に過ぎず、生成後は普通の CSS 変数として
347
+ * 通常の cascade に従う。加えて:
348
+ * - このブロックは **unlayered**(どの @layer にも属さない)ので、@theme の出力が
349
+ * 乗る theme レイヤーより必ず強い
350
+ * - セレクタの詳細度も `:root[data-theme="light"]`(0,2,0) > `:root`(0,1,0)
351
+ * どちらの理由でも勝つので、消費側の取り込み方(レイヤー付き import か否か)に
352
+ * 依らず効く。
353
+ *
354
+ * ── 上書きしなくてよいトークン ──────────────────────────
355
+ * ティント面(--color-tint-*)とセマンティック面(--color-*-surface / *-surface-strong)は
356
+ * `color-mix(… , var(--color-bg))` の合成で定義してあるので、ここで --color-bg が
357
+ * 変わればそのまま追従する。リンク色(--color-link / --color-link-hover)と
358
+ * --color-accent も --color-mint / --color-mint-soft の var() 参照なので追従する。
359
+ * したがってここに書くのは**参照元の生値だけ**。
360
+ *
361
+ * ── 値の出自 ──────────────────────────────────────
362
+ * insession-app(apps/web)と loophub(apps/web / apps/lp)が各自の style.css に持って
363
+ * いた `[data-theme="light"]` オーバーレイを、ここへ一本化したもの。移設前に3者の値を
364
+ * 突き合わせ、**loophub の17トークンは insession-app の30トークンの部分集合で値も完全一致**
365
+ * であることを確認している。insession-app 固有で DS が持たない3つ
366
+ * (--color-visibility-public / -followers / -community)は移していない。
367
+ *
368
+ * ⚠ ダーク側(`[data-theme="dark"]`)の再宣言は置かない。@theme の値が既定として効くため
369
+ * 同じ値の二重管理になるだけ。移設元にはあったが、意図的に持ち込んでいない。
370
+ *
371
+ * ⚠ セレクタは `:root[...]` なので html 要素だけに効く。要素単位で部分的にテーマを
372
+ * 切り替えたいプロダクトは、自分側で `[data-theme="light"]` 版を足すこと。
373
+ */
374
+ :root[data-theme="light"] {
375
+ /* 背景面(奥 → 手前)。ダークの3段ランプに対応する明るいトーン。 */
376
+ --color-bg: #e9e9e6;
377
+ --color-bg-elevated: #f4f1e9;
378
+ --color-surface: #ffffff;
379
+ --color-surface-2: rgba(244, 241, 233, 0.96);
380
+ --color-surface-3: #ebe7dc;
381
+ --color-surface-hover: #f1ede3;
382
+
383
+ /* 境界。 */
384
+ --color-border: #e2ded3;
385
+ --color-border-strong: #d6d2c6;
386
+
387
+ /* テキスト階層。ダークと明暗を反転させる。 */
388
+ --color-text: #17160f;
389
+ --color-text-dim: #5c5b52;
390
+ --color-text-faint: #a3a197;
391
+
392
+ /* 中立塗り(Primary ボタン等)。ダークでは明色 + 暗い文字、ライトでは逆になる。 */
393
+ --color-fill: #17160f;
394
+ --color-on-fill: #f1eee6;
395
+
396
+ /* ブランドパレット。白背景でのコントラスト確保のため、ダークより濃い値にする。
397
+ mint-soft はダークでは「淡いコーラル」だが、ライトでは白地に載るため
398
+ 逆に濃いコーラルになる(テキスト/リンクの静止色に使うため)。 */
399
+ --color-mint: #ff5a36;
400
+ --color-mint-soft: #c8431f;
401
+ --color-cyan: #3b6fe0;
402
+ --color-violet: #1fa463;
403
+
404
+ /* セマンティック(状態表現)の地の色。白背景での可読性のため少し濃くする。
405
+ 対応する *-surface / *-border はこれらの var() 合成なので追従する。 */
406
+ --color-success: #1fa463;
407
+ --color-warning: #e0930f;
408
+ --color-danger: #d8433d;
409
+ --color-info: #3b6fe0;
410
+
411
+ /* 影の色。ダークは黒だが、ライトで黒を使うと濁るのでウォームグレーにする。 */
412
+ --color-shadow: #b4afa0;
413
+
414
+ /* スナックバー。面(--color-snackbar-surface)は**ライトでも暗いまま**にする
415
+ (操作フィードバックは前面に浮く別レイヤーという扱いで、意図的にテーマへ追従させない)。
416
+ 文字色系だけライトの danger に合わせる。 */
417
+ --color-snackbar-danger: var(--color-danger);
418
+ --color-snackbar-danger-border: color-mix(in srgb, var(--color-danger) 30%, transparent);
419
+
420
+ /* エレベーション。ライトでは黒の落ち影が強すぎるため、青みを含むグレーで薄く出す。 */
421
+ --elev-soft: 0 2px 6px -2px rgba(20, 20, 26, 0.12);
422
+ --elev-popover: 0 12px 24px -14px rgba(20, 20, 26, 0.4);
423
+ --elev-overlay: 0 20px 46px -28px rgba(20, 20, 26, 0.42);
424
+ }