Repository navigation
Releases
v1.1.0
Highlights
--font-sansのブランドフォントスタック ("Hanken Grotesk", "LINE Seed JP", …) がdist/schatten.cssの live default になりました。従来はentry.cssの unlayered 宣言が registrar を常に上書きしており、ブランドフォントが実質 dead default だった問題を解消 (#501)。.st-spinner__labelを追加 — Spinner の視覚的に隠れたアクセシブルラベル用クラス。Tailwind-free な dist ではsr-onlyが存在せず、ラベルが可視テキストとして見えてしまう問題を修正 (#513)。- disabled 時の装飾アイコン(Input icon / Select chevron / DropdownMenu shortcut・chevron)が muted のまま残り、隣接テキストより濃く見えてしまう問題を修正 (#535)。
- Switch の
disabled + checkedでチェックアイコンがトラックに埋もれて見えなくなる問題を修正 (#529)。 sonner2.0.7 → 2.0.8 ほか@radix-ui/*/react/react-domを更新。視覚契約への影響なし — VRT 411 件・a11y 268 件がゼロ差分で通過 (#520)。
What's Changed
Minor Changes
- CSS API:
--font-sansのブランドスタックが live default に。変数名・上書き recipe は不変 — named slot の既定値のみ変更 (#501) - CSS API:
.st-spinner__labelを追加 (#513)
Patch Changes
- fix(lv1): disabled 時の装飾アイコンの色を明示的に塗り直し (
--color-foreground-disabled)。Input の text affix は WCAG 1.4.3 の都合で対象外 (#535) - chore(deps):
sonner2.0.7 → 2.0.8、@radix-ui/*/react/react-dom更新。公開 API 不変 (#520) - fix(lv1): Switch の disabled + checked チェックアイコンの可視性を修正。Checkbox と同じ
currentColoridiom に統一 (#529)
Full Changelog: v1.0.0...v1.1.0
v1.0.0 — Schatten 1.0 (API stability 発効)
Schatten の最初の stable リリースです。React コンポーネント層と、Tailwind もビルドステップも不要な framework-agnostic な .st-* CSS class API の二層構成が、このリリースから semver 契約下に入ります。
API stability commitment
v1.0.0 から、公開 surface — React props / 公開 TS 型 / .st-* クラス名 / 公開 CSS 変数(四層モデル)/ CVA 出力文字列 / multi-entry exports map(ESM-only)/ theme contract / FOUC snippet bytes(CSP hash)— の破壊的変更は major リリースのみで行い、migration guide と 1 minor 以上の @deprecated 期間を伴います。何が public かの正典は api-stability.md、機械可読の一覧は @yasmro/schatten/schatten.manifest.json です。
Highlights
- 二層アーキテクチャ:
import '@yasmro/schatten/schatten.css'1 本で.st-*class API(252 classes / 8 state 属性 / 127 CSS 変数)。React 層(25 lv1 components)はオプション - ESM-only(#479): dual-package hazard を構造的に排除。Vite / Next.js 13+ / Remix / Astro / Node ≥18 ESM をサポート
- Mode × Special 二軸テーマ: light/dark × 季節 8 パレット。
data-theme属性 1 つで JS 再レンダリングなしに全体リテーマ - a11y: 全 25 コンポーネントに axe-core(WCAG 2.1 A/AA)blocking gate + role/name/keyboard の a11y contract
- SSR/CSP フレンドリー: FOUC 対策スニペットは SHA-256 pin 可能(
sha256-YKmfjVUKTYOL4QdVTkV/AUzMrHhhfPw//OthidDmEEE=)
Breaking changes
v0.x からの移行は 0.x → 1.0 migration guide を参照してください(ESM-only 化を含む全 Breaking の Before → After 一覧)。
Install
npm i @yasmro/schattenCSS のみの利用(React 不要):
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@yasmro/schatten@1.0.0/dist/schatten.css" />Full changelog: CHANGELOG.md
v0.15.0
Highlights
v1.0 RC 準備マイルストーン。公開 surface(.st-* 252 クラス / state 属性 8 / CSS 変数 127)は完全不変で、内部基盤とドキュメントを 1.0 に向けて仕上げた。
- 脱 Tailwind(dist) —
dist/schatten.css/dist/css/*.cssを Tailwind v4 CLI から lightningcss に置換。@theme展開はハンドメンテの public registrar(src/styles/public-tokens.css)、preflight はベンダリング。manifest 0 diff・dist VRT 0 diff 検証済み。Tailwind は Storybook(dev)専用に。(#317) - CSS 変数命名 audit 確定 — 命名規約を 4 層モデルに一本化。公開 Tailwind 規約名
--default-font-family/--default-mono-familyを撤去(解決値不変)。公開 CSS 変数 129 → 127。(#231) - Docs 一式 — 0.x → 1.0 Migration guide / ADR-0001〜0010 / AGENTS・CLAUDE・CONTRIBUTING 三点セット / Storybook docs 最終掃引。(#157 / #158 / #159 / #160)
- manifest export 検証ゲート
pnpm check:manifest:exportを追加。(#162) tailwind-merge依存を削除(.st-*のみの出力で no-op だったため)。(#461)
Breaking Changes
なし(公開 surface 不変)。個々の changeset は patch 相当だが、1.0 RC 前の区切りとして minor で 0.15.0 を発番。--default-font-family / --default-mono-family の撤去は解決値・レンダリング不変。
What's Changed
Minor Changes
- v0.15.0 — 1.0 RC 準備の区切り(surface 不変)
Patch Changes
- ADR-0001〜0010 追加(#471)
- CSS 変数命名 audit(#458)
- dist 脱 Tailwind → lightningcss(#454)
- Welcome カード追加 + placeholder 削除(#459)
- Storybook docs 最終掃引(#473)
tailwind-merge削除(#461)- manifest export 検証ゲート(#469)
- Migration guide(#463)
Full Changelog: v0.14.0...v0.15.0
v0.14.0
Highlights
- Radix 型境界 (anti-corruption layer) の確立 — Radix ベース lv1 (Select / Tooltip / Popover / DropdownMenu / Tabs / Radio / Checkbox / Switch / Separator / Avatar) の公開 Props 型から Radix 継承を全廃し、「native 要素の props + curated 再宣言」に移行 (#448)。公開型サーフェスが consumer の lockfile の Radix 解決に依存しなくなり、v1.0 の API 安定契約の前提が整った。
- 区分 C/D コンポーネント (Select / Dialog / Tooltip) に実ブラウザの非スクリーンショット interaction テストを追加 (#450) — jsdom + 静的 VRT では捕捉できない「ブラウザでは壊れている」class の欠陥を CI でブロック。
⚠️ Breaking Changes
Radix 継承の全廃により、Radix が型上公開していた未使用 prop は型エラーになる (pre-1.0 のため minor で出荷):
| Before | After |
|---|---|
Props が ComponentPropsWithoutRef<typeof XPrimitive.Y> を継承 — Radix の全 prop が型上通る |
native 要素の props + curated 再宣言のみ。dir / forceMount / onEscapeKeyDown / onPointerDownOutside / onInteractOutside / collision 系は公開から除外 (実需が出たら additive に再公開) |
<PopoverClose asChild><Button/></PopoverClose> |
<PopoverClose><Button/></PopoverClose> (element child → 内部 asChild、描画結果は同一) |
PopoverAnchor の element child は <div> ラッパ付き |
ラッパが消え child へ直接マージ — data-testid 等の属性は child 側に載る |
TooltipProviderProps = Radix 型の全面 re-export |
delayDuration / skipDelayDuration / disableHoverableContent / children の 4 prop に縮小 |
新規 export: SelectProps / SelectValueProps / SelectItemProps / TooltipProps / PopoverProps / PopoverAnchorProps / PopoverCloseProps / DropdownMenuProps / DropdownMenuSubProps / DropdownMenuRadioGroupProps / DropdownMenuCheckboxItemProps / DropdownMenuRadioItemProps / DropdownMenuSubContentProps / TabsListProps / TabsContentProps
方針の詳細: api-stability.md §Radix type boundary
What's Changed
Minor Changes
- #448: BREAKING: Radix ベース lv1 の公開 Props 型から Radix 継承を全廃 (closes #156)。境界は
radix-type-boundary.test.tsx(drift ガード +@ts-expect-errorpin) と curated props の spread 実装の typecheck で機械的に維持される。
Tests
- #450: 区分 C/D の実ブラウザ interaction テストを Select / Dialog / Tooltip に追加 (closes #447)。
pnpm audit:coverageのinteraction列で presence を機械検査。
Full Changelog: v0.13.0...v0.14.0
v0.13.0
Highlights
- Table (#439) — a semantic, presentational-only / logic-agnostic data table. Ships chrome only (size density,
striped/bordered/hoverable,selected); sort / filter / pagination compose on top via any headless layer (TanStack Table, react-table, your own). - Card (#427, #430) — a compound surface primitive (
CardHeader/CardTitle/CardDescription/CardContent/CardFooter) with afilled(default) /plainbackground variant. - Avatar (#434) — a Radix-backed avatar that falls back to initials when the image is absent or fails to load.
- Skeleton (#426) — a loading placeholder; the shimmer respects
prefers-reduced-motion. - Field
required→aria-required(#440) — Field now propagatesaria-required(announce-only) to the wrapped control, mirroringisError → aria-invalid.
What's Changed
Minor Changes
- Avatar (#434) — flat wrapper over
@radix-ui/react-avatar;src/alt/fallback/size(sm32 /md40 /lg48) /delayMs. CSS API:.st-avatar*, also at@yasmro/schatten/css/avatar. - Card (#427) — compound surface primitive; first consumer of the
--shadow-cardtoken. CSS API:.st-card*, also at@yasmro/schatten/css/card. - Card
variant(#430) —filled(default, value-identical to previous Card) /plain(transparent, border only). CSS API:.st-card--filled/.st-card--plain. - Field
requiredpropagation (#440) —aria-required(announce-only) on Input / Textarea / Select / Checkbox / Switch / RadioGroup via FieldContext. Native / Radix validation unchanged. - Skeleton (#426) — className-driven size/shape;
prefers-reduced-motionaware; decorative (aria-hidden) by default. CSS API:.st-skeleton, also at@yasmro/schatten/css/skeleton. - Table (#439) —
Table/TableHeader/TableBody/TableRow/TableHead/TableCell/TableCaption; presentational-only, all behavioural hooks pass through...props. CSS API:.st-table*, also at@yasmro/schatten/css/table.
Patch Changes
Patterns/Data Tablerecipe (#442) — Storybook recipe composing the presentationalTablewith TanStack Table v8 for sort / filter / pagination. Docs only —@tanstack/react-tableis a devDependency, never shipped as prod / peer.
Full Changelog: v0.12.0...v0.13.0
v0.12.0
Highlights
- 🆕 3 つの新 lv1 コンポーネント — Popover / Tabs / DropdownMenu(いずれも Radix ベースの compound)。
- 🔔 Toast を sonner ベースに刷新 — stacking / swipe / auto-dismiss を Sonner が所有し、
toast.loading()/toast.promise()を追加(#396)。pre-1.0 BREAKING あり(下記)。 🅰️ Text に serif + leading 軸 —family/leadingを追加し、ライブラリ全体に JP/EN cap-height 補正を適用(#400)。- ♿ state token / foreground を WCAG 2.1 AA へ —
emphasisrung 新設で淡背景・白地の色文字を 4.5:1 に、foreground-muted/subtle も AA に(#413 / #412)。
⚠️ Breaking Changes (pre-1.0)
Toast の sonner 移行(#396)で、以下の公開 surface を撤去しました。toast() の signature・ToastInput・ToastVariant / ToastAppearance・.st-toast--{tone/shape} / .st-toast__{icon,content,title,description} は維持されます。
| 区分 | 撤去 | 移行 |
|---|---|---|
| CSS class | .st-toaster / .st-toaster--{6 position} |
位置は <Toaster position> prop(Sonner)に一本化 |
| State 属性 | [data-swipe] |
swipe は Sonner 所有(属性は emit されない) |
| Animation | .st-toast の [data-state] 駆動 enter/exit |
enter/exit は Sonner 所有 |
| Types / hook | useToast() / ToastData |
自前 store を廃止(Sonner の store に一本化) |
追加(additive): toast.loading() / toast.promise() / <Toaster expand visibleToasts> / .st-toast__action / 型 ToastFn ToastPromiseOptions ToastPromiseHandle。依存は @radix-ui/react-toast を削除し sonner@2.0.7(exact pin)を追加。
What's Changed
Minor Changes
- feat(lv1): Popover を追加 (#409)
- feat(lv1): Tabs を追加 (#404)
- feat(lv1): DropdownMenu を追加 (#403)
- refactor(lv1): Toast を sonner ベースに刷新 + loading / promise API (#396)
- feat(lv1): Text に serif family + leading variants + JP/EN size 補正 (#400)
- a11y: state token に
emphasisrung を新設し色文字を WCAG 2.1 AA に (#413) - a11y: foreground-muted / foreground-subtle を WCAG 2.1 AA に引き上げ (#412)
- CSS API: Callout / Toast のアイコン整列と action / close レイアウトを調整 (#411)
Patch Changes
- CSS API:
.st-btnラベルを bold 化 + destructive hover の文字色調整 (#401) - perf(lv1): Button のローディングスピナーをアイドル時に停止 (#406)
- fix(lv1): Checkbox / Radio / Switch の disabled + isError で disabled を優先 (#402)
- refactor(docs): Welcome のリンクマニフェストを非 stories モジュールへ切り出し (#399)
Full Changelog: v0.11.0...v0.12.0
v0.11.0
v0.11.0 は docs 完備 + a11y 自動化 + semantic token 層拡充 のリリースです。
Highlights
- semantic token 層: shadow / radius / motion (#145)、用途別 z-index (#146)
- a11y 自動化:
@axe-core/playwrightを VRT に同梱 (#147)、Storybookaddon-a11y導入 (#148) - docs 完備 (新 IA): 7 グループ taxonomy へ刷新 (#332)、Tokens / Patterns 9 ページ + Welcome 刷新 +
DocsTablea11y (#384) - seasonal payoff:
--color-solidを theme ramp の段参照に再配線し季節色が solid 面に効くように (#150)、Seasonal Showcase (#151) - asChild policy 確定: 公開 asChild を Button に限定 (#331)
⚠️ Breaking Changes (pre-1.0 のため minor)
| 変更 | Before | After |
|---|---|---|
<Text asChild> 削除 (#338) |
<Text asChild><a …> |
<a className={textVariants({…})}> / as prop |
--transition-* トークン削除 (#350) |
var(--transition-fast) (150ms ease) |
var(--motion-base) (150ms) + easing 自前 / tokens.motion.* |
What's Changed
詳細は下記 CHANGELOG を参照。
0.11.0
Minor Changes
-
#379
29a272cThanks @yasmro! - feat(lv1): FieldContext にlabelIdを追加 — Field label が self-labelled / group コンポーネントの accessible name になるように (#345)FieldContextValueにlabelId?: stringを追加 (additive)。<Field label>が描画する<label>要素に id が付き、context 経由で参照できます。Checkbox/Switchは自前のlabelprop が無く、aria-label/aria-labelledbyの明示指定も無い場合に限り、Field の label をaria-labelledbyで参照します。<Field label="Notifications"><Switch /></Field>がスクリーンリーダーで「Notifications」と読み上げられるようになります (従来は無名 — axebutton-name違反)。RadioGroupは group root (role="radiogroup") で Field label をaria-labelledby参照します (radiogroup はhtmlForでは命名できないため)。- 優先順位: 明示の
aria-label/aria-labelledby> 自前label> Field のlabelId。既存の利用形 (自前 label あり / Field 外) の出力 DOM は不変です。 - 既知の限界: Field label クリックでの focus / toggle 連動は self-labelled コンポーネントでは効きません (SR 名の配線のみ)。
-
#378
9c8dcd1Thanks @yasmro! - BREAKING: 死蔵されていた--transition-fast/--transition-normal/--transition-slow(CSS 変数)、tokens.transition.*、TransitionToken型を削除。#145 で deprecated 化済み・参照ゼロのため、pre-1.0 のうちに削除(#350)。移行表:
旧 新 var(--transition-fast)(150ms ease)var(--motion-base)(150ms)+ easing は自分で指定var(--transition-normal)(200ms ease)var(--motion-expressive)(200ms)+ 同上var(--transition-slow)(300ms ease)対応 step なし — 300ms 直書き、または 200ms へ寄せる tokens.transition.*/TransitionTokentokens.motion.*/MotionToken旧トークンは duration + easing を束ねた値(例
150ms ease)、新--motion-*は duration 単体である点に注意(名前の対応もfast→--motion-quickではなく--motion-base)。CSS API:
dist/schatten.cssの tokens layer から上記 3 変数が消える(@theme未登録のため manifest 差分はなし)。再導入はsrc/core/tokens/__tests__/no-transition-tokens.test.tsのソース走査ガードが防ぐ。 -
#348
1f2538bThanks @yasmro! - CSS API: 用途別 semantic token を追加(shadow:--shadow-card/popover/modal/toast、radius:--radius-control/surface/pill、motion:--motion-quick/base/expressive)。@theme登録済みでtokens.tsからも参照可能(shadow.card等、新規motionセクション +MotionToken型)。既存コンポーネントは value-preserving に置換(視覚変更なし・VRT zero diff): Dialog/Toast/Tooltip/Select の elevation を
--shadow-modal(=lg)/--shadow-toast(=md)/--shadow-popover(=md) 経由に、Badge/Radio/Switch の pill を--radius-pill(=full) 経由に。standalone CSS 向けに literal fallback 付き。motion semantic は死蔵していた
--transition-*ではなく生きている--st-duration-*のエイリアスとして定義。tokens.tsのtransitionセクションは@deprecated注記。--radius-control/surfaceは定義のみ(Button/Input 等への角丸適用は別 spike)。 -
#354
84de0d0Thanks @yasmro! - feat(tokens): route Select content z-index through the--z-popoversemantic
token (was a hard-coded50). Visual no-op (50→60, the 51–60 band is otherwise
empty) but fixes a latent Select-in-Dialog stacking case and removes the last
hard-coded z-index in a component. Documents the reserved0–100z-index band
in the README. -
#374
4a5df43Thanks @yasmro! - feat(theme): seasonal payoff 強化 —--color-solidファミリーを theme ramp の段参照に再配線 (#150)--color-solid/--color-solid-hover/--color-solid-foreground/--color-solid-foreground-hoverが theme ramp の段 (light: 700/900/100/300、dark: 300/100/800/700) を参照するようになりました。「Mode が段を選び、Special が ramp を供給する」モデルです。seasonal テーマ (data-theme="season--*") を有効にすると、Button primary / Badge・Callout・Toast の neutral × solid が季節色で再着色されます。- default の theme scale (
--color-theme-50..950) の解決先が blue → alabaster (中立 ramp) に変わりました。Special 非適用時の solid 面の見た目は再配線前と完全に同一 (value-preserving) ですが、bg-theme-*ユーティリティやtokens.theme*(JS) を直接使っている場合は default 値が blue から warm neutral に変わります。 - CSS 変数名・
.st-*クラスの増減はありません (manifest 不変)。seasonal の allowlist (['--color-theme-*']) も不変で、Special が solid を直接書くことは引き続き禁止です。 - 注意: custom property 連鎖の置換は宣言要素 (
:root) で確定するため、data-themeは<html>に設定してください (サブツリーの wrapper では solid が再着色されません)。
-
#338
825a1e5Thanks @yasmro! - BREAKING:<Text>no longer exposes theasChildprop. Text's
polymorphism is already covered by two non-overlapping escape hatches —
as(a closed enum of semantic tagsp/span/h1–h6) for swapping
the element, andtextVariants()for applying Text's classes to an
arbitrary element — soasChildwas redundant (it merged nothing beyond
className+ spread DOM props, whichtextVariants()does with full
typing).Migration: replace
<Text asChild><a href="…">…</a></Text>with
<a href="…" className={textVariants({ /* variant, size, color, … */ })}>…</a>.
textVariantsis exported from@yasmro/schatten/variants.Public
asChildis nowButtononly. Seecomponent-api-conventions.md
§"asChild vs*Variants()— which to reach for" for the boundary. -
#351
0724e64Thanks @yasmro! - BREAKING:--text-{body,label,heading}-{xs..2xl}-{size,leading,weight}の 39 個の
composite typography 変数を公開サーフェスから撤去。タイポグラフィの shorthand は
.st-text--{variant}.st-text--{size}クラス API(および React<Text>)に一本化。CSS API: 上記 39 変数を manifest から削除。基底スケール(
--text-*/--leading-*
/--font-*)は存続。独自 CSS で composite 変数を参照していた利用者は、.st-text
クラスへ移行するか基底スケール変数を直接束ねること。視覚は不変(値保存リファクタ)。
Patch Changes
-
#340
b2b3658Thanks @yasmro! - Fix:<Button asChild variant="link">no longer throwsReact.Children.only expected to receive a single React element child. Thelinkbranch wraps
childrenwith two icon-conditional siblings, so combining it with
asChildhanded RadixSlotmore than one child. TheasChildpath is now
resolved before thelinkbranch, so a single child always reachesSlot.
As with the otherasChildpaths,icon/isLoadingare not projected
onto the child — author the inner content yourself. -
#379
29a272cThanks @yasmro! - fix(lv1): Dialog の本文スクロール領域をキーボードフォーカス可能に (#345).st-dialog__bodyは内容がオーバーフローした時のみtabIndex={0}を持つようになり、focusable な子要素を含まない長文ダイアログでもキーボードでスクロールできます (WCAG 2.1.1 / axescrollable-region-focusable)。オーバーフローしていない通常のダイアログには tab stop を追加しません。focus ring は Button と同じ ring トークンの 2 段 box-shadow です。CSS クラス・属性セレクタの増減はありません (manifest 不変)。 -
#386
45f2fe4Thanks @yasmro! - docs(a11y): ハンドビルド docs ページの table を共有DocsTableに集約し、<th scope="col">を構造的に強制 (closes #384)Accessibility/Testingが二重定義していたRefTableをdocs-ui.tsxのDocsTableに統合し、scope欠落・<th>/<td>不整合を構造で防ぐ。CompositionWithAsChildの比較表もDocsTable化、CSSApiの bespoke ta...
v0.10.0
Highlights
- FOUC snippet が公式 API に —
<ThemeInitScript>(from@yasmro/schatten/providers) と framework-agnostic な@yasmro/schatten/theme-initentry (THEME_INIT_SCRIPT/buildThemeInitScript(storageKey)) を新設。これまで README のコピペブロックだった「first paint 前に Mode/Special を適用する<head>script」が、Provider のlocalStorage契約と同期された SSOT になりました (#321) - strict-CSP 運用ガイド + byte 契約 — Next.js / Astro / Remix の nonce レシピ、
sha256-…hash-pin レシピ、pnpm schatten:csp-hashCLI を追加。FOUC snippet のバイト列を public surface としてapi-stability.mdに pin (変更はmajor) (#328) - 共有モーションスケール
--st-duration-*(fast 100ms / base 150ms / slow 200ms) を新設し、Tooltip / Dialog / Toast の transition timing を value-preserving に集約 (見た目不変・VRT 再ベースライン不要) (#325) - icon-only Badge の a11y 修正 —
<Badge icon={Check} aria-label="Done" />にrole="img"を自動付与し、aria-labelが screen reader /getByRole('img', { name })から確実に参照できるように (#325) - ブランド朱
vermillion-*を真朱 #E73121 系へ retune — hue 22 → 30 に全 shade を引き直し。危険色red-*(error/destructive) は据え置きで無影響 (#327)
⚠️ Breaking Changes (pre-1.0 のため minor bump)
ripple 型 Spinner のアニメーション timing 変数を rename しました (#325)。class API の st- prefix と揃え、v1.0 freeze 前に変数契約を確定する目的です。
| Before (v0.9.0) | After (v0.10.0) |
|---|---|
--schatten-spinner-duration (default 2.8s) |
--st-spinner-duration |
--schatten-spinner-ripple-delay (default 1.1s) |
--st-spinner-ripple-delay |
影響を受けるケース
React 利用は 無影響。上記 2 変数を CSS から override している消費者のみ要対応で、sed 一発で移行できます:
sed -i '' 's/--schatten-spinner-/--st-spinner-/g' <your-css>What's Changed
Minor Changes
<ThemeInitScript>+ framework-agnostic@yasmro/schatten/theme-initentry で FOUC snippet を公開 (#321)- ripple Spinner timing 変数を
--schatten-spinner-*→--st-spinner-*に rename (BREAKING pre-1.0)・@theme登録で manifest cssVariables に追加 (#325) - enter/exit transition timing の共有スケール
--st-duration-*(fast/base/slow) を新設 (#325)
Patch Changes
- icon-only Badge に
role="img"自動付与 (consumer 指定のroleが常に優先) (#325) - strict-CSP 運用ガイド +
pnpm schatten:csp-hashCLI + FOUC snippet byte 契約 (#328) - ブランド朱
vermillion-*を真朱 #E73121 系へ retune (semantic 名不変・値のみ変更) (#327)
Full Changelog: v0.9.0...v0.10.0
v0.9.0
Highlights
- 「consumers do NOT need Tailwind」 が技術的に達成 —
dist/schatten.cssに全 18 lv1 コンポの.st-*セマンティッククラス API が同梱され、vanilla HTML / WordPress / Astro / Vue / Svelte から<button class="st-btn st-btn--primary">だけで React と同じ見た目が得られるように (#154, sweep #282/#283/#290/#296/#298/#299/#300) - Per-component CSS subpath
@yasmro/schatten/css/<component>を 18 lv1 全コンポに (#301)。.size-limit.jsonで 1 コンポ ≤ 1.5 KB / 集約 ≤ 20 KB / 統合 dist ≤ 50 KB が CI で gate dist/schatten.manifest.jsonを新規 export (#279) — 公開 CSS surface (195 classes / 8 state attributes / 145 CSS variables) を機械可読 JSON として配布。pnpm check:manifestで diff が CI ログに直接出る- 新しい lv1
<Icon>(#255) + 新しい<ThemeProvider>/useTheme()(#260) — Mode × Special の宣言的 API、'system'/'auto-seasonal'対応 +localStorage永続化 + cross-tab 同期 - Lighthouse 100 を狙える consumer 向けレシピ (#293) と runnable な
examples/lighthouse-100/{nextjs,vanilla}/
⚠️ Breaking Changes (pre-1.0 のため minor bump)
CSS class 出力が Tailwind utility から .st-* semantic class chain に変更されました。
| Before (v0.8.0) | After (v0.9.0) |
|---|---|
<Button> renders class="inline-flex items-center ... bg-solid ..." |
<Button> renders class="st-btn st-btn--primary st-btn--md" |
<Tooltip> content uses .tooltip-content |
.st-tooltip__content |
Spinner internal classes .schatten-spinner-dot / .schatten-spinner-ripple-{1,2} |
.st-spinner__dot / .st-spinner__ripple-{1,2} |
Selector .st-callout--success { background: ... } overrides every appearance |
Pattern B は double-class selector — .st-callout--success.st-callout--solid / .st-callout--success.st-callout--subtle 等を組合せで記述 |
影響を受けるケース
React 利用 (<Button> / <Input> 等 prop 経由) は 無影響。以下のいずれかに該当する場合のみ要対応:
cn(buttonVariants(...), 'h-12')のように CVA 出力に Tailwind utility を重ね打ち しているケース → 出力 class set の内訳が変わる(動作は等価).tooltip-content/.schatten-spinner-*など 古い内部クラスを CSS から直接参照 しているケース →.st-tooltip__content/.st-spinner__*に sed-migrate- VRT baseline を持つ消費者 → 再生成が必要
What's Changed
Minor Changes
build:cssを@tailwindcss/cliに切替 +src/styles/entry.css新設 (#275)- CSS API sweep-1 — Separator / Text / Icon (#282)
- CSS API sweep-2 — Spinner / Badge / Callout (#283)
- CSS API sweep-3 — Button / Checkbox / Switch (#290)
- CSS API sweep-4 — Input / Textarea / Radio (#296)
- CSS API sweep-5 — Select / Tooltip (#298)
- CSS API sweep-6 — Toast / Dialog (#299)
- CSS API sweep-7 — Field / FieldSet (#300)
- 新 lv1
<Icon>+iconVariants(#255) - 新
<ThemeProvider>/useTheme()(#260) dist/schatten.manifest.json新規 export + CI diff check (#279)- manifest
cssVariablesを@layer theme配下に限定 (#281) - per-component CSS subpath
@yasmro/schatten/css/<component>(#301)
Patch Changes
/audit-coverageslash command +scripts/audit-coverage.mjs(#305)- Callout inner flex を
.st-calloutに昇格 +__content/__actionsub-element (#288) - Foundation/CSS API vanilla-HTML 実機検証 VRT +
dist/schatten.csscascade bug 修正 (#313) - DefaultSpinner の Tailwind 依存を raw CSS に置き換え (#289)
- Button
variant="link"icon 孤立を解消、text↔icon 間に 4px gap (#302) - Storybook
STORYBOOK_CHANNELをimport.meta.env経由に (#256) - Biome
noRestrictedImportsでcore/variants/themes境界を機械化 (#294) /prepare-releaseskill 新設 (#309)
Full Changelog: v0.8.0...v0.9.0
v0.8.0
Highlights
- BREAKING —
lucide-reactis now an optional peer dependency. Icon props (Button/Badge/Input/Dialog) take a Lucide icon component instead of a string name, eliminating a ~1.37 MB whole-barrel icon import from consumer bundles. (#223) - BREAKING — brand-named semantic tokens. New
--color-vermillion(朱) and--color-indigo(藍) tokens;--color-accentis removed andText'scolorprop drops"accent". (#236) - New
--indigo-*primitive scale — a traditional Japanese indigo, the second brand color alongside vermillion. (#232) error/destructivesplit onto a dedicated--red-*primitive — value-identical to vermillion today, a governance seam so brand 朱 and danger red retune independently. (#240)- Tree-shakeable lv1 barrel + SSR support —
import { Button }drops ~81% (~48 KB → ~9.7 KB), and React bundles now carry a'use client'directive for Next.js App Router. (#228, #225)
⚠️ Breaking Changes
lucide-react → optional peer dependency, icon props take components (#223)
Install lucide-react yourself (pnpm add lucide-react) and pass the icon component, not a name string:
| Before | After |
|---|---|
<Button icon="Search" /> |
import { Search } from 'lucide-react'<Button icon={Search} /> |
Applies to Button / Badge icon, Input iconLeft / iconRight, and Dialog's actionButton.icon / cancelButton.icon / subActionButton.icon. The IconName type export is removed — icon props are now typed as LucideIcon (import from lucide-react).
--color-accent removed, brand-named tokens added (#236)
| Before | After |
|---|---|
<Text color="accent"> |
<Text color="vermillion"> (also new: color="indigo") |
bg-accent / text-accent / var(--color-accent) |
bg-vermillion / text-vermillion / var(--color-vermillion) |
tokens.color.accent / .accentForeground |
tokens.color.vermillion / .vermillionForeground (or .indigo / .indigoForeground) |
Settled pre-1.0 deliberately — api-stability.md freezes CSS variable names as BREAKING from v1.0.0, so the brand-named tokens land in v0.8.0 to bake before the contract goes live.
What's Changed
Minor Changes
- BREAKING: brand-named semantic tokens
--color-vermillion/--color-indigo;--color-accentremoved (#185) — #236 - feat(tokens): add the
--indigo-*primitive color scale (#181) — #232 - BREAKING:
lucide-reactoptional peerDep + tree-shakeable icon component API (#117, #118) — #223 - refactor(tokens): add
--red-*primitive scale, repointerror/destructiveoff vermillion (#238) — #240
Patch Changes
- perf(build): make the
components/lv1barrel tree-shakeable via per-component entries — #228 - chore: normalize
package.jsonsideEffectsto["*.css", "**/*.css"]— #223 - feat(lint): add the
no-primitive-colorBiome GritQL plugin (#122) — #220 - fix(ssr): inject
'use client'into the lv1 build via tsup banner (#116) — #225
Full Changelog: v0.7.0...v0.8.0