@dashforge/tw 1.1.1 → 1.3.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 (197) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/README.md +45 -0
  3. package/dist/index.esm.js +4443 -667
  4. package/dist/src/components/Accordion/Accordion.d.ts.map +1 -1
  5. package/dist/src/components/Accordion/accordion.types.d.ts +7 -0
  6. package/dist/src/components/Accordion/accordion.types.d.ts.map +1 -1
  7. package/dist/src/components/Alert/Alert.d.ts +1 -1
  8. package/dist/src/components/Alert/Alert.d.ts.map +1 -1
  9. package/dist/src/components/Alert/alert.types.d.ts +17 -0
  10. package/dist/src/components/Alert/alert.types.d.ts.map +1 -1
  11. package/dist/src/components/AppShell/AppShell.d.ts.map +1 -1
  12. package/dist/src/components/AppShell/appShell.types.d.ts +7 -0
  13. package/dist/src/components/AppShell/appShell.types.d.ts.map +1 -1
  14. package/dist/src/components/Autocomplete/Autocomplete.d.ts.map +1 -1
  15. package/dist/src/components/Autocomplete/autocomplete.types.d.ts +47 -1
  16. package/dist/src/components/Autocomplete/autocomplete.types.d.ts.map +1 -1
  17. package/dist/src/components/Avatar/Avatar.d.ts.map +1 -1
  18. package/dist/src/components/Avatar/avatar.types.d.ts +17 -1
  19. package/dist/src/components/Avatar/avatar.types.d.ts.map +1 -1
  20. package/dist/src/components/Badge/Badge.d.ts.map +1 -1
  21. package/dist/src/components/Badge/badge.types.d.ts +27 -2
  22. package/dist/src/components/Badge/badge.types.d.ts.map +1 -1
  23. package/dist/src/components/Box/Box.d.ts.map +1 -1
  24. package/dist/src/components/Box/box.types.d.ts +64 -1
  25. package/dist/src/components/Box/box.types.d.ts.map +1 -1
  26. package/dist/src/components/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  27. package/dist/src/components/Breadcrumbs/breadcrumbs.types.d.ts +26 -1
  28. package/dist/src/components/Breadcrumbs/breadcrumbs.types.d.ts.map +1 -1
  29. package/dist/src/components/Button/Button.d.ts.map +1 -1
  30. package/dist/src/components/Button/button.types.d.ts +53 -1
  31. package/dist/src/components/Button/button.types.d.ts.map +1 -1
  32. package/dist/src/components/Calendar/Calendar.d.ts.map +1 -1
  33. package/dist/src/components/Calendar/calendar.types.d.ts +16 -0
  34. package/dist/src/components/Calendar/calendar.types.d.ts.map +1 -1
  35. package/dist/src/components/Card/Card.d.ts.map +1 -1
  36. package/dist/src/components/Card/card.types.d.ts +17 -0
  37. package/dist/src/components/Card/card.types.d.ts.map +1 -1
  38. package/dist/src/components/Checkbox/Checkbox.d.ts.map +1 -1
  39. package/dist/src/components/Checkbox/checkbox.types.d.ts +19 -1
  40. package/dist/src/components/Checkbox/checkbox.types.d.ts.map +1 -1
  41. package/dist/src/components/Chip/Chip.d.ts.map +1 -1
  42. package/dist/src/components/Chip/chip.types.d.ts +40 -1
  43. package/dist/src/components/Chip/chip.types.d.ts.map +1 -1
  44. package/dist/src/components/ConfirmDialog/ConfirmDialog.d.ts.map +1 -1
  45. package/dist/src/components/ConfirmDialog/confirmDialog.types.d.ts +30 -2
  46. package/dist/src/components/ConfirmDialog/confirmDialog.types.d.ts.map +1 -1
  47. package/dist/src/components/Container/Container.d.ts.map +1 -1
  48. package/dist/src/components/Container/container.types.d.ts +29 -1
  49. package/dist/src/components/Container/container.types.d.ts.map +1 -1
  50. package/dist/src/components/DataGrid/DataGrid.d.ts +1 -1
  51. package/dist/src/components/DataGrid/DataGrid.d.ts.map +1 -1
  52. package/dist/src/components/DataGrid/dataGrid.types.d.ts +124 -10
  53. package/dist/src/components/DataGrid/dataGrid.types.d.ts.map +1 -1
  54. package/dist/src/components/DatePicker/DatePicker.d.ts +1 -1
  55. package/dist/src/components/DatePicker/DatePicker.d.ts.map +1 -1
  56. package/dist/src/components/DatePicker/datePicker.types.d.ts +18 -0
  57. package/dist/src/components/DatePicker/datePicker.types.d.ts.map +1 -1
  58. package/dist/src/components/DateRangePicker/DateRangePicker.d.ts +1 -1
  59. package/dist/src/components/DateRangePicker/DateRangePicker.d.ts.map +1 -1
  60. package/dist/src/components/DateRangePicker/dateRangePicker.types.d.ts +18 -0
  61. package/dist/src/components/DateRangePicker/dateRangePicker.types.d.ts.map +1 -1
  62. package/dist/src/components/DateTimePicker/DateTimePicker.d.ts +1 -1
  63. package/dist/src/components/DateTimePicker/DateTimePicker.d.ts.map +1 -1
  64. package/dist/src/components/DateTimePicker/dateTimePicker.types.d.ts +20 -0
  65. package/dist/src/components/DateTimePicker/dateTimePicker.types.d.ts.map +1 -1
  66. package/dist/src/components/Dialog/Dialog.d.ts.map +1 -1
  67. package/dist/src/components/Dialog/dialog.types.d.ts +25 -1
  68. package/dist/src/components/Dialog/dialog.types.d.ts.map +1 -1
  69. package/dist/src/components/Divider/Divider.d.ts.map +1 -1
  70. package/dist/src/components/Divider/divider.types.d.ts +37 -1
  71. package/dist/src/components/Divider/divider.types.d.ts.map +1 -1
  72. package/dist/src/components/Drawer/Drawer.d.ts +21 -0
  73. package/dist/src/components/Drawer/Drawer.d.ts.map +1 -0
  74. package/dist/src/components/Drawer/drawer.types.d.ts +311 -0
  75. package/dist/src/components/Drawer/drawer.types.d.ts.map +1 -0
  76. package/dist/src/components/Drawer/drawer.variants.d.ts +177 -0
  77. package/dist/src/components/Drawer/drawer.variants.d.ts.map +1 -0
  78. package/dist/src/components/Grid/Grid.d.ts.map +1 -1
  79. package/dist/src/components/Grid/grid.types.d.ts +16 -0
  80. package/dist/src/components/Grid/grid.types.d.ts.map +1 -1
  81. package/dist/src/components/IconButton/IconButton.d.ts.map +1 -1
  82. package/dist/src/components/IconButton/iconButton.types.d.ts +40 -1
  83. package/dist/src/components/IconButton/iconButton.types.d.ts.map +1 -1
  84. package/dist/src/components/Image/Image.d.ts +27 -0
  85. package/dist/src/components/Image/Image.d.ts.map +1 -0
  86. package/dist/src/components/Image/image.types.d.ts +126 -0
  87. package/dist/src/components/Image/image.types.d.ts.map +1 -0
  88. package/dist/src/components/Image/image.variants.d.ts +149 -0
  89. package/dist/src/components/Image/image.variants.d.ts.map +1 -0
  90. package/dist/src/components/LeftNav/LeftNav.d.ts.map +1 -1
  91. package/dist/src/components/LeftNav/leftNav.types.d.ts +26 -6
  92. package/dist/src/components/LeftNav/leftNav.types.d.ts.map +1 -1
  93. package/dist/src/components/Link/Link.d.ts +15 -0
  94. package/dist/src/components/Link/Link.d.ts.map +1 -0
  95. package/dist/src/components/Link/link.types.d.ts +169 -0
  96. package/dist/src/components/Link/link.types.d.ts.map +1 -0
  97. package/dist/src/components/Link/link.variants.d.ts +107 -0
  98. package/dist/src/components/Link/link.variants.d.ts.map +1 -0
  99. package/dist/src/components/Menu/Menu.d.ts +1 -1
  100. package/dist/src/components/Menu/Menu.d.ts.map +1 -1
  101. package/dist/src/components/Menu/menu.types.d.ts +20 -0
  102. package/dist/src/components/Menu/menu.types.d.ts.map +1 -1
  103. package/dist/src/components/NumberField/NumberField.d.ts.map +1 -1
  104. package/dist/src/components/NumberField/numberField.types.d.ts +47 -1
  105. package/dist/src/components/NumberField/numberField.types.d.ts.map +1 -1
  106. package/dist/src/components/OTPField/OTPField.d.ts.map +1 -1
  107. package/dist/src/components/OTPField/otpField.types.d.ts +35 -1
  108. package/dist/src/components/OTPField/otpField.types.d.ts.map +1 -1
  109. package/dist/src/components/Pagination/Pagination.d.ts.map +1 -1
  110. package/dist/src/components/Pagination/pagination.types.d.ts +26 -1
  111. package/dist/src/components/Pagination/pagination.types.d.ts.map +1 -1
  112. package/dist/src/components/Popover/Popover.d.ts.map +1 -1
  113. package/dist/src/components/Popover/popover.types.d.ts +29 -0
  114. package/dist/src/components/Popover/popover.types.d.ts.map +1 -1
  115. package/dist/src/components/Progress/Progress.d.ts +20 -0
  116. package/dist/src/components/Progress/Progress.d.ts.map +1 -0
  117. package/dist/src/components/Progress/progress.types.d.ts +200 -0
  118. package/dist/src/components/Progress/progress.types.d.ts.map +1 -0
  119. package/dist/src/components/Progress/progress.variants.d.ts +224 -0
  120. package/dist/src/components/Progress/progress.variants.d.ts.map +1 -0
  121. package/dist/src/components/RadioGroup/RadioGroup.d.ts.map +1 -1
  122. package/dist/src/components/RadioGroup/radioGroup.types.d.ts +25 -1
  123. package/dist/src/components/RadioGroup/radioGroup.types.d.ts.map +1 -1
  124. package/dist/src/components/Select/Select.d.ts +14 -0
  125. package/dist/src/components/Select/Select.d.ts.map +1 -0
  126. package/dist/src/components/Select/select.types.d.ts +272 -0
  127. package/dist/src/components/Select/select.types.d.ts.map +1 -0
  128. package/dist/src/components/Select/select.variants.d.ts +204 -0
  129. package/dist/src/components/Select/select.variants.d.ts.map +1 -0
  130. package/dist/src/components/Skeleton/Skeleton.d.ts.map +1 -1
  131. package/dist/src/components/Skeleton/skeleton.types.d.ts +25 -1
  132. package/dist/src/components/Skeleton/skeleton.types.d.ts.map +1 -1
  133. package/dist/src/components/Slider/Slider.d.ts +15 -0
  134. package/dist/src/components/Slider/Slider.d.ts.map +1 -0
  135. package/dist/src/components/Slider/slider.types.d.ts +279 -0
  136. package/dist/src/components/Slider/slider.types.d.ts.map +1 -0
  137. package/dist/src/components/Slider/slider.variants.d.ts +313 -0
  138. package/dist/src/components/Slider/slider.variants.d.ts.map +1 -0
  139. package/dist/src/components/Snackbar/Snackbar.d.ts.map +1 -1
  140. package/dist/src/components/Snackbar/snackbar.types.d.ts +29 -5
  141. package/dist/src/components/Snackbar/snackbar.types.d.ts.map +1 -1
  142. package/dist/src/components/Spinner/Spinner.d.ts.map +1 -1
  143. package/dist/src/components/Spinner/spinner.types.d.ts +22 -2
  144. package/dist/src/components/Spinner/spinner.types.d.ts.map +1 -1
  145. package/dist/src/components/Stack/Stack.d.ts.map +1 -1
  146. package/dist/src/components/Stack/stack.types.d.ts +53 -2
  147. package/dist/src/components/Stack/stack.types.d.ts.map +1 -1
  148. package/dist/src/components/Stack/stack.variants.d.ts +23 -0
  149. package/dist/src/components/Stack/stack.variants.d.ts.map +1 -1
  150. package/dist/src/components/Stepper/Step.d.ts +30 -0
  151. package/dist/src/components/Stepper/Step.d.ts.map +1 -0
  152. package/dist/src/components/Stepper/Stepper.d.ts +15 -0
  153. package/dist/src/components/Stepper/Stepper.d.ts.map +1 -0
  154. package/dist/src/components/Stepper/StepperContext.d.ts +8 -0
  155. package/dist/src/components/Stepper/StepperContext.d.ts.map +1 -0
  156. package/dist/src/components/Stepper/stepper.types.d.ts +358 -0
  157. package/dist/src/components/Stepper/stepper.types.d.ts.map +1 -0
  158. package/dist/src/components/Stepper/stepper.variants.d.ts +253 -0
  159. package/dist/src/components/Stepper/stepper.variants.d.ts.map +1 -0
  160. package/dist/src/components/Stepper/useStep.d.ts +53 -0
  161. package/dist/src/components/Stepper/useStep.d.ts.map +1 -0
  162. package/dist/src/components/Switch/Switch.d.ts.map +1 -1
  163. package/dist/src/components/Switch/switch.types.d.ts +44 -1
  164. package/dist/src/components/Switch/switch.types.d.ts.map +1 -1
  165. package/dist/src/components/Table/Table.d.ts +1 -1
  166. package/dist/src/components/Table/Table.d.ts.map +1 -1
  167. package/dist/src/components/Table/table.types.d.ts +103 -8
  168. package/dist/src/components/Table/table.types.d.ts.map +1 -1
  169. package/dist/src/components/Tabs/Tabs.d.ts.map +1 -1
  170. package/dist/src/components/Tabs/tabs.types.d.ts +26 -1
  171. package/dist/src/components/Tabs/tabs.types.d.ts.map +1 -1
  172. package/dist/src/components/TextField/TextField.d.ts.map +1 -1
  173. package/dist/src/components/TextField/textField.types.d.ts +30 -1
  174. package/dist/src/components/TextField/textField.types.d.ts.map +1 -1
  175. package/dist/src/components/Textarea/Textarea.d.ts.map +1 -1
  176. package/dist/src/components/Textarea/textarea.types.d.ts +51 -1
  177. package/dist/src/components/Textarea/textarea.types.d.ts.map +1 -1
  178. package/dist/src/components/TimePicker/TimePicker.d.ts +1 -1
  179. package/dist/src/components/TimePicker/TimePicker.d.ts.map +1 -1
  180. package/dist/src/components/TimePicker/timePicker.types.d.ts +18 -0
  181. package/dist/src/components/TimePicker/timePicker.types.d.ts.map +1 -1
  182. package/dist/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  183. package/dist/src/components/Tooltip/tooltip.types.d.ts +30 -0
  184. package/dist/src/components/Tooltip/tooltip.types.d.ts.map +1 -1
  185. package/dist/src/components/TopBar/TopBar.d.ts.map +1 -1
  186. package/dist/src/components/TopBar/topBar.types.d.ts +25 -1
  187. package/dist/src/components/TopBar/topBar.types.d.ts.map +1 -1
  188. package/dist/src/components/Typography/Typography.d.ts.map +1 -1
  189. package/dist/src/components/Typography/typography.types.d.ts +47 -1
  190. package/dist/src/components/Typography/typography.types.d.ts.map +1 -1
  191. package/dist/src/components/Typography/typography.variants.d.ts +2 -2
  192. package/dist/src/components/Typography/typography.variants.d.ts.map +1 -1
  193. package/dist/src/hooks/useStandaloneFieldWarning.d.ts +38 -0
  194. package/dist/src/hooks/useStandaloneFieldWarning.d.ts.map +1 -0
  195. package/dist/src/index.d.ts +66 -42
  196. package/dist/src/index.d.ts.map +1 -1
  197. package/package.json +5 -4
