@gouno/ui 0.3.2

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 (231) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/LICENSE +21 -0
  3. package/README.md +144 -0
  4. package/dist/base.css +239 -0
  5. package/dist/bootstrap.js +22 -0
  6. package/dist/components/primitives/alert-dialog.d.ts +18 -0
  7. package/dist/components/primitives/alert-dialog.js +43 -0
  8. package/dist/components/primitives/alert.d.ts +9 -0
  9. package/dist/components/primitives/alert.js +25 -0
  10. package/dist/components/primitives/avatar.d.ts +14 -0
  11. package/dist/components/primitives/avatar.js +42 -0
  12. package/dist/components/primitives/badge.d.ts +9 -0
  13. package/dist/components/primitives/badge.js +25 -0
  14. package/dist/components/primitives/button.d.ts +10 -0
  15. package/dist/components/primitives/button.js +36 -0
  16. package/dist/components/primitives/checkbox.d.ts +4 -0
  17. package/dist/components/primitives/checkbox.js +10 -0
  18. package/dist/components/primitives/dialog.d.ts +20 -0
  19. package/dist/components/primitives/dialog.js +37 -0
  20. package/dist/components/primitives/dropdown-menu.d.ts +25 -0
  21. package/dist/components/primitives/dropdown-menu.js +51 -0
  22. package/dist/components/primitives/empty.d.ts +11 -0
  23. package/dist/components/primitives/empty.js +33 -0
  24. package/dist/components/primitives/field.d.ts +24 -0
  25. package/dist/components/primitives/field.js +75 -0
  26. package/dist/components/primitives/input.d.ts +3 -0
  27. package/dist/components/primitives/input.js +7 -0
  28. package/dist/components/primitives/label.d.ts +4 -0
  29. package/dist/components/primitives/label.js +8 -0
  30. package/dist/components/primitives/popover.d.ts +16 -0
  31. package/dist/components/primitives/popover.js +31 -0
  32. package/dist/components/primitives/radio-group.d.ts +5 -0
  33. package/dist/components/primitives/radio-group.js +13 -0
  34. package/dist/components/primitives/select.d.ts +15 -0
  35. package/dist/components/primitives/select.js +38 -0
  36. package/dist/components/primitives/separator.d.ts +4 -0
  37. package/dist/components/primitives/separator.js +8 -0
  38. package/dist/components/primitives/sheet.d.ts +17 -0
  39. package/dist/components/primitives/sheet.js +41 -0
  40. package/dist/components/primitives/skeleton.d.ts +2 -0
  41. package/dist/components/primitives/skeleton.js +6 -0
  42. package/dist/components/primitives/switch.d.ts +6 -0
  43. package/dist/components/primitives/switch.js +8 -0
  44. package/dist/components/primitives/table.d.ts +28 -0
  45. package/dist/components/primitives/table.js +44 -0
  46. package/dist/components/primitives/tabs.d.ts +11 -0
  47. package/dist/components/primitives/tabs.js +30 -0
  48. package/dist/components/primitives/textarea.d.ts +3 -0
  49. package/dist/components/primitives/textarea.js +7 -0
  50. package/dist/components/primitives/tooltip.d.ts +13 -0
  51. package/dist/components/primitives/tooltip.js +24 -0
  52. package/dist/core/affix.d.ts +14 -0
  53. package/dist/core/affix.js +29 -0
  54. package/dist/core/alert.d.ts +54 -0
  55. package/dist/core/alert.js +56 -0
  56. package/dist/core/anchor.d.ts +16 -0
  57. package/dist/core/anchor.js +31 -0
  58. package/dist/core/app.d.ts +5 -0
  59. package/dist/core/app.js +5 -0
  60. package/dist/core/aspect-ratio.d.ts +6 -0
  61. package/dist/core/aspect-ratio.js +6 -0
  62. package/dist/core/autocomplete.d.ts +24 -0
  63. package/dist/core/autocomplete.js +139 -0
  64. package/dist/core/avatar.d.ts +26 -0
  65. package/dist/core/avatar.js +20 -0
  66. package/dist/core/badge.d.ts +16 -0
  67. package/dist/core/badge.js +22 -0
  68. package/dist/core/breadcrumb.d.ts +55 -0
  69. package/dist/core/breadcrumb.js +69 -0
  70. package/dist/core/button.d.ts +49 -0
  71. package/dist/core/button.js +66 -0
  72. package/dist/core/calendar.d.ts +48 -0
  73. package/dist/core/calendar.js +179 -0
  74. package/dist/core/card.d.ts +30 -0
  75. package/dist/core/card.js +12 -0
  76. package/dist/core/carousel.d.ts +49 -0
  77. package/dist/core/carousel.js +166 -0
  78. package/dist/core/cascader.d.ts +19 -0
  79. package/dist/core/cascader.js +45 -0
  80. package/dist/core/code-block.d.ts +16 -0
  81. package/dist/core/code-block.js +47 -0
  82. package/dist/core/collapse.d.ts +49 -0
  83. package/dist/core/collapse.js +96 -0
  84. package/dist/core/color-picker.d.ts +9 -0
  85. package/dist/core/color-picker.js +8 -0
  86. package/dist/core/config-provider.d.ts +10 -0
  87. package/dist/core/config-provider.js +14 -0
  88. package/dist/core/control-types.d.ts +2 -0
  89. package/dist/core/control-types.js +7 -0
  90. package/dist/core/date-picker.d.ts +13 -0
  91. package/dist/core/date-picker.js +14 -0
  92. package/dist/core/date-range-picker.d.ts +26 -0
  93. package/dist/core/date-range-picker.js +10 -0
  94. package/dist/core/descriptions.d.ts +41 -0
  95. package/dist/core/descriptions.js +133 -0
  96. package/dist/core/drawer.d.ts +9 -0
  97. package/dist/core/drawer.js +58 -0
  98. package/dist/core/empty.d.ts +8 -0
  99. package/dist/core/empty.js +5 -0
  100. package/dist/core/feedback.d.ts +5 -0
  101. package/dist/core/feedback.js +5 -0
  102. package/dist/core/field.d.ts +15 -0
  103. package/dist/core/field.js +19 -0
  104. package/dist/core/float-button.d.ts +13 -0
  105. package/dist/core/float-button.js +22 -0
  106. package/dist/core/form.d.ts +19 -0
  107. package/dist/core/form.js +56 -0
  108. package/dist/core/icon-button.d.ts +7 -0
  109. package/dist/core/icon-button.js +4 -0
  110. package/dist/core/icon.d.ts +17 -0
  111. package/dist/core/icon.js +35 -0
  112. package/dist/core/image.d.ts +76 -0
  113. package/dist/core/image.js +189 -0
  114. package/dist/core/index.d.ts +79 -0
  115. package/dist/core/index.js +77 -0
  116. package/dist/core/input-number.d.ts +24 -0
  117. package/dist/core/input-number.js +70 -0
  118. package/dist/core/input-otp.d.ts +14 -0
  119. package/dist/core/input-otp.js +76 -0
  120. package/dist/core/input.d.ts +14 -0
  121. package/dist/core/input.js +51 -0
  122. package/dist/core/kbd.d.ts +8 -0
  123. package/dist/core/kbd.js +11 -0
  124. package/dist/core/layout-primitives.d.ts +11 -0
  125. package/dist/core/layout-primitives.js +8 -0
  126. package/dist/core/layout.d.ts +71 -0
  127. package/dist/core/layout.js +119 -0
  128. package/dist/core/list.d.ts +37 -0
  129. package/dist/core/list.js +35 -0
  130. package/dist/core/locale.d.ts +48 -0
  131. package/dist/core/locale.js +32 -0
  132. package/dist/core/mentions.d.ts +10 -0
  133. package/dist/core/mentions.js +112 -0
  134. package/dist/core/menu.d.ts +79 -0
  135. package/dist/core/menu.js +265 -0
  136. package/dist/core/message.d.ts +16 -0
  137. package/dist/core/message.js +36 -0
  138. package/dist/core/modal.d.ts +40 -0
  139. package/dist/core/modal.js +67 -0
  140. package/dist/core/notification.d.ts +15 -0
  141. package/dist/core/notification.js +39 -0
  142. package/dist/core/page-layout.d.ts +6 -0
  143. package/dist/core/page-layout.js +7 -0
  144. package/dist/core/pagination.d.ts +28 -0
  145. package/dist/core/pagination.js +69 -0
  146. package/dist/core/popconfirm.d.ts +13 -0
  147. package/dist/core/popconfirm.js +42 -0
  148. package/dist/core/progress.d.ts +6 -0
  149. package/dist/core/progress.js +8 -0
  150. package/dist/core/public-props.d.ts +82 -0
  151. package/dist/core/public-props.js +1 -0
  152. package/dist/core/qrcode.d.ts +14 -0
  153. package/dist/core/qrcode.js +17 -0
  154. package/dist/core/rate.d.ts +11 -0
  155. package/dist/core/rate.js +48 -0
  156. package/dist/core/result.d.ts +12 -0
  157. package/dist/core/result.js +19 -0
  158. package/dist/core/segmented.d.ts +29 -0
  159. package/dist/core/segmented.js +38 -0
  160. package/dist/core/select.d.ts +27 -0
  161. package/dist/core/select.js +143 -0
  162. package/dist/core/selection-controls.d.ts +12 -0
  163. package/dist/core/selection-controls.js +23 -0
  164. package/dist/core/separator.d.ts +24 -0
  165. package/dist/core/separator.js +17 -0
  166. package/dist/core/slider.d.ts +2 -0
  167. package/dist/core/slider.js +6 -0
  168. package/dist/core/spin.d.ts +7 -0
  169. package/dist/core/spin.js +7 -0
  170. package/dist/core/spinner.d.ts +3 -0
  171. package/dist/core/spinner.js +6 -0
  172. package/dist/core/splitter.d.ts +44 -0
  173. package/dist/core/splitter.js +208 -0
  174. package/dist/core/statistic.d.ts +12 -0
  175. package/dist/core/statistic.js +6 -0
  176. package/dist/core/steps.d.ts +54 -0
  177. package/dist/core/steps.js +106 -0
  178. package/dist/core/tabs.d.ts +40 -0
  179. package/dist/core/tabs.js +80 -0
  180. package/dist/core/tag.d.ts +19 -0
  181. package/dist/core/tag.js +29 -0
  182. package/dist/core/textarea.d.ts +8 -0
  183. package/dist/core/textarea.js +14 -0
  184. package/dist/core/time-picker.d.ts +9 -0
  185. package/dist/core/time-picker.js +8 -0
  186. package/dist/core/timeline.d.ts +37 -0
  187. package/dist/core/timeline.js +48 -0
  188. package/dist/core/tour.d.ts +18 -0
  189. package/dist/core/tour.js +51 -0
  190. package/dist/core/transfer.d.ts +16 -0
  191. package/dist/core/transfer.js +46 -0
  192. package/dist/core/tree-select.d.ts +19 -0
  193. package/dist/core/tree-select.js +19 -0
  194. package/dist/core/tree.d.ts +89 -0
  195. package/dist/core/tree.js +386 -0
  196. package/dist/core/typography.d.ts +20 -0
  197. package/dist/core/typography.js +12 -0
  198. package/dist/core/upload.d.ts +20 -0
  199. package/dist/core/upload.js +72 -0
  200. package/dist/core/watermark.d.ts +10 -0
  201. package/dist/core/watermark.js +21 -0
  202. package/dist/fonts/inter-LICENSE +93 -0
  203. package/dist/fonts/inter-latin-wght-normal.woff2 +0 -0
  204. package/dist/fonts/jetbrains-mono-LICENSE +93 -0
  205. package/dist/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  206. package/dist/gouno/app-shell.d.ts +22 -0
  207. package/dist/gouno/app-shell.js +27 -0
  208. package/dist/gouno/index.d.ts +4 -0
  209. package/dist/gouno/index.js +4 -0
  210. package/dist/gouno/page-container.d.ts +4 -0
  211. package/dist/gouno/page-container.js +6 -0
  212. package/dist/gouno/page-header.d.ts +8 -0
  213. package/dist/gouno/page-header.js +6 -0
  214. package/dist/hooks/use-overlay-body.d.ts +6 -0
  215. package/dist/hooks/use-overlay-body.js +18 -0
  216. package/dist/index.d.ts +5 -0
  217. package/dist/index.js +5 -0
  218. package/dist/lib/utils.d.ts +2 -0
  219. package/dist/lib/utils.js +5 -0
  220. package/dist/patterns/bulk-action-bar.d.ts +8 -0
  221. package/dist/patterns/bulk-action-bar.js +7 -0
  222. package/dist/patterns/index.d.ts +5 -0
  223. package/dist/patterns/index.js +5 -0
  224. package/dist/theme/index.d.ts +2 -0
  225. package/dist/theme/index.js +2 -0
  226. package/dist/theme/provider.d.ts +22 -0
  227. package/dist/theme/provider.js +76 -0
  228. package/dist/theme/theme-toggle.d.ts +6 -0
  229. package/dist/theme/theme-toggle.js +10 -0
  230. package/dist/tokens.css +164 -0
  231. package/package.json +111 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,120 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ ## [Unreleased]
6
+
7
+ ### Added
8
+ - Core locale-only ConfigProvider, English and Simplified Chinese packs, and typed local copy overrides for Input, DatePicker, InputNumber, Select, Upload and Pagination.
9
+
10
+ ### Fixed
11
+ - Select clear and tag-removal keyboard actions, focus return, generated listbox IDs and searchable active-descendant ownership.
12
+ - Input suffix/clear spacing and Pagination ReactNode navigation labels.
13
+ - Showcase Fixture controls reserve tooling space instead of covering product actions; standalone page navigation starts collapsed.
14
+
15
+ ### Changed
16
+ - Participating controls use English fallback consistently. Configure zhCN to retain Chinese defaults; existing explicit text remains authoritative. See [migration](docs/component-localization.md).
17
+ - Review completion retains scope/evidence and can reopen after a defect instead of requiring every catalog entry to remain permanently at 100.
18
+
19
+ ## [0.3.2] - 2026-09-13
20
+
21
+ ### Fixed
22
+
23
+ - Fixed the tag-driven npm release workflow to publish the generated local tarball path correctly, preserving npm provenance and Trusted Publishing support.
24
+
25
+ ## [0.3.1] - 2026-09-13
26
+
27
+ ### Added
28
+
29
+ - Added standard public npm distribution metadata for `@gouno/ui`, including immutable registry release metadata and the MIT license.
30
+ - Added package-surface validation through `package:check` and `release:check`, with CI release gates covering the published entry points and archive contents.
31
+ - Added tag-driven npm publishing with npm provenance / Trusted Publishing support and GitHub Release artifact creation.
32
+ - Added release documentation describing immutable versions, exact release identity, npm authentication and consumer upgrades.
33
+
34
+
35
+ ## [0.3.0] - 2026-09-12
36
+
37
+ ### Changed
38
+
39
+ - Other 6F3: hardened Core `Affix` as a standard top-sticky container and `BackTop` as a window-scroll threshold control with real visibility behavior, caller-owned accessible copy, cancellable smooth-scroll action, standard DOM/event/ref passthrough, same-source Showcase examples, and focused regressions.
40
+ - Other 6F2: hardened Core `Watermark` with caller-owned required content, XML-safe SVG text encoding, normalized tile/rotation/opacity inputs, and standard div DOM/ARIA/style/ref passthrough. Core no longer injects the Gouno brand into generic watermarks.
41
+ - Other 6F1: hardened Core `FloatButton` as a generic icon-only floating action with caller-owned icon/accessibility copy, real button-or-anchor semantics, standard DOM/event/ref passthrough, working ReactNode Tooltip rendering, and explicit disabled-link behavior. The BackTop-style default arrow and string-only pseudo-tooltip bridge are removed from the generic action contract.
42
+ - Feedback 6E4: hardened Core `Tour` as a controlled modal walkthrough with caller-owned navigation copy, a controlled/uncontrolled normalized step index, canonical Dialog focus containment/Escape close/focus return, and visible step titles as the dialog accessible name. The never-implemented `TourStep.target` hook and injected English `Product tour` / `Previous` / `Next` / `Finish` copy are removed; target highlighting/positioning and product onboarding orchestration remain outside Core.
43
+ - Feedback 6E3: hardened Core `NotificationProvider` as a finite-lived local notification queue. Provider-local monotonic IDs replace time/random keys, removal timers are tracked and cleared on unmount, and each notice owns one atomic `status` region instead of nesting under an additional outer `aria-live`. `NotificationNotice` is now an explicit public type; notice duration accepts finite positive milliseconds and otherwise falls back to 4500ms, removing the old `duration=0` uncloseable-persistence sentinel. Persistent notification centers, read state, manual close/update/destroy, and cross-root singleton behavior remain product-owned.
44
+ - Feedback 6E2: hardened Core `MessageProvider` as a local transient queue. Message IDs are now deterministic per Provider, removal timers are tracked and cleared on unmount, and each message owns its `status`/`alert` live-region semantics instead of stacking those roles under a second outer `aria-live`. The existing `open/info/success/warning/error` hook surface is retained, `duration` only controls automatic removal, and global singleton, manual key/update/destroy, Promise orchestration, and product notification-center behavior remain out of Core.
45
+ - Feedback 6E1: hardened Core `Popconfirm` around one local confirmation lifecycle. Confirmation and cancellation labels are now explicitly caller-owned with no injected English defaults; the trigger child is no longer cloned or overwritten, while the wrapper composes natural bubbling and lets child/root `preventDefault` veto opening. Async confirmation exposes `aria-busy`, locks cancellation/Escape while pending, closes on success, and preserves context after rejection. Standard span DOM/ref ownership is retained without adding controlled-open, permission, MFA, or product feedback orchestration.
46
+ - Data Entry 6D7: hardened Core `TreeSelect` around its actual native-select implementation. Hierarchical data is now readonly, `title` is explicitly string text instead of a ReactNode that could stringify to `[object Object]`, single/multiple values retain native selection semantics, placeholder copy is caller-owned, hierarchy indentation is non-verbal whitespace, and the component now forwards the real select ref with canonical size/status, disabled and standard DOM/form/ARIA ownership. Search, async tree loading, checkbox selection, popup-tree behavior and custom node rendering remain out of scope.
47
+ - Data Entry 6D6: hardened Core `Cascader` while preserving its native per-level select architecture. `value/defaultValue/onChange` now form one path-state contract, clearing a level truncates the path instead of storing an empty key, root naming is caller-owned through standard group ARIA, and each native select uses a language-neutral numeric level name. English `Please select` / `Select` / `Level N` defaults were removed; placeholder copy is caller-owned. The component now supports readonly option trees, canonical control sizing/status, disabled semantics, stable slots and a real root ref without adding search, async loading or custom-panel feature bags.
48
+ - Data Entry 6D5: hardened Core `Transfer` around one target-key state contract with stable item keys, caller-owned list/operation labels, disabled-item protection, preserved opposite-side selection, grouped list semantics, standard root DOM/ARIA/ref ownership and same-source Showcase coverage. The documented canonical path always provides `titles`/`operations`; pre-6D5 omitted labels remain a narrow compatibility bridge that injects no English list copy. Search, pagination, remote data and business collection rules remain product-owned.
49
+ - Data Entry 6D4: hardened Core `Mentions` while preserving native multiline textarea/textbox semantics. `value/defaultValue/onChange` now form one string-state contract; literal prefixes drive local option filtering; suggestions are associated through standard autocomplete/listbox ARIA and support ArrowUp/ArrowDown/Enter/Escape selection. The component forwards the real textarea ref and reuses canonical Textarea sizing, validation status, count and native form/ARIA behavior. Remote search, debounce, user-resource loading and rich-token orchestration remain caller-owned.
50
+ - Data Entry 6D3: hardened Core `InputOTP` around one digit-string value contract with caller-owned group naming, language-neutral numeric slot names, real root ref, canonical `small/middle/large` sizing, explicit `error/warning` status, digit sanitization, multi-digit paste distribution, automatic forward focus, empty-slot Backspace retreat and Arrow/Home/End positional navigation. Business verification, resend timers and completion policy remain product-owned.
51
+ - Data Entry 6D2: hardened Core `Slider` and `Rate` without expanding them into feature bags. Slider remains a thin native `input[type=range]` control and now exposes the real input ref, stable slot and governed focus treatment while preserving platform range/form/keyboard semantics. Rate now uses caller-owned standard ARIA on its `radiogroup`, language-neutral numeric radio names, real root ref, stable slots, click-to-clear behavior and one roving-focus Arrow/Home/End keyboard selection model.
52
+ - Data Entry 6D1: hardened Core `AutoComplete` around an accessible combobox/listbox contract with string shorthand or explicit `{ value, label, disabled }` options, caller-owned empty-state content, canonical `small/middle/large` sizing, explicit `error/warning` status, composed native input events, disabled-option keyboard skipping, real input ref and stable semantic slots. The existing `value/defaultValue/onChange` text state remains the single input value contract; `onSelect` reports confirmed suggestions without replacing `onChange`.
53
+ - Data Entry 6C2: hardened Core `DateRangePicker` as a two-native-input compound control. The root now owns only range composition/layout while `startInputProps` and `endInputProps` independently own each date input's native attributes, form identity, ARIA naming, constraints and optional ref; canonical `size/status`, root ref, stable slots and same-source Showcase/tests are included without changing the established controlled `start/end/onChange` state model.
54
+ - Data Entry 6C1: hardened Core `TimePicker` and `ColorPicker` while preserving native `input[type=time]` / `input[type=color]` semantics; both now share canonical `small/middle/large` control sizing, explicit `error/warning` status, standard DOM/ARIA extension, real input refs, stable `data-slot` anatomy, same-source Showcase examples and focused certification tests.
55
+ - Layout 6B2: hardened Core `Splitter` around canonical `Splitter.Panel` compound composition with multiple panels, controlled/uncontrolled size vectors, per-panel constraints, pointer/keyboard resizing, resize lifecycle and separator ARIA; the established two-panel `first/second/defaultSize/min/max/onResize(number)` path remains deprecated-compatible rather than removed.
56
+ - General/Layout 6B1: hardened Core `Avatar` and `Grid`; Avatar now follows canonical `small/middle/large | number` sizing while retaining deprecated `sm/default/lg` compatibility, exposes Group/Badge/Count compound anatomy, and Grid retains its simple helper while adding responsive 24-column `Row`/`Col`.
57
+ - General/Layout 6A: hardened Core `Icon`, `Kbd`, `Flex` and `Separator` with ref-safe native contracts, standard ARIA, mature layout/line capabilities, semantic slots, same-source Showcase examples and focused certification tests.
58
+ - Core reviewed-completion continues independently from runtime-family coverage; no established Core family is removed merely to raise completion percentages.
59
+
60
+ ### Breaking
61
+
62
+ - `BackTop` now requires caller-owned `aria-label` and actually remains unrendered until `window.scrollY` reaches `visibilityHeight`; Core no longer injects the English `Back to top` label.
63
+ - `Watermark.content` is now required; Core no longer defaults generic watermarks to `Gouno`.
64
+ - `FloatButton` now requires `icon` and no longer injects a default `↑` glyph. Accessible names should be supplied with standard `aria-label` / `aria-labelledby`; `tooltip` renders visual Tooltip content and is not an implicit naming API.
65
+ - `TourStep.target` is removed because Core never implemented target positioning/highlighting. `Tour` now requires caller-owned `previousText`, `nextText`, and `finishText` instead of injecting English copy; the visible step title names the modal dialog.
66
+ - `Icon.label` is replaced by the standard `aria-label` / `aria-labelledby` accessible-name path.
67
+ - `TimePicker.size` and `ColorPicker.size` now mean canonical Gouno control size (`small | middle | large`) rather than the native numeric input `size` attribute; the native numeric attribute is not meaningful for these picker controls and is intentionally excluded from the public contract.
68
+ - `DateRangePicker` no longer copies one top-level set of input attributes to both date inputs or injects English `Start date` / `End date` accessible names. Per-input `id`, `name`, ARIA, constraints, events and refs belong under `startInputProps` / `endInputProps`; the root accepts normal div attributes. Existing `start`, `end` and `onChange` remain the range state contract.
69
+ - `AutoComplete` no longer injects `No options` or reuses the native numeric input `size` attribute. Empty-state copy is opt-in through `emptyText`; `size` now follows Gouno `ControlSize`. The component-owned suggestion `onSelect(value, option)` intentionally replaces the native text-selection event of the same React prop name; consumers needing text-selection behavior should handle it through their surrounding input workflow rather than a second `onSelect` meaning.
70
+ - `Rate.label` and injected English item names such as `"4 stars"` are removed. Name the rating group with standard `aria-label` / `aria-labelledby`; each radio now exposes its language-neutral numeric value within that named group. This avoids Core-owned locale copy while retaining one `value/defaultValue/onChange` rating state contract.
71
+ - `InputOTP.ariaLabel` and injected English names such as `"One-time password"` / `"Digit 1"` are removed. Name the OTP group with standard `aria-label` / `aria-labelledby`; individual digit fields expose numeric position names within that context. `InputOTP` now owns one digit-string `value/defaultValue/onChange` contract and standard root DOM/ref semantics rather than a non-standard naming prop.
72
+ - `Mentions.onChange` now reports the complete text string instead of exposing the native textarea `ChangeEvent`, making controlled and uncontrolled text ownership explicit. `Mentions.onSelect` remains the single suggestion-confirmation callback and intentionally excludes the native textarea text-selection event of the same prop name. The component retains native multiline textbox semantics rather than overriding the textarea with a single-line combobox role.
73
+
74
+ ## [0.2.0] - 2026-09-10
75
+
76
+ `0.2.0` is the first product-validated release after the initial standalone package. It intentionally contains pre-1.0 breaking API corrections. See [`docs/migration.md`](docs/migration.md) for consumer migration details.
77
+
78
+ ### Added
79
+
80
+ - Added the completed Gosso Admin, Blog Admin and Gouno Blog public Showcase corpora as live regression and abstraction evidence rather than simulated product demos.
81
+ - Added canonical Core `CodeBlock` after independent Blog article and Showcase evidence converged on the same read-only code/copy contract; syntax highlighting remains caller-owned.
82
+ - Added canonical Pattern `BulkActionBar` after multiple independent Blog Admin collection workflows proved one stable selection-toolbar interaction. It is the only currently admitted Pattern.
83
+ - Added product-driven governance for abstraction admission, API conformance, design language, Core retention and runtime-family coverage.
84
+ - Added a zero-pending Core runtime-family gate: every PascalCase Core runtime export must map to a visible Core Showcase family and cannot remain `needs-review` or `unassigned`.
85
+ - Added focused behavior, accessibility, API-documentation, architecture, product-fixture and source-trust regression coverage across the validated component surface.
86
+
87
+ ### Changed
88
+
89
+ - Formalized the public dependency/ownership chain as `Core -> Theme -> Patterns -> Gouno`; the package root remains a compatibility umbrella rather than a fifth owner.
90
+ - Curated package entry points and explicit symbol manifests; canonical implementation and Showcase consume formal layer entry points rather than source-directory wildcards or the root umbrella.
91
+ - Quarantined `src/legacy` outside canonical builds, publication, Showcase and dependency flow. Legacy is prior art only, not a compatibility layer or naming precedent.
92
+ - Re-admitted only evidence-backed Gouno structure: `AppShell`, `PageContainer`, `PageHeader`, `NavigationGroup` and `navigationItemClass`.
93
+ - Hardened Tabs around one high-level state contract: `activeKey`, `defaultActiveKey`, `items[].key`, `onChange`. Primitive `Tab` / `TabPanel value` remains only the composition key. Standard `aria-label` / `aria-labelledby` is canonical; `ariaLabel` remains temporarily as an explicit deprecated bridge for atomic real-product artifact upgrades.
94
+ - Hardened `Steps` and `Menu` around stable keys, explicit selection/expansion state, hierarchical navigation and keyboard/accessibility behavior without compatibility feature bags or injected English accessible copy.
95
+ - Hardened `Empty`, `Result`, `Skeleton`, `QRCode`, `Statistic`, `Spin` and `Spinner` so product copy, live-region policy, surface/elevation and standard DOM/ARIA ownership stay explicit rather than being injected as hidden defaults.
96
+ - Hardened `Segmented`, `Anchor`, `Alert`, `Modal`, `Card`, Table row-action composition and other Core families from real product pressure tests while keeping domain orchestration product-owned.
97
+ - Standardized compound spacing and surface ownership: parents own structural spacing between semantic slots; content regions own internal padding/rhythm; Tabs indicators stay inside the TabList scroll boundary.
98
+ - Standardized semantic elevation roles and product-surface rules, replacing ad-hoc page-level shadow-size decisions with governed `control`, `surface`, `raised`, `overlay` and `modal` responsibilities.
99
+ - Assigned retained convenience/compound APIs to canonical families without deleting them merely for low usage: `SearchField -> Input`, `CheckboxField -> Checkbox`, `AvatarImage`/`AvatarFallback -> Avatar`, `Divider -> Separator`, `App`/`Container`/`AspectRatio`/`Stack` remain retained and assigned to their canonical Layout/Flex families.
100
+ - Upgraded the verification/publish baseline to Node.js 24 with immutable SHA-pinned GitHub Actions; main must pass typecheck, the complete test suite, package build and Showcase build before Pages publication.
101
+
102
+ ### Removed / Breaking
103
+
104
+ - Removed speculative public Pattern/Gouno surfaces that were not re-proven by real products, including the historical broad DataTable/Toast/Feedback/AsyncState/page-utility feature bags. Their Legacy snapshots remain non-public prior art only.
105
+ - Removed inert global configuration APIs such as `ConfigProvider`, `useConfig` and `UIConfig` when no canonical component consumed their configuration.
106
+ - Removed public source-directory wildcard subpaths and duplicate ownership/re-export paths.
107
+ - Removed duplicate Pattern-level Tabs/Pagination implementations and `SubnavTabs`; Core is the single owner.
108
+ - Removed high-level Tabs `value`, `defaultValue`, `items[].value` and `onValueChange` compatibility paths. Consumers must use the canonical keyed contract.
109
+ - Removed or renamed non-canonical compatibility inputs as documented in the migration guide, including affected Alert, Empty, Result, QRCode, Steps and Menu contracts. No aliases are added merely to preserve historical Gouno/Legacy naming.
110
+
111
+ ### Delivery
112
+
113
+ - The three completed product corpora remain in Showcase as comparison/regression evidence; there is intentionally no fabricated fourth-product migration line.
114
+ - Main validation now treats a phase as complete only after exact-head CI passes and the matching Showcase commit is published to `gh-pages`.
115
+
116
+ ## [0.1.0] - 2026-09-05
117
+
118
+ ### Added
119
+
120
+ - Initial standalone `@gouno/ui` package with semantic themes, local fonts, accessible Radix-based primitives, Core components, reusable Patterns, Gouno product templates, and a static Showcase.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gouno UI contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # @gouno/ui
2
+
3
+ Shared React UI system for the Gouno product family: product-agnostic Core, dedicated Theme, product-driven Pattern/Gouno abstractions, and a static Showcase used as component documentation plus real-page validation.
4
+
5
+ **Live Showcase:** https://rushairer.github.io/gouno-ui/
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @gouno/ui
11
+ ```
12
+
13
+ `@gouno/ui` is published as an immutable public npm package. Gouno products should initially pin an exact version and upgrade it through a normal dependency PR rather than tracking mutable archives or repository branches.
14
+
15
+ For Tailwind CSS v4 consumers, import Tailwind once, then the canonical tokens/base styles, and register the package dist directory as a Tailwind source:
16
+
17
+ ```css
18
+ @import "tailwindcss";
19
+ @import "@gouno/ui/tokens.css";
20
+ @import "@gouno/ui/base.css";
21
+
22
+ @source "../node_modules/@gouno/ui/dist";
23
+ ```
24
+
25
+ Use the formal public entry points rather than source paths:
26
+
27
+ ```tsx
28
+ import { Button, Card } from "@gouno/ui/core";
29
+ import { ThemeProvider } from "@gouno/ui/theme";
30
+ import { BulkActionBar } from "@gouno/ui/patterns";
31
+ import { AppShell, PageContainer, PageHeader } from "@gouno/ui/gouno";
32
+ ```
33
+
34
+ React and React DOM are peer dependencies. See [`docs/releasing.md`](docs/releasing.md) for the immutable npm release contract.
35
+
36
+ ## Architecture
37
+
38
+ Formal public owners:
39
+
40
+ - `src/core` — product-agnostic controls, layout, data entry/display, navigation, feedback and overlays.
41
+ - `src/theme` — brand/theme state, persistence and controls.
42
+ - `src/patterns` — admitted reusable compound interactions. Current runtime surface: `BulkActionBar`.
43
+ - `src/gouno` — admitted Gouno product-family structure/policy. Current runtime surface: `AppShell`, `PageContainer`, `PageHeader`, `NavigationGroup`, `navigationItemClass`.
44
+
45
+ ```text
46
+ components/primitives + lib → Core → Theme → Patterns → Gouno
47
+ ```
48
+
49
+ `src/legacy` has been removed from the current source tree. Historical implementations live in Git history; do not recreate a Legacy, Candidates or Incubator source layer.
50
+
51
+ See [`docs/architecture.md`](docs/architecture.md) and [`docs/product-driven-development.md`](docs/product-driven-development.md).
52
+
53
+ ## Public entry points
54
+
55
+ ```ts
56
+ import { Button, CodeBlock, Pagination, Table, Tabs } from "@gouno/ui/core";
57
+ import { ThemeProvider, ThemeToggle, useTheme } from "@gouno/ui/theme";
58
+ import { BulkActionBar } from "@gouno/ui/patterns";
59
+ import { AppShell, PageContainer, PageHeader } from "@gouno/ui/gouno";
60
+ ```
61
+
62
+ `BulkActionBar` is the first admitted Pattern. It was extracted only after three independently rebuilt Blog Admin workflows (Posts, Comments and Categories) converged on the same selection-aware toolbar interaction. Its API intentionally excludes resource-specific or AI-specific shortcuts.
63
+
64
+ `CodeBlock` was admitted to Core only after the real Blog article renderer independently proved the same read-only code frame, horizontal overflow and copy-feedback contract that Showcase had previously exercised privately. Core deliberately does not own a syntax highlighter; consumers may inject token rendering through `renderCode(code)` while `code` remains the sole display/copy source.
65
+
66
+ The root `@gouno/ui` is an external compatibility umbrella, not a fifth owner. Repository implementation and Showcase import canonical formal layers instead. Source wildcard paths and historical Legacy package paths are not public API.
67
+
68
+ ## Product-driven evolution
69
+
70
+ Three real product corpora are now closed as comparison evidence:
71
+
72
+ - **Gosso Admin** — completed first-product corpus after route coverage plus product-language convergence.
73
+ - **Blog Admin** — completed second-product corpus after route coverage plus behavior/detail fidelity hardening.
74
+ - **Gouno Blog public site** — completed third-product corpus after PublicShell/Home, discovery, reading, document, account and final NotFound route-family validation.
75
+ - **No active fourth-product migration line is selected.** New product migration starts only when a real independently owned product/page family is chosen, or when a completed corpus exposes a genuine canonical defect that requires reopening a component or fixture.
76
+
77
+ Pages still start Core-first with Theme, admitted Gouno structure where semantics match, and local composition. Public-site document/content shells are not forced into `AppShell` merely for visual consistency. Small repetition is preferred over premature extraction, and the third semantically equivalent occurrence still triggers review rather than automatic extraction.
78
+
79
+ Before a Pattern/Gouno addition or material Core extension, compare canonical UI, relevant Git history when historical prior art is useful, and matching real product cases across all completed corpora. Durable decisions live in [`docs/abstraction-register.md`](docs/abstraction-register.md); public naming/state/composition rules live in [`docs/api-specification.md`](docs/api-specification.md).
80
+
81
+ Current admitted abstractions demonstrate the process rather than a fixed catalog: `AppShell`/`PageContainer` were the initial shell baseline; `PageHeader` was re-admitted only after real page evidence; `BulkActionBar` became the first Pattern only after three different migrated collection workflows proved a smaller shared interaction than the surrounding page structures; `CodeBlock` moved from Showcase-private tooling into Core only when the public Blog reading path supplied independent product demand.
82
+
83
+ ## Showcase role
84
+
85
+ Showcase separates product workspace from design-system ownership:
86
+
87
+ - **Gouno UI** — canonical `Core / Theme / Patterns / Gouno` documentation.
88
+ - **Gosso Admin** — completed first-product comparison corpus.
89
+ - **Blog Admin** — completed second-product comparison corpus.
90
+ - **Blog** — completed third-product public-site comparison corpus.
91
+
92
+ There is currently no active product workspace receiving page-by-page migration. Completed workspaces stay live as regression/comparison evidence and may be reopened only when a real new product or a discovered canonical defect creates demand.
93
+
94
+ Showcase dogfoods admitted canonical APIs. `CodeBlock` is now a canonical Core component, while Showcase's Prism renderer remains a private adapter layered on top of it. API tables, demo framing, viewport simulation and similar documentation tooling remain private; Showcase-only repetition is supporting evidence and cannot create another public abstraction by itself.
95
+
96
+ Every PascalCase Core runtime export is now assigned to a visible Core Showcase family. The coverage gate rejects `needs-review` and `unassigned` entries; established Core APIs follow the explicit retention policy rather than being removed solely because no current product calls them.
97
+
98
+ ## Tabs
99
+
100
+ Core Tabs uses a mature high-level contract while retaining Radix-backed accessibility/composition:
101
+
102
+ ```tsx
103
+ <Tabs
104
+ aria-label="Account sections"
105
+ activeKey={activeKey}
106
+ items={[
107
+ { key: "profile", label: "Profile" },
108
+ { key: "security", label: "Security" },
109
+ ]}
110
+ onChange={setActiveKey}
111
+ />
112
+ ```
113
+
114
+ Canonical state names are `activeKey`, `defaultActiveKey`, `items[].key`, `onChange`. The pre-reset high-level `value`, `defaultValue` and `items[].value` compatibility inputs have been removed. Primitive `Tab`/`TabPanel` still use `value` only as their composition key. Standard `aria-label` / `aria-labelledby` is canonical; `ariaLabel` remains temporarily as an explicitly deprecated real-product migration bridge until vendored artifacts are refreshed. The default `type="line"` uses a lightweight ink-bar style; `type="card"` is explicit. See [`docs/migration.md`](docs/migration.md) for the breaking migration details.
115
+
116
+ ## Neutral application structure
117
+
118
+ ```tsx
119
+ <AppShell brand="GOSSO" navigation={renderNavigation}>
120
+ <PageContainer>
121
+ <PageHeader
122
+ title="OAuth2 客户端"
123
+ description="管理客户端注册与授权配置。"
124
+ actions={<Button>注册客户端</Button>}
125
+ />
126
+ <RouteContent />
127
+ </PageContainer>
128
+ </AppShell>
129
+ ```
130
+
131
+ `AppShell` owns application chrome, `PageContainer` owns content width/rhythm, and `PageHeader` owns only page title/description/actions presentation. Routing, authentication, permissions, filtering, tables and business state stay in the consuming product unless separately admitted.
132
+
133
+ ## Build and verification
134
+
135
+ ```bash
136
+ npm ci
137
+ npm run release:check
138
+ ```
139
+
140
+ `release:check` runs typecheck, the full test suite, package build, Showcase build and the publication-surface check. `npm run package:check` additionally verifies that formal entry points load from `dist` and that `npm pack --dry-run` contains the required public files without leaking source, Showcase, docs, scripts or workflow internals.
141
+
142
+ Main CI uses the same Node.js 24 release gate before publishing Showcase to `gh-pages`. Pull requests run the same release-readiness check. Stable npm publication is tag-driven; see [`docs/releasing.md`](docs/releasing.md).
143
+
144
+ Run `npm run showcase:dev` for local documentation/product scenarios. Showcase fixtures are static: they do not authenticate, read cookies, call APIs or mutate real application state.
package/dist/base.css ADDED
@@ -0,0 +1,239 @@
1
+ @font-face {
2
+ font-family: "Inter Variable";
3
+ font-style: normal;
4
+ font-weight: 100 900;
5
+ font-display: swap;
6
+ src: url("./fonts/inter-latin-wght-normal.woff2") format("woff2");
7
+ }
8
+ @font-face {
9
+ font-family: "JetBrains Mono";
10
+ font-style: normal;
11
+ font-weight: 400;
12
+ font-display: swap;
13
+ src: url("./fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");
14
+ }
15
+ @layer base {
16
+ * {
17
+ border-color: var(--border);
18
+ }
19
+ html {
20
+ color-scheme: light dark;
21
+ scroll-padding-top: 80px;
22
+ }
23
+ body {
24
+ margin: 0;
25
+ background: var(--background);
26
+ color: var(--foreground);
27
+ font-family: var(--font-sans);
28
+ font-size: 14px;
29
+ line-height: 1.6;
30
+ -webkit-font-smoothing: antialiased;
31
+ }
32
+ body,
33
+ #root {
34
+ min-height: 100vh;
35
+ }
36
+ button,
37
+ input,
38
+ select,
39
+ textarea {
40
+ font: inherit;
41
+ }
42
+ button:not(:disabled),
43
+ [role="button"]:not([aria-disabled="true"]) {
44
+ cursor: pointer;
45
+ }
46
+ :focus-visible {
47
+ outline: 2px solid var(--ring);
48
+ outline-offset: 3px;
49
+ }
50
+ ::selection {
51
+ background: var(--accent);
52
+ color: var(--accent-foreground);
53
+ }
54
+ img {
55
+ max-width: 100%;
56
+ }
57
+ pre,
58
+ code,
59
+ kbd {
60
+ font-family: var(--font-mono);
61
+ }
62
+ th {
63
+ text-align: start;
64
+ }
65
+ [data-slot="table-head"] {
66
+ color: var(--muted-foreground);
67
+ }
68
+ [data-slot="table-cell"],
69
+ [data-slot="table-head"] {
70
+ box-sizing: border-box;
71
+ padding: 12px 16px;
72
+ }
73
+ [data-slot="table-head"] {
74
+ height: 40px;
75
+ }
76
+ [data-slot="table-row"]:hover {
77
+ background: var(--muted);
78
+ }
79
+ [data-slot="dialog-overlay"],
80
+ [data-slot="sheet-overlay"],
81
+ [data-slot="alert-dialog-overlay"] {
82
+ background: var(--overlay);
83
+ }
84
+ [data-slot="dialog-content"] {
85
+ max-height: 92dvh;
86
+ overflow-y: auto;
87
+ }
88
+ [data-slot="sheet-content"] {
89
+ max-height: 100dvh;
90
+ overflow-y: auto;
91
+ }
92
+ [data-slot="dialog-content"] {
93
+ width: calc(100% - 32px);
94
+ }
95
+ [data-slot="button"] {
96
+ border-radius: var(--radius-control);
97
+ }
98
+ [data-slot="button"] svg {
99
+ width: 16px;
100
+ height: 16px;
101
+ flex-shrink: 0;
102
+ }
103
+ @media (max-width: 767px) {
104
+ [data-slot="button"],
105
+ [data-slot="input"],
106
+ [data-slot="select-trigger"] {
107
+ min-height: 44px;
108
+ }
109
+ }
110
+ @media (prefers-reduced-motion: reduce) {
111
+ *,
112
+ *::before,
113
+ *::after {
114
+ animation-duration: 0s;
115
+ transition-duration: 0s;
116
+ scroll-behavior: auto;
117
+ }
118
+ }
119
+ }
120
+
121
+ @keyframes gouno-carousel-dot {
122
+ from {
123
+ transform: scaleX(0);
124
+ }
125
+ to {
126
+ transform: scaleX(1);
127
+ }
128
+ }
129
+
130
+ @layer components {
131
+ .form-layout--horizontal .field {
132
+ display: grid;
133
+ grid-template-columns: minmax(8rem, 12rem) minmax(0, 1fr);
134
+ align-items: start;
135
+ column-gap: 16px;
136
+ }
137
+ .form-layout--horizontal .field > [data-slot="field-label"] {
138
+ padding-top: 8px;
139
+ text-align: end;
140
+ }
141
+ .form-layout--horizontal .field > [data-slot="field-description"],
142
+ .form-layout--horizontal .field > [data-slot="field-error"] {
143
+ grid-column: 2;
144
+ }
145
+ @media (max-width: 767px) {
146
+ .form-layout--horizontal .field {
147
+ display: flex;
148
+ flex-direction: column;
149
+ gap: 6px;
150
+ }
151
+ .form-layout--horizontal .field > [data-slot="field-label"] {
152
+ padding-top: 0;
153
+ text-align: start;
154
+ }
155
+ }
156
+ [data-slot="table-container"][data-density="compact"]
157
+ [data-slot="table-head"] {
158
+ height: 36px;
159
+ padding: 8px 12px;
160
+ }
161
+ [data-slot="table-container"][data-density="compact"]
162
+ [data-slot="table-cell"] {
163
+ padding: 8px 12px;
164
+ }
165
+ [data-slot="table-container"][data-density="touch"] [data-slot="table-head"] {
166
+ height: 48px;
167
+ padding: 14px 16px;
168
+ }
169
+ [data-slot="table-container"][data-density="touch"] [data-slot="table-cell"] {
170
+ padding: 14px 16px;
171
+ }
172
+
173
+ /* Icon-only actions share one size, optical center, and state treatment. */
174
+ .icon-button {
175
+ display: inline-flex;
176
+ width: 36px;
177
+ height: 36px;
178
+ min-height: 36px;
179
+ align-items: center;
180
+ justify-content: center;
181
+ padding: 0;
182
+ line-height: 1;
183
+ }
184
+
185
+ .icon-button > .btn__icon {
186
+ display: inline-flex;
187
+ width: 16px;
188
+ height: 16px;
189
+ align-items: center;
190
+ justify-content: center;
191
+ line-height: 1;
192
+ }
193
+
194
+ .icon-button > .btn__icon > svg {
195
+ display: block;
196
+ width: 16px;
197
+ height: 16px;
198
+ flex: 0 0 16px;
199
+ }
200
+ }
201
+
202
+ @layer components {
203
+ /* Core 24-column Row/Col responsive contract. */
204
+ [data-slot="col"] {
205
+ box-sizing: border-box;
206
+ position: relative;
207
+ flex: 0 0 var(--gouno-col-basis);
208
+ max-width: var(--gouno-col-basis);
209
+ margin-inline-start: var(--gouno-col-offset);
210
+ inset-inline-start: var(--gouno-col-shift);
211
+ order: var(--gouno-col-order);
212
+ }
213
+ [data-slot="col"][data-span="0"] { display: none; }
214
+ @media (min-width: 640px) {
215
+ [data-slot="col"] { flex-basis: var(--gouno-col-sm-basis); max-width: var(--gouno-col-sm-basis); margin-inline-start: var(--gouno-col-sm-offset); inset-inline-start: var(--gouno-col-sm-shift); order: var(--gouno-col-sm-order); }
216
+ [data-slot="col"][data-sm-span="0"] { display: none; }
217
+ [data-slot="col"]:not([data-sm-span="0"]) { display: block; }
218
+ }
219
+ @media (min-width: 768px) {
220
+ [data-slot="col"] { flex-basis: var(--gouno-col-md-basis); max-width: var(--gouno-col-md-basis); margin-inline-start: var(--gouno-col-md-offset); inset-inline-start: var(--gouno-col-md-shift); order: var(--gouno-col-md-order); }
221
+ [data-slot="col"][data-md-span="0"] { display: none; }
222
+ [data-slot="col"]:not([data-md-span="0"]) { display: block; }
223
+ }
224
+ @media (min-width: 1024px) {
225
+ [data-slot="col"] { flex-basis: var(--gouno-col-lg-basis); max-width: var(--gouno-col-lg-basis); margin-inline-start: var(--gouno-col-lg-offset); inset-inline-start: var(--gouno-col-lg-shift); order: var(--gouno-col-lg-order); }
226
+ [data-slot="col"][data-lg-span="0"] { display: none; }
227
+ [data-slot="col"]:not([data-lg-span="0"]) { display: block; }
228
+ }
229
+ @media (min-width: 1280px) {
230
+ [data-slot="col"] { flex-basis: var(--gouno-col-xl-basis); max-width: var(--gouno-col-xl-basis); margin-inline-start: var(--gouno-col-xl-offset); inset-inline-start: var(--gouno-col-xl-shift); order: var(--gouno-col-xl-order); }
231
+ [data-slot="col"][data-xl-span="0"] { display: none; }
232
+ [data-slot="col"]:not([data-xl-span="0"]) { display: block; }
233
+ }
234
+ @media (min-width: 1536px) {
235
+ [data-slot="col"] { flex-basis: var(--gouno-col-xxl-basis); max-width: var(--gouno-col-xxl-basis); margin-inline-start: var(--gouno-col-xxl-offset); inset-inline-start: var(--gouno-col-xxl-shift); order: var(--gouno-col-xxl-order); }
236
+ [data-slot="col"][data-xxl-span="0"] { display: none; }
237
+ [data-slot="col"]:not([data-xxl-span="0"]) { display: block; }
238
+ }
239
+ }
@@ -0,0 +1,22 @@
1
+ /* Same-origin, parser-blocking bootstrap. No auth state is read or written. */
2
+ (() => {
3
+ const script = document.currentScript;
4
+ const key = script?.dataset.storageKey || "gouno-blog:theme";
5
+ let mode = "system";
6
+ try {
7
+ const stored = localStorage.getItem(key);
8
+ if (stored === "light" || stored === "dark") mode = stored;
9
+ } catch {}
10
+ const resolved =
11
+ mode === "system"
12
+ ? window.matchMedia("(prefers-color-scheme: dark)").matches
13
+ ? "dark"
14
+ : "light"
15
+ : mode;
16
+ const root = document.documentElement;
17
+ root.dataset.theme = resolved;
18
+ root.dataset.brand =
19
+ script?.dataset.brand ||
20
+ (/^\/admin(?:\/|$)/.test(location.pathname) ? "blog-admin" : "blog");
21
+ root.style.colorScheme = resolved;
22
+ })();
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ import { AlertDialog as AlertDialogPrimitive } from "radix-ui";
3
+ import { Button } from "./button.js";
4
+ declare function AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>): React.JSX.Element;
5
+ declare function AlertDialogTrigger({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>): React.JSX.Element;
6
+ declare function AlertDialogPortal({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>): React.JSX.Element;
7
+ declare function AlertDialogOverlay({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>): React.JSX.Element;
8
+ declare function AlertDialogContent({ className, size, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {
9
+ size?: "default" | "sm";
10
+ }): React.JSX.Element;
11
+ declare function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
12
+ declare function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
13
+ declare function AlertDialogTitle({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Title>): React.JSX.Element;
14
+ declare function AlertDialogDescription({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Description>): React.JSX.Element;
15
+ declare function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
16
+ declare function AlertDialogAction({ className, variant, size, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Action> & Pick<React.ComponentProps<typeof Button>, "variant" | "size">): React.JSX.Element;
17
+ declare function AlertDialogCancel({ className, variant, size, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel> & Pick<React.ComponentProps<typeof Button>, "variant" | "size">): React.JSX.Element;
18
+ export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, };
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../../lib/utils.js";
5
+ import { AlertDialog as AlertDialogPrimitive } from "radix-ui";
6
+ import { Button } from "./button.js";
7
+ function AlertDialog({ ...props }) {
8
+ return _jsx(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
9
+ }
10
+ function AlertDialogTrigger({ ...props }) {
11
+ return (_jsx(AlertDialogPrimitive.Trigger, { "data-slot": "alert-dialog-trigger", ...props }));
12
+ }
13
+ function AlertDialogPortal({ ...props }) {
14
+ return (_jsx(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props }));
15
+ }
16
+ function AlertDialogOverlay({ className, ...props }) {
17
+ return (_jsx(AlertDialogPrimitive.Overlay, { "data-slot": "alert-dialog-overlay", className: cn("fixed inset-0 z-50 bg-overlay data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0", className), ...props }));
18
+ }
19
+ function AlertDialogContent({ className, size = "default", ...props }) {
20
+ return (_jsxs(AlertDialogPortal, { children: [_jsx(AlertDialogOverlay, {}), _jsx(AlertDialogPrimitive.Content, { "data-slot": "alert-dialog-content", "data-size": size, className: cn("group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-popover p-6 shadow-modal duration-150 data-[size=sm]:max-w-xs data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[size=default]:sm:max-w-lg", className), ...props })] }));
21
+ }
22
+ function AlertDialogHeader({ className, ...props }) {
23
+ return (_jsx("div", { "data-slot": "alert-dialog-header", className: cn("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]", className), ...props }));
24
+ }
25
+ function AlertDialogFooter({ className, ...props }) {
26
+ return (_jsx("div", { "data-slot": "alert-dialog-footer", className: cn("flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end", className), ...props }));
27
+ }
28
+ function AlertDialogTitle({ className, ...props }) {
29
+ return (_jsx(AlertDialogPrimitive.Title, { "data-slot": "alert-dialog-title", className: cn("text-lg font-semibold sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className), ...props }));
30
+ }
31
+ function AlertDialogDescription({ className, ...props }) {
32
+ return (_jsx(AlertDialogPrimitive.Description, { "data-slot": "alert-dialog-description", className: cn("text-sm text-muted-foreground", className), ...props }));
33
+ }
34
+ function AlertDialogMedia({ className, ...props }) {
35
+ return (_jsx("div", { "data-slot": "alert-dialog-media", className: cn("mb-2 inline-flex size-16 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8", className), ...props }));
36
+ }
37
+ function AlertDialogAction({ className, variant = "default", size = "default", ...props }) {
38
+ return (_jsx(Button, { variant: variant, size: size, asChild: true, children: _jsx(AlertDialogPrimitive.Action, { "data-slot": "alert-dialog-action", className: cn(className), ...props }) }));
39
+ }
40
+ function AlertDialogCancel({ className, variant = "outline", size = "default", ...props }) {
41
+ return (_jsx(Button, { variant: variant, size: size, asChild: true, children: _jsx(AlertDialogPrimitive.Cancel, { "data-slot": "alert-dialog-cancel", className: cn(className), ...props }) }));
42
+ }
43
+ export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, };
@@ -0,0 +1,9 @@
1
+ import * as React from "react";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ declare const alertVariants: (props?: ({
4
+ variant?: "default" | "destructive" | null | undefined;
5
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
+ declare function Alert({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>): React.JSX.Element;
7
+ declare function AlertTitle({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
8
+ declare function AlertDescription({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
9
+ export { Alert, AlertTitle, AlertDescription };