package/CHANGELOG.md CHANGED
@@ -12,6 +12,147 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
12
12
  > duplicated intentionally — no shared "lowest common denominator" headless
13
13
  > layer.
14
14
 
15
+ ## [1.3.0] — 2026-08-14
16
+
17
+ Adds the `<Image>` primitive. No breaking changes vs 1.2.0 — every
18
+ existing consumer works unchanged.
19
+
20
+ ### Added
21
+
22
+ - **`<Image>`** — a thin, declarative wrapper over the native `<img>`.
23
+ Zero eval, no data fetching: it renders a URL and adds what a bare
24
+ `<img>` lacks:
25
+ - **No layout shift** — `aspectRatio` (or `width` + `height`) reserves
26
+ the box before load via CSS `aspect-ratio`.
27
+ - **Loading skeleton** — fills the reserved box while loading, and is
28
+ skipped for already-cached images (no flash).
29
+ - **Graceful error** — a muted fallback replaces the broken-image glyph
30
+ on failure (`fallback` to customise).
31
+ - Lazy by default (`loading="lazy"`); native `<img>` attributes are
32
+ forwarded.
33
+ - `fit` (`object-fit`) and `rounded` are Option C configurable via
34
+ `theme.components.Image.defaults`; `sx` / `slotProps` for overrides.
35
+ - Supports `access` (RBAC) and `visibleWhen` gating like the form
36
+ components — `hide` removes the image, `disable` / `readonly` dim it.
37
+
38
+ ### Internal
39
+
40
+ - Corrected the exported `VERSION` constant, which had drifted to
41
+ `1.1.1`; it now tracks the package version.
42
+
43
+ ## [1.2.0] — 2026-07-24
44
+
45
+ Sprint 6 — closes the Option C rollout (`theme.components.<Name>.defaults`)
46
+ across the full catalog and adds 6 new primitives (Link, Select, Slider,
47
+ Progress, Stepper, Drawer). No breaking changes vs 1.1.1 — every
48
+ existing consumer works unchanged.
49
+
50
+ ### Added — new primitives
51
+
52
+ - **`<Link>`** — token-driven anchor primitive. Every visual axis
53
+ (`color` / `underline` / `weight` / `size`) is Option C configurable.
54
+ `startIcon` / `endIcon` accept any ReactNode; `external` toggles
55
+ `target="_blank"` + `rel="noopener noreferrer"`; `asChild` for router
56
+ integration via Radix Slot. 32 unit + precedence tests.
57
+ - **`<Select>`** — dedicated enum picker, narrower than Autocomplete
58
+ (no search, no async, no typeahead). Options shape
59
+ `{ value, label, disabled? }` mirrors AutocompleteOption. Two-arg
60
+ `onChange(value, option)`. Bridge + standalone controlled modes.
61
+ Multi-select shipped in v1. Generic `V extends string | number`.
62
+ 22 unit + 6 precedence tests. Unblocks Blueprint G-25.
63
+ - **`<Slider>`** — token-driven numeric picker. Single value or
64
+ `[min, max]` range via `range?: boolean` discriminated union.
65
+ Bridge commits on drag-end by default; opt into per-tick via
66
+ `commitOnChange`. Marks (explicit or auto). Value label tooltip with
67
+ formatter (`'auto' | 'always' | 'off'`). 6 color intents. Built on
68
+ `@radix-ui/react-slider`. 24 unit + 6 precedence tests.
69
+ - **`<Progress>`** — determinate progress indicator. Two visual flavors
70
+ on the same primitive: `variant='linear'` (bar) and `variant='circular'`
71
+ (SVG arc). Display-only (no bridge). `value` required (Spinner covers
72
+ indeterminate). 6 color intents, size + independent `thickness` axis,
73
+ custom `formatLabel`. 24 unit + 6 precedence tests.
74
+ - **`<Stepper>` + `<Step>` + `useStep()`** — declarative multi-step
75
+ wizard. Compound children with per-step config: `name`, `label`,
76
+ `helperText`, `icon`, `optional`, `fields` (RHF-triggered validation),
77
+ `isValid` (custom async, AND semantics with `fields`), `visibleWhen`
78
+ (reactive predicate for dynamic step composition), `access` (RBAC).
79
+ `useStep()` hook exposes navigation state + API. Horizontal + vertical
80
+ orientation, `labelPlacement 'end' | 'below'` (MUI `alternativeLabel`
81
+ parity), `initialStep` for name-based resume, `allowJumpTo: 'visited' | 'none'`.
82
+ Docs cover 4 error surfaces. 35 unit + precedence tests.
83
+ - **`<Drawer>`** — edge-anchored sliding panel. 4 positions
84
+ (`left`/`right`/`top`/`bottom`), 3 variants (`temporary` default,
85
+ `persistent`, `sticky`). `title: string | ReactNode`,
86
+ `closeButtonPosition: 'start' | 'end'` (bordered × styling),
87
+ `onCloseClick` side-effect hook, `onOpenAutoFocus` a11y customization
88
+ hook. Resize handle on the free edge with pointer drag + keyboard
89
+ step + localStorage persistence under `df.drawer.<resizeKey>`.
90
+ Curtain-like slide animation via inline `@keyframes` module-level
91
+ injection — `tailwindcss-animate` not required. `z-[1400]/[1410]`
92
+ stacks above MUI AppBar for MUI-coexistence. `visibleWhen` + `access`
93
+ catalog-uniform. 66 unit + precedence tests. Closes
94
+ [#108](https://github.com/kensaadi/dashforge/issues/108) (Blueprint
95
+ Builder V2 G-12 blocker).
96
+
97
+ ### Added — Option C coverage
98
+
99
+ - **`theme.components.<Name>.defaults`** wired across the full catalog
100
+ (46 components with visual axes; VisuallyHidden, AspectRatio,
101
+ Accordion, AppShell, Flex skipped with rationale — no theme-configurable
102
+ visual axes). Each consumer can now set application-wide defaults for
103
+ any component: `patchTheme({ components: { Button: { defaults: { size: 'lg' } } } })`.
104
+ - **`theme.components.<Name>.slotProps`** wired for compound components
105
+ where slot-level defaults have DS-identity value (Dialog, Popover,
106
+ Menu, DataGrid, Tabs, LeftNav, TopBar, Drawer, Stepper, Slider, Link,
107
+ Select).
108
+ - **47 `.precedence.test.tsx` files** shipped, verifying the 4-level
109
+ precedence chain (TV defaults → `theme.components.defaults` → instance
110
+ props → `sx`) across the whole catalog. Backward-compat guarantee:
111
+ every test's baseline confirms no-config behavior identical to 1.1.x.
112
+
113
+ ### Changed
114
+
115
+ - **`DashFormBridge` — new optional `trigger?: (name?: string | string[]) => Promise<boolean>`**
116
+ method on the bridge contract, implemented by `DashFormProvider`. Uses
117
+ `rhf.getFieldState()` internally to read fresh errors synchronously
118
+ after RHF trigger (bypasses React's render cycle where
119
+ `rhf.formState.errors` would be stale). Feature-gated / non-breaking —
120
+ consumers that don't call `bridge.trigger` are unaffected. Powers
121
+ `<Step fields={...}>` validation.
122
+ - **Stack `gap` type narrowed** from wide `string` to the 11-value
123
+ numeric union (Fix [#111](https://github.com/kensaadi/dashforge/issues/111)).
124
+ TypeScript now rejects `<Stack gap="md">`; a runtime dev-warn fires
125
+ when a non-numeric value slips through.
126
+ - **5 layout primitives (Box / Stack / Grid / Container / Flex)** —
127
+ runtime className sneak-in via `sx` no longer clobbers TV variant
128
+ classes; the merge chain is deterministic (Fix
129
+ [#112](https://github.com/kensaadi/dashforge/issues/112)).
130
+
131
+ ### Fixed
132
+
133
+ - **Standalone form widgets now dev-warn** when rendered outside a
134
+ `<DashFormProvider>` and without a controlled `value` / `onChange`
135
+ pair. Previously silent no-op that consumers couldn't diagnose
136
+ ([#113](https://github.com/kensaadi/dashforge/issues/113)).
137
+ - **`<DatePicker>` inside `<DashForm>`** now commits the value on
138
+ day-click when the field is bridge-registered
139
+ ([#114](https://github.com/kensaadi/dashforge/issues/114)).
140
+
141
+ ### Internal
142
+
143
+ - **`tw-theme` mode sync**: `patchTheme({ meta: { mode: 'dark' } })` now
144
+ correctly synchronizes the `data-dash-tw-theme` attribute + document
145
+ class (Fix [#110](https://github.com/kensaadi/dashforge/issues/110)).
146
+ - **JSDoc backfill**: every `*Props` interface now carries per-prop
147
+ JSDoc with `@default` tags. Powers `sync-props` MDX doc generation
148
+ in `dashforge-docs-lab`.
149
+
150
+ ### Migration
151
+
152
+ See [`docs/migration/1.2.0.md`](../../docs/migration/1.2.0.md) for the
153
+ full migration guide (all changes are additive — no code changes
154
+ required to upgrade).
155
+
15
156
  ## [1.1.1] — 2026-06-18
16
157
 
17
158
  > **Re-issued from the unpublished `1.1.0`** — `1.1.0` was published
package/README.md CHANGED
@@ -176,6 +176,51 @@ variant defaults regardless of stylesheet order.
176
176
 
177
177
  ---
178
178
 
179
+ ## Theme-level component defaults (Option C, since 1.2.0)
180
+
181
+ Instead of repeating `sx` / instance props on every component, pin
182
+ your DS identity once in the theme and every instance inherits it.
183
+
184
+ ```tsx
185
+ import { patchTheme } from '@dashforge/tw-theme';
186
+
187
+ patchTheme({
188
+ components: {
189
+ // Component-level defaults — apply to every <Button> in the app
190
+ Button: {
191
+ defaults: { variant: 'solid', color: 'primary', size: 'md' },
192
+ },
193
+ Drawer: {
194
+ defaults: { position: 'right', size: 'md', variant: 'temporary' },
195
+ },
196
+ // Slot-level defaults for compound components — override the visual
197
+ // chrome without touching consumer call sites
198
+ DataGrid: {
199
+ slotProps: {
200
+ header: { className: 'bg-neutral-100 font-semibold' },
201
+ cell: { className: 'py-3 text-sm' },
202
+ },
203
+ },
204
+ },
205
+ });
206
+ ```
207
+
208
+ **Precedence chain** (lowest → highest):
209
+
210
+ 1. Tailwind-variants `defaultVariants` — component-level baseline
211
+ 2. `theme.components.<Name>.defaults` — consumer-wide DS identity
212
+ 3. Instance props — `<Button size="lg">` beats theme default
213
+ 4. `sx` prop — merged last via `tailwind-merge`
214
+
215
+ Same 4-level chain applies to `slotProps` (theme slotProps → instance
216
+ slotProps). Backward-compat: consumers who don't set `theme.components`
217
+ get behavior identical to 1.1.x.
218
+
219
+ Full guide + per-component playgrounds:
220
+ [`/tw/docs/theme-system/component-defaults`](https://dashforge-docs-lab.pages.dev/tw/docs/theme-system/component-defaults).
221
+
222
+ ---
223
+
179
224
  ## Common consumer pitfalls
180
225
 
181
226
  The following are **not library bugs** — they're use-time issues that