@askrjs/themes 0.0.19 → 0.0.21

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 (202) hide show
  1. package/README.md +24 -3
  2. package/THEMING.md +11 -4
  3. package/dist/components/_internal/block-layout.js +1 -1
  4. package/dist/components/_internal/block-layout.js.map +1 -1
  5. package/dist/components/_internal/style.js +9 -21
  6. package/dist/components/_internal/style.js.map +1 -1
  7. package/dist/components/grid/grid.js +5 -42
  8. package/dist/components/grid/grid.js.map +1 -1
  9. package/dist/components/jsx-types.d.ts +0 -3
  10. package/dist/components/theme/theme.js +11 -12
  11. package/dist/components/theme/theme.js.map +1 -1
  12. package/dist/entries/accordion.d.ts +1 -0
  13. package/dist/entries/accordion.js +1 -0
  14. package/dist/entries/alert-dialog.d.ts +1 -0
  15. package/dist/entries/alert-dialog.js +1 -0
  16. package/dist/entries/alert.d.ts +4 -0
  17. package/dist/entries/alert.js +2 -0
  18. package/dist/entries/aspect-ratio.d.ts +4 -0
  19. package/dist/entries/aspect-ratio.js +2 -0
  20. package/dist/entries/avatar.d.ts +1 -0
  21. package/dist/entries/avatar.js +1 -0
  22. package/dist/entries/badge.d.ts +4 -0
  23. package/dist/entries/badge.js +2 -0
  24. package/dist/entries/breadcrumb.d.ts +2 -0
  25. package/dist/entries/breadcrumb.js +2 -0
  26. package/dist/entries/button-group.d.ts +4 -0
  27. package/dist/entries/button-group.js +2 -0
  28. package/dist/entries/button.d.ts +1 -0
  29. package/dist/entries/button.js +1 -0
  30. package/dist/entries/calendar.d.ts +2 -0
  31. package/dist/entries/calendar.js +2 -0
  32. package/dist/entries/card.d.ts +4 -0
  33. package/dist/entries/card.js +2 -0
  34. package/dist/entries/carousel.d.ts +2 -0
  35. package/dist/entries/carousel.js +2 -0
  36. package/dist/entries/checkbox.d.ts +1 -0
  37. package/dist/entries/checkbox.js +1 -0
  38. package/dist/entries/collapsible.d.ts +1 -0
  39. package/dist/entries/collapsible.js +1 -0
  40. package/dist/entries/combobox.d.ts +2 -0
  41. package/dist/entries/combobox.js +2 -0
  42. package/dist/entries/command.d.ts +2 -0
  43. package/dist/entries/command.js +2 -0
  44. package/dist/entries/context-menu.d.ts +3 -0
  45. package/dist/entries/context-menu.js +3 -0
  46. package/dist/entries/data-table.d.ts +2 -0
  47. package/dist/entries/data-table.js +2 -0
  48. package/dist/entries/date-picker.d.ts +2 -0
  49. package/dist/entries/date-picker.js +2 -0
  50. package/dist/entries/dialog.d.ts +1 -0
  51. package/dist/entries/dialog.js +1 -0
  52. package/dist/entries/direction.d.ts +2 -0
  53. package/dist/entries/direction.js +2 -0
  54. package/dist/entries/drawer.d.ts +2 -0
  55. package/dist/entries/drawer.js +2 -0
  56. package/dist/entries/dropdown-menu.d.ts +3 -0
  57. package/dist/entries/dropdown-menu.js +3 -0
  58. package/dist/entries/empty.d.ts +2 -0
  59. package/dist/entries/empty.js +2 -0
  60. package/dist/entries/field.d.ts +4 -0
  61. package/dist/entries/field.js +2 -0
  62. package/dist/entries/form.d.ts +1 -0
  63. package/dist/entries/form.js +1 -0
  64. package/dist/entries/hover-card.d.ts +1 -0
  65. package/dist/entries/hover-card.js +1 -0
  66. package/dist/entries/input-group.d.ts +4 -0
  67. package/dist/entries/input-group.js +2 -0
  68. package/dist/entries/input-otp.d.ts +2 -0
  69. package/dist/entries/input-otp.js +2 -0
  70. package/dist/entries/input.d.ts +1 -0
  71. package/dist/entries/input.js +1 -0
  72. package/dist/entries/item.d.ts +2 -0
  73. package/dist/entries/item.js +2 -0
  74. package/dist/entries/kbd.d.ts +2 -0
  75. package/dist/entries/kbd.js +2 -0
  76. package/dist/entries/label.d.ts +1 -0
  77. package/dist/entries/label.js +1 -0
  78. package/dist/entries/menubar.d.ts +1 -0
  79. package/dist/entries/menubar.js +1 -0
  80. package/dist/entries/native-select.d.ts +2 -0
  81. package/dist/entries/native-select.js +2 -0
  82. package/dist/entries/navigation-menu.d.ts +2 -0
  83. package/dist/entries/navigation-menu.js +2 -0
  84. package/dist/entries/pagination.d.ts +2 -0
  85. package/dist/entries/pagination.js +2 -0
  86. package/dist/entries/popover.d.ts +1 -0
  87. package/dist/entries/popover.js +1 -0
  88. package/dist/entries/progress.d.ts +1 -0
  89. package/dist/entries/progress.js +1 -0
  90. package/dist/entries/radio-group.d.ts +1 -0
  91. package/dist/entries/radio-group.js +1 -0
  92. package/dist/entries/resizable.d.ts +2 -0
  93. package/dist/entries/resizable.js +2 -0
  94. package/dist/entries/scroll-area.d.ts +1 -0
  95. package/dist/entries/scroll-area.js +1 -0
  96. package/dist/entries/select.d.ts +1 -0
  97. package/dist/entries/select.js +1 -0
  98. package/dist/entries/separator.d.ts +4 -0
  99. package/dist/entries/separator.js +2 -0
  100. package/dist/entries/sheet.d.ts +3 -0
  101. package/dist/entries/sheet.js +3 -0
  102. package/dist/entries/sidebar.d.ts +4 -0
  103. package/dist/entries/sidebar.js +2 -0
  104. package/dist/entries/skeleton.d.ts +4 -0
  105. package/dist/entries/skeleton.js +2 -0
  106. package/dist/entries/slider.d.ts +1 -0
  107. package/dist/entries/slider.js +1 -0
  108. package/dist/entries/sonner.d.ts +2 -0
  109. package/dist/entries/sonner.js +2 -0
  110. package/dist/entries/spinner.d.ts +4 -0
  111. package/dist/entries/spinner.js +2 -0
  112. package/dist/entries/switch.d.ts +1 -0
  113. package/dist/entries/switch.js +1 -0
  114. package/dist/entries/table.d.ts +1 -0
  115. package/dist/entries/table.js +1 -0
  116. package/dist/entries/tabs.d.ts +4 -0
  117. package/dist/entries/tabs.js +3 -0
  118. package/dist/entries/textarea.d.ts +1 -0
  119. package/dist/entries/textarea.js +1 -0
  120. package/dist/entries/toast.d.ts +1 -0
  121. package/dist/entries/toast.js +1 -0
  122. package/dist/entries/toggle-group.d.ts +1 -0
  123. package/dist/entries/toggle-group.js +1 -0
  124. package/dist/entries/toggle.d.ts +1 -0
  125. package/dist/entries/toggle.js +1 -0
  126. package/dist/entries/tooltip.d.ts +1 -0
  127. package/dist/entries/tooltip.js +1 -0
  128. package/dist/entries/typography.d.ts +2 -0
  129. package/dist/entries/typography.js +2 -0
  130. package/dist/ssr.js +23 -11
  131. package/dist/ssr.js.map +1 -1
  132. package/dist/themes/default/index.css +1 -1
  133. package/package.json +25 -240
  134. package/src/components/_internal/block-layout.ts +2 -2
  135. package/src/components/_internal/style.ts +8 -26
  136. package/src/components/grid/grid.tsx +6 -57
  137. package/src/components/jsx-types.ts +0 -5
  138. package/src/components/theme/theme.tsx +22 -22
  139. package/src/entries/accordion.ts +1 -0
  140. package/src/entries/alert-dialog.ts +1 -0
  141. package/src/entries/alert.ts +1 -0
  142. package/src/entries/aspect-ratio.ts +1 -0
  143. package/src/entries/avatar.ts +1 -0
  144. package/src/entries/badge.ts +1 -0
  145. package/src/entries/breadcrumb.ts +9 -0
  146. package/src/entries/button-group.ts +1 -0
  147. package/src/entries/button.ts +1 -0
  148. package/src/entries/calendar.ts +14 -0
  149. package/src/entries/card.ts +1 -0
  150. package/src/entries/carousel.ts +7 -0
  151. package/src/entries/checkbox.ts +1 -0
  152. package/src/entries/collapsible.ts +1 -0
  153. package/src/entries/combobox.ts +1 -0
  154. package/src/entries/command.ts +13 -0
  155. package/src/entries/context-menu.ts +10 -0
  156. package/src/entries/data-table.ts +1 -0
  157. package/src/entries/date-picker.ts +1 -0
  158. package/src/entries/dialog.ts +1 -0
  159. package/src/entries/direction.ts +1 -0
  160. package/src/entries/drawer.ts +10 -0
  161. package/src/entries/dropdown-menu.ts +10 -0
  162. package/src/entries/empty.ts +8 -0
  163. package/src/entries/field.ts +1 -0
  164. package/src/entries/form.ts +1 -0
  165. package/src/entries/hover-card.ts +1 -0
  166. package/src/entries/input-group.ts +1 -0
  167. package/src/entries/input-otp.ts +1 -0
  168. package/src/entries/input.ts +1 -0
  169. package/src/entries/item.ts +11 -0
  170. package/src/entries/kbd.ts +1 -0
  171. package/src/entries/label.ts +1 -0
  172. package/src/entries/menubar.ts +1 -0
  173. package/src/entries/native-select.ts +1 -0
  174. package/src/entries/navigation-menu.ts +10 -0
  175. package/src/entries/pagination.ts +9 -0
  176. package/src/entries/popover.ts +1 -0
  177. package/src/entries/progress.ts +1 -0
  178. package/src/entries/radio-group.ts +1 -0
  179. package/src/entries/resizable.ts +1 -0
  180. package/src/entries/scroll-area.ts +1 -0
  181. package/src/entries/select.ts +1 -0
  182. package/src/entries/separator.ts +1 -0
  183. package/src/entries/sheet.ts +14 -0
  184. package/src/entries/sidebar.ts +1 -0
  185. package/src/entries/skeleton.ts +1 -0
  186. package/src/entries/slider.ts +1 -0
  187. package/src/entries/sonner.ts +1 -0
  188. package/src/entries/spinner.ts +1 -0
  189. package/src/entries/switch.ts +1 -0
  190. package/src/entries/table.ts +1 -0
  191. package/src/entries/tabs.ts +2 -0
  192. package/src/entries/textarea.ts +1 -0
  193. package/src/entries/toast.ts +1 -0
  194. package/src/entries/toggle-group.ts +1 -0
  195. package/src/entries/toggle.ts +1 -0
  196. package/src/entries/tooltip.ts +1 -0
  197. package/src/entries/typography.ts +12 -0
  198. package/src/parity.ts +3 -3
  199. package/src/ssr.ts +45 -20
  200. package/src/themes/default/foundations.css +6 -0
  201. package/src/themes/default/tokens.css +1 -1
  202. package/templates/theme/tokens.css +1 -1
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![CI](https://github.com/askrjs/askr-themes/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/askrjs/askr-themes/actions/workflows/ci.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/%40askrjs%2Fthemes.svg)](https://www.npmjs.com/package/@askrjs/themes)
5
5
 
6
- CSS tokens and a shadcn-style styled component catalog for Askr apps.
6
+ CSS tokens and a styled component catalog for Askr apps.
7
7
 
8
8
  `@askrjs/themes` is the visual companion to `@askrjs/ui` and
9
9
  `@askrjs/charts`. It owns the default theme and styled component catalog while
@@ -31,6 +31,24 @@ curated preset family:
31
31
  @import "@askrjs/themes/presets";
32
32
  ```
33
33
 
34
+ For a small page that only uses individual controls, import their JavaScript
35
+ and CSS independently instead of the full default theme:
36
+
37
+ ```tsx
38
+ import { Input } from "@askrjs/themes/input";
39
+ import { Label } from "@askrjs/themes/label";
40
+ import "@askrjs/themes/default/foundations.css";
41
+ import "@askrjs/themes/default/input.css";
42
+ import "@askrjs/themes/default/label.css";
43
+ ```
44
+
45
+ The foundations entry contains tokens and base/reset styles. Component CSS
46
+ entries contain only that component's styles. `@askrjs/themes/default` remains
47
+ the batteries-included theme.
48
+
49
+ See [Acknowledgements](./docs/acknowledgements.md) for the open-source projects
50
+ that inspired parts of the design philosophy.
51
+
34
52
  Then set `data-theme` to `tabby`, `ginger`, `tuxedo`, `calico`, or `torty`.
35
53
  For picker/toggle composition, import `CAT_THEME_OPTIONS` and `CAT_THEME_NAMES`
36
54
  from `@askrjs/themes/theme`.
@@ -81,8 +99,11 @@ export const staticConfig = {
81
99
  };
82
100
  ```
83
101
 
84
- The wrapper also applies `context.cspNonce` to the emitted style registry.
85
- Use the same wrapper for an SSR `document` callback.
102
+ The wrapper also applies `context.cspNonce` to the emitted style registry and
103
+ requires the request-local style registrations provided by Askr 0.0.85 or
104
+ newer. It fails clearly if generated classes and their registered rules ever
105
+ diverge instead of emitting unstyled markup. Use the same wrapper for an SSR
106
+ `document` callback.
86
107
 
87
108
  ## What To Import
88
109
 
package/THEMING.md CHANGED
@@ -29,6 +29,10 @@ Token override:
29
29
  }
30
30
  ```
31
31
 
32
+ The shipped light and dark token sets are contrast-tested. Consumer token
33
+ overrides are ordinary CSS and cannot be validated by the runtime, so recheck
34
+ WCAG contrast for every overridden foreground/background pair.
35
+
32
36
  Style override:
33
37
 
34
38
  ```css
@@ -119,7 +123,7 @@ Package boundaries:
119
123
  presets, and default styling.
120
124
 
121
125
  Use `@askrjs/themes/components` for the aggregate styled catalog, or the
122
- component subpaths such as `@askrjs/themes/button`,
126
+ tree-shakeable component subpaths such as `@askrjs/themes/button`,
123
127
  `@askrjs/themes/card`, and `@askrjs/themes/dialog`. The aggregate catalog
124
128
  contains styled components such as Button, ButtonGroup, Close, InputGroup,
125
129
  Block, Container, Header, Main, Sidebar, Navbar, NavBrand, NavDropdown, Alert,
@@ -132,6 +136,9 @@ wrapped in `data-slot="theme-toggle-content"` so icon and text compositions can
132
136
  be styled consistently across themes. If you use icon children, the direct child
133
137
  icon is sized from `var(--ak-theme-toggle-icon-size, var(--ak-icon-size, 1em))`,
134
138
  so apps can override `--ak-theme-toggle-icon-size` to fit custom icon dimensions.
139
+ `ThemeName` accepts application-defined strings intentionally. Register custom
140
+ names in the scope's theme options and provide a matching `[data-theme="..."]`
141
+ token block; misspelled names otherwise remain valid custom identifiers.
135
142
  The common wrapper components also emit familiar alias classes such as
136
143
  `alert`, `btn-group`, `btn-close`, `input-group`, `tabs`, and `pills` so
137
144
  app-level CSS can stay close to familiar HTML authoring without
@@ -183,7 +190,7 @@ This contract is intentionally semantic, not component-specific.
183
190
  The token system must:
184
191
 
185
192
  - support both light and dark themes
186
- - theme headless UI primitives consistently
193
+ - theme behavior-first UI primitives consistently
187
194
  - optimize for admin and internal tools by default
188
195
  - avoid hardcoded component styling
189
196
  - provide enough semantic coverage for real apps
@@ -213,7 +220,7 @@ This spec does not:
213
220
  5. Theme blocks should only override theme-dependent values.
214
221
  6. Layout, spacing, typography scale, icon scale, and breakpoints belong in the global root unless intentionally themed.
215
222
  7. Default visual choices should reduce end-user design decisions: one accent, subtle borders, compact density, restrained radius, and minimal decorative styling.
216
- 8. The default theme should stay crisp and low-noise, closer to a shadcn-style baseline than a glossy decorative system.
223
+ 8. The default theme should stay crisp and low-noise, favoring a restrained product baseline over a glossy decorative system.
217
224
 
218
225
  ---
219
226
 
@@ -755,7 +762,7 @@ These are recommended implementation defaults for component authors:
755
762
  --ak-layout-content-max-width: 75rem;
756
763
 
757
764
  /* stacking */
758
- --ak-z-dropdown: 1000;
765
+ --ak-z-dropdown: 1500;
759
766
  --ak-z-sticky: 1100;
760
767
  --ak-z-fixed: 1200;
761
768
  --ak-z-modal-backdrop: 1300;
@@ -208,4 +208,4 @@ function mergeLayoutStyles(layout, user) {
208
208
  return mergedString || void 0;
209
209
  }
210
210
  //#endregion
211
- export { applyBlockLayoutStyles, mergeLayoutStyles, splitBlockLayoutProps };
211
+ export { applyBlockLayoutStyles, mergeLayoutStyles, resolveSpaceValue, setResponsiveVar, splitBlockLayoutProps };
@@ -1 +1 @@
1
- {"version":3,"file":"block-layout.js","names":[],"sources":["../../../src/components/_internal/block-layout.ts"],"sourcesContent":["import { serializeCssDeclarations } from \"./style\";\n\nexport type LayoutBreakpoint = \"base\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type ResponsiveValue<T> = T | Partial<Record<LayoutBreakpoint, T>>;\n\nexport type BlockSpace = \"0\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"page\";\nexport type BlockMargin = BlockSpace | \"auto\";\nexport type BlockSize =\n | \"auto\"\n | \"full\"\n | \"screen\"\n | \"content\"\n | \"sidebar\"\n | \"page\"\n | \"sm\"\n | \"md\"\n | \"lg\"\n | \"xl\";\nexport type BlockDirection = \"row\" | \"column\" | \"row-reverse\" | \"column-reverse\";\nexport type BlockRowFrom = Exclude<LayoutBreakpoint, \"base\">;\nexport type BlockAlign = \"start\" | \"end\" | \"center\" | \"stretch\" | \"baseline\";\nexport type BlockJustify = \"start\" | \"end\" | \"center\" | \"between\";\nexport type BlockBackground =\n | \"surface\"\n | \"muted\"\n | \"selected\"\n | \"canvas\"\n | \"raised\"\n | \"overlay\"\n | \"transparent\";\nexport type BlockRadius = true | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"round\";\nexport type BlockShadow = true | \"sm\" | \"md\" | \"lg\";\nexport type BlockZIndex =\n | \"header\"\n | \"sticky\"\n | \"fixed\"\n | \"dropdown\"\n | \"modal\"\n | \"popover\"\n | \"toast\"\n | \"tooltip\";\n\nexport type BlockLayoutProps = {\n padding?: ResponsiveValue<BlockSpace>;\n paddingX?: ResponsiveValue<BlockSpace>;\n paddingY?: ResponsiveValue<BlockSpace>;\n margin?: ResponsiveValue<BlockMargin>;\n marginX?: ResponsiveValue<BlockMargin>;\n marginY?: ResponsiveValue<BlockMargin>;\n width?: ResponsiveValue<BlockSize>;\n minWidth?: ResponsiveValue<BlockSize>;\n maxWidth?: ResponsiveValue<BlockSize>;\n height?: ResponsiveValue<BlockSize>;\n minHeight?: ResponsiveValue<BlockSize>;\n maxHeight?: ResponsiveValue<BlockSize>;\n rowFrom?: BlockRowFrom;\n direction?: ResponsiveValue<BlockDirection>;\n align?: ResponsiveValue<BlockAlign>;\n justify?: ResponsiveValue<BlockJustify>;\n gap?: ResponsiveValue<BlockSpace>;\n grow?: ResponsiveValue<boolean | number>;\n shrink?: ResponsiveValue<boolean | number>;\n center?: ResponsiveValue<boolean>;\n sticky?: boolean;\n top?: ResponsiveValue<BlockSpace>;\n zIndex?: ResponsiveValue<BlockZIndex>;\n background?: ResponsiveValue<BlockBackground>;\n border?: ResponsiveValue<boolean>;\n borderTop?: ResponsiveValue<boolean>;\n borderBottom?: ResponsiveValue<boolean>;\n borderRight?: ResponsiveValue<boolean>;\n radius?: ResponsiveValue<BlockRadius>;\n shadow?: ResponsiveValue<BlockShadow>;\n hide?: ResponsiveValue<boolean>;\n};\n\nconst BREAKPOINTS: readonly LayoutBreakpoint[] = [\"base\", \"sm\", \"md\", \"lg\", \"xl\"];\n\nconst SPACE_TOKEN_MAP: Record<string, string> = {\n \"0\": \"0\",\n xs: \"var(--ak-space-xs)\",\n sm: \"var(--ak-space-sm)\",\n md: \"var(--ak-space-md)\",\n lg: \"var(--ak-space-lg)\",\n xl: \"var(--ak-space-xl)\",\n \"2xl\": \"var(--ak-space-2xl)\",\n \"3xl\": \"var(--ak-space-3xl)\",\n page: \"var(--ak-layout-page-gutter)\",\n};\n\nconst SIZE_TOKEN_MAP: Record<string, string> = {\n auto: \"auto\",\n full: \"100%\",\n screen: \"100dvh\",\n content: \"min(60vh, 36rem)\",\n sidebar: \"var(--ak-layout-sidebar-width)\",\n page: \"var(--ak-layout-content-max-width)\",\n sm: \"var(--ak-container-1)\",\n md: \"var(--ak-container-2)\",\n lg: \"var(--ak-container-3)\",\n xl: \"var(--ak-container-4)\",\n};\n\nconst BACKGROUND_TOKEN_MAP: Record<string, string> = {\n canvas: \"var(--ak-color-bg)\",\n surface: \"var(--ak-color-surface)\",\n muted: \"var(--ak-color-surface-muted)\",\n raised: \"var(--ak-color-surface-raised)\",\n overlay: \"var(--ak-color-surface-overlay)\",\n selected: \"var(--ak-color-selected)\",\n transparent: \"transparent\",\n};\n\nconst RADIUS_TOKEN_MAP: Record<string, string> = {\n sm: \"var(--ak-radius-sm)\",\n md: \"var(--ak-radius-md)\",\n lg: \"var(--ak-radius-lg)\",\n xl: \"var(--ak-radius-xl)\",\n round: \"var(--ak-radius-round)\",\n};\n\nconst SHADOW_TOKEN_MAP: Record<string, string> = {\n sm: \"var(--ak-shadow-sm)\",\n md: \"var(--ak-shadow-md)\",\n lg: \"var(--ak-shadow-lg)\",\n};\n\nconst Z_INDEX_TOKEN_MAP: Record<string, string> = {\n header: \"var(--ak-z-sticky)\",\n sticky: \"var(--ak-z-sticky)\",\n fixed: \"var(--ak-z-fixed)\",\n dropdown: \"var(--ak-z-dropdown)\",\n modal: \"var(--ak-z-modal)\",\n popover: \"var(--ak-z-popover)\",\n toast: \"var(--ak-z-toast)\",\n tooltip: \"var(--ak-z-tooltip)\",\n};\n\nconst BORDER_VALUE = \"1px solid var(--ak-color-border-subtle)\";\n\nconst BLOCK_LAYOUT_KEYS = new Set<keyof BlockLayoutProps>([\n \"padding\",\n \"paddingX\",\n \"paddingY\",\n \"margin\",\n \"marginX\",\n \"marginY\",\n \"width\",\n \"minWidth\",\n \"maxWidth\",\n \"height\",\n \"minHeight\",\n \"maxHeight\",\n \"rowFrom\",\n \"direction\",\n \"align\",\n \"justify\",\n \"gap\",\n \"grow\",\n \"shrink\",\n \"center\",\n \"sticky\",\n \"top\",\n \"zIndex\",\n \"background\",\n \"border\",\n \"borderTop\",\n \"borderBottom\",\n \"borderRight\",\n \"radius\",\n \"shadow\",\n \"hide\",\n]);\n\nfunction isResponsiveValue<T>(\n value: ResponsiveValue<T> | undefined,\n): value is Partial<Record<LayoutBreakpoint, T>> {\n return Boolean(\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n BREAKPOINTS.some((breakpoint) => breakpoint in value),\n );\n}\n\nfunction normalizeResponsiveValue<T>(\n value: ResponsiveValue<T> | undefined,\n): Partial<Record<LayoutBreakpoint, T>> | undefined {\n if (value === undefined) return undefined;\n if (isResponsiveValue(value)) return value;\n return { base: value };\n}\n\nfunction resolveTokenValue(\n value: string | number,\n tokens: Record<string, string>,\n): string | number {\n if (typeof value === \"number\") return value;\n const trimmed = value.trim();\n return tokens[trimmed] ?? trimmed;\n}\n\nfunction resolveSpaceValue(value: string | number): string | number {\n return resolveTokenValue(value, SPACE_TOKEN_MAP);\n}\n\nfunction resolveSizeValue(value: string, axis: \"inline\" | \"block\"): string {\n if (value === \"screen\") return axis === \"inline\" ? \"100dvw\" : \"100dvh\";\n return String(resolveTokenValue(value, SIZE_TOKEN_MAP));\n}\n\nfunction resolveAlignValue(value: BlockAlign): string {\n if (value === \"start\") return \"flex-start\";\n if (value === \"end\") return \"flex-end\";\n return value;\n}\n\nfunction resolveJustifyValue(value: BlockJustify): string {\n if (value === \"start\") return \"flex-start\";\n if (value === \"end\") return \"flex-end\";\n if (value === \"between\") return \"space-between\";\n return value;\n}\n\nfunction resolveFlexFlag(value: boolean | number): string | number {\n if (value === true) return 1;\n if (value === false) return 0;\n return value;\n}\n\nfunction resolveBorderValue(value: boolean): string | undefined {\n if (value === false) return \"0\";\n return BORDER_VALUE;\n}\n\nfunction resolveRadiusValue(value: BlockRadius): string | undefined {\n if (value === true) return RADIUS_TOKEN_MAP.md;\n return String(resolveTokenValue(value, RADIUS_TOKEN_MAP));\n}\n\nfunction resolveShadowValue(value: BlockShadow): string | undefined {\n if (value === true) return SHADOW_TOKEN_MAP.sm;\n return String(resolveTokenValue(value, SHADOW_TOKEN_MAP));\n}\n\nfunction setResponsiveVar<T>(\n styles: Record<string, string | number>,\n property: string,\n value: ResponsiveValue<T> | undefined,\n resolve: (value: T) => string | number | undefined,\n) {\n const normalized = normalizeResponsiveValue(value);\n if (!normalized) return;\n\n for (const breakpoint of BREAKPOINTS) {\n const breakpointValue = normalized[breakpoint];\n if (breakpointValue === undefined) continue;\n const resolved = resolve(breakpointValue);\n if (resolved === undefined || resolved === \"\") continue;\n styles[`--ak-${property}-${breakpoint}`] = resolved;\n }\n}\n\nexport function splitBlockLayoutProps<T extends Record<string, unknown>>(\n props: T,\n): {\n blockProps: Partial<BlockLayoutProps>;\n rest: Omit<T, keyof BlockLayoutProps>;\n} {\n const blockProps: Partial<BlockLayoutProps> = {};\n const rest: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n if (BLOCK_LAYOUT_KEYS.has(key as keyof BlockLayoutProps)) {\n (blockProps as Record<string, unknown>)[key] = value;\n } else {\n rest[key] = value;\n }\n }\n\n return { blockProps, rest: rest as Omit<T, keyof BlockLayoutProps> };\n}\n\nexport function applyBlockLayoutStyles(\n styles: Record<string, string | number>,\n props: Partial<BlockLayoutProps>,\n) {\n setResponsiveVar(styles, \"p\", props.padding, resolveSpaceValue);\n setResponsiveVar(styles, \"px\", props.paddingX, resolveSpaceValue);\n setResponsiveVar(styles, \"py\", props.paddingY, resolveSpaceValue);\n setResponsiveVar(styles, \"m\", props.margin, resolveSpaceValue);\n setResponsiveVar(styles, \"mx\", props.marginX, resolveSpaceValue);\n setResponsiveVar(styles, \"my\", props.marginY, resolveSpaceValue);\n\n setResponsiveVar(styles, \"width\", props.width, (value) => resolveSizeValue(value, \"inline\"));\n setResponsiveVar(styles, \"min-width\", props.minWidth, (value) =>\n resolveSizeValue(value, \"inline\"),\n );\n setResponsiveVar(styles, \"max-width\", props.maxWidth, (value) =>\n resolveSizeValue(value, \"inline\"),\n );\n setResponsiveVar(styles, \"height\", props.height, (value) => resolveSizeValue(value, \"block\"));\n setResponsiveVar(styles, \"min-height\", props.minHeight, (value) =>\n resolveSizeValue(value, \"block\"),\n );\n setResponsiveVar(styles, \"max-height\", props.maxHeight, (value) =>\n resolveSizeValue(value, \"block\"),\n );\n\n if (props.rowFrom !== undefined) {\n styles[`--ak-flex-direction-${props.rowFrom}`] = \"row\";\n }\n if (props.center !== undefined) {\n setResponsiveVar(styles, \"align-items\", props.center, (value) =>\n value ? \"center\" : \"stretch\",\n );\n setResponsiveVar(styles, \"justify-content\", props.center, (value) =>\n value ? \"center\" : \"flex-start\",\n );\n }\n setResponsiveVar(styles, \"flex-direction\", props.direction, (value) => value);\n setResponsiveVar(styles, \"align-items\", props.align, resolveAlignValue);\n setResponsiveVar(styles, \"justify-content\", props.justify, resolveJustifyValue);\n setResponsiveVar(styles, \"gap\", props.gap, resolveSpaceValue);\n setResponsiveVar(styles, \"flex-grow\", props.grow, resolveFlexFlag);\n setResponsiveVar(styles, \"flex-shrink\", props.shrink, resolveFlexFlag);\n\n if (props.sticky) {\n styles[\"--ak-position-base\"] = \"sticky\";\n }\n setResponsiveVar(styles, \"top\", props.top, resolveSpaceValue);\n setResponsiveVar(styles, \"z-index\", props.zIndex, (value) =>\n String(resolveTokenValue(value, Z_INDEX_TOKEN_MAP)),\n );\n\n setResponsiveVar(styles, \"background\", props.background, (value) =>\n String(resolveTokenValue(value, BACKGROUND_TOKEN_MAP)),\n );\n setResponsiveVar(styles, \"border\", props.border, resolveBorderValue);\n setResponsiveVar(styles, \"border-top\", props.borderTop, resolveBorderValue);\n setResponsiveVar(styles, \"border-bottom\", props.borderBottom, resolveBorderValue);\n setResponsiveVar(styles, \"border-right\", props.borderRight, resolveBorderValue);\n setResponsiveVar(styles, \"border-radius\", props.radius, resolveRadiusValue);\n setResponsiveVar(styles, \"box-shadow\", props.shadow, resolveShadowValue);\n setResponsiveVar(styles, \"display\", props.hide, (value) => (value ? \"none\" : \"flex\"));\n}\n\nexport function mergeLayoutStyles(\n layout: Record<string, string | number>,\n user: unknown,\n): string | undefined {\n const merged: Record<string, unknown> = { ...layout };\n\n if (user !== null && user !== undefined && typeof user === \"object\") {\n Object.assign(merged, user as Record<string, unknown>);\n }\n\n const mergedString = serializeCssDeclarations(merged);\n\n if (typeof user === \"string\" && user.trim()) {\n return mergedString ? `${mergedString};${user.trim()}` : user.trim();\n }\n\n return mergedString || undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"block-layout.js","names":[],"sources":["../../../src/components/_internal/block-layout.ts"],"sourcesContent":["import { serializeCssDeclarations } from \"./style\";\n\nexport type LayoutBreakpoint = \"base\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type ResponsiveValue<T> = T | Partial<Record<LayoutBreakpoint, T>>;\n\nexport type BlockSpace = \"0\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"page\";\nexport type BlockMargin = BlockSpace | \"auto\";\nexport type BlockSize =\n | \"auto\"\n | \"full\"\n | \"screen\"\n | \"content\"\n | \"sidebar\"\n | \"page\"\n | \"sm\"\n | \"md\"\n | \"lg\"\n | \"xl\";\nexport type BlockDirection = \"row\" | \"column\" | \"row-reverse\" | \"column-reverse\";\nexport type BlockRowFrom = Exclude<LayoutBreakpoint, \"base\">;\nexport type BlockAlign = \"start\" | \"end\" | \"center\" | \"stretch\" | \"baseline\";\nexport type BlockJustify = \"start\" | \"end\" | \"center\" | \"between\";\nexport type BlockBackground =\n | \"surface\"\n | \"muted\"\n | \"selected\"\n | \"canvas\"\n | \"raised\"\n | \"overlay\"\n | \"transparent\";\nexport type BlockRadius = true | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"round\";\nexport type BlockShadow = true | \"sm\" | \"md\" | \"lg\";\nexport type BlockZIndex =\n | \"header\"\n | \"sticky\"\n | \"fixed\"\n | \"dropdown\"\n | \"modal\"\n | \"popover\"\n | \"toast\"\n | \"tooltip\";\n\nexport type BlockLayoutProps = {\n padding?: ResponsiveValue<BlockSpace>;\n paddingX?: ResponsiveValue<BlockSpace>;\n paddingY?: ResponsiveValue<BlockSpace>;\n margin?: ResponsiveValue<BlockMargin>;\n marginX?: ResponsiveValue<BlockMargin>;\n marginY?: ResponsiveValue<BlockMargin>;\n width?: ResponsiveValue<BlockSize>;\n minWidth?: ResponsiveValue<BlockSize>;\n maxWidth?: ResponsiveValue<BlockSize>;\n height?: ResponsiveValue<BlockSize>;\n minHeight?: ResponsiveValue<BlockSize>;\n maxHeight?: ResponsiveValue<BlockSize>;\n rowFrom?: BlockRowFrom;\n direction?: ResponsiveValue<BlockDirection>;\n align?: ResponsiveValue<BlockAlign>;\n justify?: ResponsiveValue<BlockJustify>;\n gap?: ResponsiveValue<BlockSpace>;\n grow?: ResponsiveValue<boolean | number>;\n shrink?: ResponsiveValue<boolean | number>;\n center?: ResponsiveValue<boolean>;\n sticky?: boolean;\n top?: ResponsiveValue<BlockSpace>;\n zIndex?: ResponsiveValue<BlockZIndex>;\n background?: ResponsiveValue<BlockBackground>;\n border?: ResponsiveValue<boolean>;\n borderTop?: ResponsiveValue<boolean>;\n borderBottom?: ResponsiveValue<boolean>;\n borderRight?: ResponsiveValue<boolean>;\n radius?: ResponsiveValue<BlockRadius>;\n shadow?: ResponsiveValue<BlockShadow>;\n hide?: ResponsiveValue<boolean>;\n};\n\nconst BREAKPOINTS: readonly LayoutBreakpoint[] = [\"base\", \"sm\", \"md\", \"lg\", \"xl\"];\n\nconst SPACE_TOKEN_MAP: Record<string, string> = {\n \"0\": \"0\",\n xs: \"var(--ak-space-xs)\",\n sm: \"var(--ak-space-sm)\",\n md: \"var(--ak-space-md)\",\n lg: \"var(--ak-space-lg)\",\n xl: \"var(--ak-space-xl)\",\n \"2xl\": \"var(--ak-space-2xl)\",\n \"3xl\": \"var(--ak-space-3xl)\",\n page: \"var(--ak-layout-page-gutter)\",\n};\n\nconst SIZE_TOKEN_MAP: Record<string, string> = {\n auto: \"auto\",\n full: \"100%\",\n screen: \"100dvh\",\n content: \"min(60vh, 36rem)\",\n sidebar: \"var(--ak-layout-sidebar-width)\",\n page: \"var(--ak-layout-content-max-width)\",\n sm: \"var(--ak-container-1)\",\n md: \"var(--ak-container-2)\",\n lg: \"var(--ak-container-3)\",\n xl: \"var(--ak-container-4)\",\n};\n\nconst BACKGROUND_TOKEN_MAP: Record<string, string> = {\n canvas: \"var(--ak-color-bg)\",\n surface: \"var(--ak-color-surface)\",\n muted: \"var(--ak-color-surface-muted)\",\n raised: \"var(--ak-color-surface-raised)\",\n overlay: \"var(--ak-color-surface-overlay)\",\n selected: \"var(--ak-color-selected)\",\n transparent: \"transparent\",\n};\n\nconst RADIUS_TOKEN_MAP: Record<string, string> = {\n sm: \"var(--ak-radius-sm)\",\n md: \"var(--ak-radius-md)\",\n lg: \"var(--ak-radius-lg)\",\n xl: \"var(--ak-radius-xl)\",\n round: \"var(--ak-radius-round)\",\n};\n\nconst SHADOW_TOKEN_MAP: Record<string, string> = {\n sm: \"var(--ak-shadow-sm)\",\n md: \"var(--ak-shadow-md)\",\n lg: \"var(--ak-shadow-lg)\",\n};\n\nconst Z_INDEX_TOKEN_MAP: Record<string, string> = {\n header: \"var(--ak-z-sticky)\",\n sticky: \"var(--ak-z-sticky)\",\n fixed: \"var(--ak-z-fixed)\",\n dropdown: \"var(--ak-z-dropdown)\",\n modal: \"var(--ak-z-modal)\",\n popover: \"var(--ak-z-popover)\",\n toast: \"var(--ak-z-toast)\",\n tooltip: \"var(--ak-z-tooltip)\",\n};\n\nconst BORDER_VALUE = \"1px solid var(--ak-color-border-subtle)\";\n\nconst BLOCK_LAYOUT_KEYS = new Set<keyof BlockLayoutProps>([\n \"padding\",\n \"paddingX\",\n \"paddingY\",\n \"margin\",\n \"marginX\",\n \"marginY\",\n \"width\",\n \"minWidth\",\n \"maxWidth\",\n \"height\",\n \"minHeight\",\n \"maxHeight\",\n \"rowFrom\",\n \"direction\",\n \"align\",\n \"justify\",\n \"gap\",\n \"grow\",\n \"shrink\",\n \"center\",\n \"sticky\",\n \"top\",\n \"zIndex\",\n \"background\",\n \"border\",\n \"borderTop\",\n \"borderBottom\",\n \"borderRight\",\n \"radius\",\n \"shadow\",\n \"hide\",\n]);\n\nfunction isResponsiveValue<T>(\n value: ResponsiveValue<T> | undefined,\n): value is Partial<Record<LayoutBreakpoint, T>> {\n return Boolean(\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n BREAKPOINTS.some((breakpoint) => breakpoint in value),\n );\n}\n\nfunction normalizeResponsiveValue<T>(\n value: ResponsiveValue<T> | undefined,\n): Partial<Record<LayoutBreakpoint, T>> | undefined {\n if (value === undefined) return undefined;\n if (isResponsiveValue(value)) return value;\n return { base: value };\n}\n\nfunction resolveTokenValue(\n value: string | number,\n tokens: Record<string, string>,\n): string | number {\n if (typeof value === \"number\") return value;\n const trimmed = value.trim();\n return tokens[trimmed] ?? trimmed;\n}\n\nexport function resolveSpaceValue(value: string | number): string | number {\n return resolveTokenValue(value, SPACE_TOKEN_MAP);\n}\n\nfunction resolveSizeValue(value: string, axis: \"inline\" | \"block\"): string {\n if (value === \"screen\") return axis === \"inline\" ? \"100dvw\" : \"100dvh\";\n return String(resolveTokenValue(value, SIZE_TOKEN_MAP));\n}\n\nfunction resolveAlignValue(value: BlockAlign): string {\n if (value === \"start\") return \"flex-start\";\n if (value === \"end\") return \"flex-end\";\n return value;\n}\n\nfunction resolveJustifyValue(value: BlockJustify): string {\n if (value === \"start\") return \"flex-start\";\n if (value === \"end\") return \"flex-end\";\n if (value === \"between\") return \"space-between\";\n return value;\n}\n\nfunction resolveFlexFlag(value: boolean | number): string | number {\n if (value === true) return 1;\n if (value === false) return 0;\n return value;\n}\n\nfunction resolveBorderValue(value: boolean): string | undefined {\n if (value === false) return \"0\";\n return BORDER_VALUE;\n}\n\nfunction resolveRadiusValue(value: BlockRadius): string | undefined {\n if (value === true) return RADIUS_TOKEN_MAP.md;\n return String(resolveTokenValue(value, RADIUS_TOKEN_MAP));\n}\n\nfunction resolveShadowValue(value: BlockShadow): string | undefined {\n if (value === true) return SHADOW_TOKEN_MAP.sm;\n return String(resolveTokenValue(value, SHADOW_TOKEN_MAP));\n}\n\nexport function setResponsiveVar<T>(\n styles: Record<string, string | number>,\n property: string,\n value: ResponsiveValue<T> | undefined,\n resolve: (value: T) => string | number | undefined,\n) {\n const normalized = normalizeResponsiveValue(value);\n if (!normalized) return;\n\n for (const breakpoint of BREAKPOINTS) {\n const breakpointValue = normalized[breakpoint];\n if (breakpointValue === undefined) continue;\n const resolved = resolve(breakpointValue);\n if (resolved === undefined || resolved === \"\") continue;\n styles[`--ak-${property}-${breakpoint}`] = resolved;\n }\n}\n\nexport function splitBlockLayoutProps<T extends Record<string, unknown>>(\n props: T,\n): {\n blockProps: Partial<BlockLayoutProps>;\n rest: Omit<T, keyof BlockLayoutProps>;\n} {\n const blockProps: Partial<BlockLayoutProps> = {};\n const rest: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n if (BLOCK_LAYOUT_KEYS.has(key as keyof BlockLayoutProps)) {\n (blockProps as Record<string, unknown>)[key] = value;\n } else {\n rest[key] = value;\n }\n }\n\n return { blockProps, rest: rest as Omit<T, keyof BlockLayoutProps> };\n}\n\nexport function applyBlockLayoutStyles(\n styles: Record<string, string | number>,\n props: Partial<BlockLayoutProps>,\n) {\n setResponsiveVar(styles, \"p\", props.padding, resolveSpaceValue);\n setResponsiveVar(styles, \"px\", props.paddingX, resolveSpaceValue);\n setResponsiveVar(styles, \"py\", props.paddingY, resolveSpaceValue);\n setResponsiveVar(styles, \"m\", props.margin, resolveSpaceValue);\n setResponsiveVar(styles, \"mx\", props.marginX, resolveSpaceValue);\n setResponsiveVar(styles, \"my\", props.marginY, resolveSpaceValue);\n\n setResponsiveVar(styles, \"width\", props.width, (value) => resolveSizeValue(value, \"inline\"));\n setResponsiveVar(styles, \"min-width\", props.minWidth, (value) =>\n resolveSizeValue(value, \"inline\"),\n );\n setResponsiveVar(styles, \"max-width\", props.maxWidth, (value) =>\n resolveSizeValue(value, \"inline\"),\n );\n setResponsiveVar(styles, \"height\", props.height, (value) => resolveSizeValue(value, \"block\"));\n setResponsiveVar(styles, \"min-height\", props.minHeight, (value) =>\n resolveSizeValue(value, \"block\"),\n );\n setResponsiveVar(styles, \"max-height\", props.maxHeight, (value) =>\n resolveSizeValue(value, \"block\"),\n );\n\n if (props.rowFrom !== undefined) {\n styles[`--ak-flex-direction-${props.rowFrom}`] = \"row\";\n }\n if (props.center !== undefined) {\n setResponsiveVar(styles, \"align-items\", props.center, (value) =>\n value ? \"center\" : \"stretch\",\n );\n setResponsiveVar(styles, \"justify-content\", props.center, (value) =>\n value ? \"center\" : \"flex-start\",\n );\n }\n setResponsiveVar(styles, \"flex-direction\", props.direction, (value) => value);\n setResponsiveVar(styles, \"align-items\", props.align, resolveAlignValue);\n setResponsiveVar(styles, \"justify-content\", props.justify, resolveJustifyValue);\n setResponsiveVar(styles, \"gap\", props.gap, resolveSpaceValue);\n setResponsiveVar(styles, \"flex-grow\", props.grow, resolveFlexFlag);\n setResponsiveVar(styles, \"flex-shrink\", props.shrink, resolveFlexFlag);\n\n if (props.sticky) {\n styles[\"--ak-position-base\"] = \"sticky\";\n }\n setResponsiveVar(styles, \"top\", props.top, resolveSpaceValue);\n setResponsiveVar(styles, \"z-index\", props.zIndex, (value) =>\n String(resolveTokenValue(value, Z_INDEX_TOKEN_MAP)),\n );\n\n setResponsiveVar(styles, \"background\", props.background, (value) =>\n String(resolveTokenValue(value, BACKGROUND_TOKEN_MAP)),\n );\n setResponsiveVar(styles, \"border\", props.border, resolveBorderValue);\n setResponsiveVar(styles, \"border-top\", props.borderTop, resolveBorderValue);\n setResponsiveVar(styles, \"border-bottom\", props.borderBottom, resolveBorderValue);\n setResponsiveVar(styles, \"border-right\", props.borderRight, resolveBorderValue);\n setResponsiveVar(styles, \"border-radius\", props.radius, resolveRadiusValue);\n setResponsiveVar(styles, \"box-shadow\", props.shadow, resolveShadowValue);\n setResponsiveVar(styles, \"display\", props.hide, (value) => (value ? \"none\" : \"flex\"));\n}\n\nexport function mergeLayoutStyles(\n layout: Record<string, string | number>,\n user: unknown,\n): string | undefined {\n const merged: Record<string, unknown> = { ...layout };\n\n if (user !== null && user !== undefined && typeof user === \"object\") {\n Object.assign(merged, user as Record<string, unknown>);\n }\n\n const mergedString = serializeCssDeclarations(merged);\n\n if (typeof user === \"string\" && user.trim()) {\n return mergedString ? `${mergedString};${user.trim()}` : user.trim();\n }\n\n return mergedString || undefined;\n}\n"],"mappings":"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"}
@@ -125,8 +125,8 @@ function serializeCssDeclarations(styles) {
125
125
  const STYLE_REGISTRY_ATTR = "data-askr-style-registry";
126
126
  const STYLE_CLASS_PREFIX = "ak-style-";
127
127
  const MAX_STYLE_RULES = 512;
128
- const MAX_SSR_STYLE_CACHE = 4096;
129
- const styleRulesByClass = /* @__PURE__ */ new Map();
128
+ const MAX_COLLISION_CACHE = 4096;
129
+ const styleCollisionCache = /* @__PURE__ */ new Map();
130
130
  const registries = /* @__PURE__ */ new WeakMap();
131
131
  function countRegisteredRules(value) {
132
132
  return value?.match(/\.ak-style-[a-z0-9]+\{/g)?.length ?? 0;
@@ -148,7 +148,7 @@ function escapeStyleRawText(value) {
148
148
  }
149
149
  function styleRuleFor(declarations) {
150
150
  const className = styleClassName(declarations);
151
- const existing = styleRulesByClass.get(className);
151
+ const existing = styleCollisionCache.get(className);
152
152
  if (existing) {
153
153
  if (existing.declarations !== declarations) throw new RangeError("Theme style class collision detected.");
154
154
  return existing;
@@ -160,12 +160,12 @@ function styleRuleFor(declarations) {
160
160
  };
161
161
  }
162
162
  function rememberStyleRule(entry) {
163
- styleRulesByClass.delete(entry.className);
164
- styleRulesByClass.set(entry.className, entry);
165
- while (styleRulesByClass.size > MAX_SSR_STYLE_CACHE) {
166
- const oldest = styleRulesByClass.keys().next().value;
163
+ styleCollisionCache.delete(entry.className);
164
+ styleCollisionCache.set(entry.className, entry);
165
+ while (styleCollisionCache.size > MAX_COLLISION_CACHE) {
166
+ const oldest = styleCollisionCache.keys().next().value;
167
167
  if (oldest === void 0) break;
168
- styleRulesByClass.delete(oldest);
168
+ styleCollisionCache.delete(oldest);
169
169
  }
170
170
  }
171
171
  function registerSSRStyle(entry) {
@@ -225,17 +225,5 @@ function styleDeclarationsToClass(declarations) {
225
225
  registerSSRStyle(entry);
226
226
  return entry.className;
227
227
  }
228
- function styleRulesForHtml(html) {
229
- const rules = /* @__PURE__ */ new Map();
230
- for (const attribute of html.matchAll(/\sclass=(?:"([^"]*)"|'([^']*)')/g)) {
231
- const value = attribute[1] ?? attribute[2] ?? "";
232
- for (const className of value.split(/\s+/)) {
233
- const entry = styleRulesByClass.get(className);
234
- if (entry) rules.set(className, entry.rule);
235
- if (rules.size > MAX_STYLE_RULES) throw new RangeError("Theme style registry capacity exceeded.");
236
- }
237
- }
238
- return Array.from(rules.values());
239
- }
240
228
  //#endregion
241
- export { serializeCssDeclarations, styleDeclarationsToClass, styleRulesForHtml };
229
+ export { serializeCssDeclarations, styleDeclarationsToClass };
@@ -1 +1 @@
1
- {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/_internal/style.ts"],"sourcesContent":["import * as Askr from \"@askrjs/askr\";\n\nconst cssPropertyNameCache = new Map<string, string>();\nconst MAX_PROPERTY_CACHE = 256;\n\nconst CSS_UNSAFE_RE = /[{}<>\\\\]/;\nconst CSS_URI_SCHEME_RE = /(?:^|[\\s(,])([a-z][a-z0-9+.-]*):/i;\nconst CSS_FUNCTION_NAME_RE = /([a-z-][a-z0-9-]*)\\s*\\(/gi;\nconst CSS_ALLOWED_FUNCTIONS = new Set([\n \"var\",\n \"calc\",\n \"min\",\n \"max\",\n \"clamp\",\n \"minmax\",\n \"repeat\",\n \"rgb\",\n \"rgba\",\n \"hsl\",\n \"hsla\",\n \"lab\",\n \"lch\",\n \"oklab\",\n \"oklch\",\n \"color\",\n \"color-mix\",\n \"translate\",\n \"translatex\",\n \"translatey\",\n \"translatez\",\n \"scale\",\n \"scalex\",\n \"scaley\",\n \"scalez\",\n \"rotate\",\n \"rotatex\",\n \"rotatey\",\n \"rotatez\",\n \"skew\",\n \"skewx\",\n \"skewy\",\n \"matrix\",\n \"matrix3d\",\n \"linear-gradient\",\n \"radial-gradient\",\n \"conic-gradient\",\n \"repeating-linear-gradient\",\n \"repeating-radial-gradient\",\n \"repeating-conic-gradient\",\n \"cubic-bezier\",\n \"steps\",\n]);\n\nfunction isSafeCssPropertyName(name: string): boolean {\n if (name.startsWith(\"--\")) return /^--[a-zA-Z0-9_-]+$/.test(name);\n return /^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(name);\n}\n\nfunction isSafeCssValue(value: string): boolean {\n if (CSS_UNSAFE_RE.test(value) || CSS_URI_SCHEME_RE.test(value)) return false;\n\n for (const match of value.matchAll(CSS_FUNCTION_NAME_RE)) {\n if (!CSS_ALLOWED_FUNCTIONS.has(match[1]!.toLowerCase())) return false;\n }\n\n return true;\n}\n\nfunction splitCssDeclarations(value: string): string[] {\n const declarations: string[] = [];\n let start = 0;\n let depth = 0;\n let quote: string | undefined;\n\n for (let index = 0; index < value.length; index += 1) {\n const char = value[index]!;\n if (quote) {\n if (char === quote && value[index - 1] !== \"\\\\\") quote = undefined;\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n continue;\n }\n if (char === \"(\") depth += 1;\n if (char === \")\" && depth > 0) depth -= 1;\n if (char === \";\" && depth === 0) {\n declarations.push(value.slice(start, index));\n start = index + 1;\n }\n }\n\n declarations.push(value.slice(start));\n return declarations;\n}\n\nfunction serializeCssString(value: string): string {\n const entries: Array<[string, string]> = [];\n for (const candidate of splitCssDeclarations(value)) {\n const separator = candidate.indexOf(\":\");\n if (separator <= 0) continue;\n const key = candidate.slice(0, separator).trim();\n const cssValue = candidate.slice(separator + 1).trim();\n if (key && cssValue) entries.push([key, cssValue]);\n }\n return serializeCssDeclarations(Object.fromEntries(entries));\n}\n\nfunction cssPropertyName(name: string): string {\n let cached = cssPropertyNameCache.get(name);\n if (cached !== undefined) {\n return cached;\n }\n\n let result = \"\";\n\n for (let index = 0; index < name.length; index += 1) {\n const code = name.charCodeAt(index);\n\n if (code >= 65 && code <= 90) {\n result += `-${String.fromCharCode(code + 32)}`;\n } else {\n result += name[index];\n }\n }\n\n if (cssPropertyNameCache.size < MAX_PROPERTY_CACHE) {\n cssPropertyNameCache.set(name, result);\n }\n return result;\n}\n\nexport function serializeCssDeclarations(styles: Record<string, unknown>): string {\n const keys = Object.keys(styles);\n let result = \"\";\n\n for (const key of keys) {\n const value = styles[key];\n if (value === undefined || value === null) {\n continue;\n }\n\n const rawProperty = key.trim();\n if (!isSafeCssPropertyName(rawProperty)) {\n continue;\n }\n const property = cssPropertyName(rawProperty).trim();\n const cssValue = String(value).trim();\n if (!cssValue || !isSafeCssValue(cssValue)) {\n continue;\n }\n\n const declaration = `${property}:${cssValue}`;\n result = result ? `${result};${declaration}` : declaration;\n }\n\n return result;\n}\n\nexport function mergeCssVar(style: unknown, name: string, value: string): string {\n const decl = `${name}:${value}`;\n\n if (typeof style === \"string\") {\n const trimmed = style.trim();\n return trimmed ? `${trimmed};${decl}` : decl;\n }\n\n if (style && typeof style === \"object\") {\n const entries = serializeCssDeclarations(style as Record<string, unknown>);\n return entries ? `${entries};${decl}` : decl;\n }\n\n return decl;\n}\n\nconst STYLE_REGISTRY_ATTR = \"data-askr-style-registry\";\nconst STYLE_CLASS_PREFIX = \"ak-style-\";\nconst MAX_STYLE_RULES = 512;\nconst MAX_SSR_STYLE_CACHE = 4096;\n\ntype StyleRule = {\n className: string;\n declarations: string;\n rule: string;\n};\n\nconst styleRulesByClass = new Map<string, StyleRule>();\ntype StyleRegistry = {\n element: HTMLStyleElement;\n ruleCount: number;\n rules: Map<string, StyleRule>;\n};\nconst registries = new WeakMap<Document, Map<string, StyleRegistry>>();\nfunction countRegisteredRules(value: string | null): number {\n return value?.match(/\\.ak-style-[a-z0-9]+\\{/g)?.length ?? 0;\n}\n\nfunction styleClassName(declarations: string): string {\n let first = 0xdeadbeef ^ declarations.length;\n let second = 0x41c6ce57 ^ declarations.length;\n\n for (let index = 0; index < declarations.length; index += 1) {\n const code = declarations.charCodeAt(index);\n first = Math.imul(first ^ code, 2_654_435_761);\n second = Math.imul(second ^ code, 1_597_334_677);\n }\n\n first =\n Math.imul(first ^ (first >>> 16), 2_246_822_507) ^\n Math.imul(second ^ (second >>> 13), 3_266_489_909);\n second =\n Math.imul(second ^ (second >>> 16), 2_246_822_507) ^\n Math.imul(first ^ (first >>> 13), 3_266_489_909);\n\n return `${STYLE_CLASS_PREFIX}${(second >>> 0).toString(36)}${(first >>> 0).toString(36)}`;\n}\n\nfunction escapeStyleRawText(value: string): string {\n return value.replace(/<\\//g, \"<\\\\/\");\n}\n\nfunction styleRuleFor(declarations: string): StyleRule {\n const className = styleClassName(declarations);\n const existing = styleRulesByClass.get(className);\n if (existing) {\n if (existing.declarations !== declarations) {\n throw new RangeError(\"Theme style class collision detected.\");\n }\n return existing;\n }\n\n const entry = {\n className,\n declarations,\n rule: `.${className}{${escapeStyleRawText(declarations)}}`,\n };\n return entry;\n}\n\nfunction rememberStyleRule(entry: StyleRule): void {\n styleRulesByClass.delete(entry.className);\n styleRulesByClass.set(entry.className, entry);\n while (styleRulesByClass.size > MAX_SSR_STYLE_CACHE) {\n const oldest = styleRulesByClass.keys().next().value;\n if (oldest === undefined) break;\n styleRulesByClass.delete(oldest);\n }\n}\n\nfunction registerSSRStyle(entry: StyleRule): void {\n const register = (\n Askr as typeof Askr & {\n registerSSRStyle?: (id: string, cssText: string) => void;\n }\n ).registerSSRStyle;\n register?.(entry.className, entry.rule);\n}\n\nfunction ensureStyleRegistry(nonce: string | undefined): StyleRegistry | null {\n if (typeof document === \"undefined\") return null;\n const key = nonce ?? \"\";\n let documentRegistries = registries.get(document);\n if (!documentRegistries) {\n documentRegistries = new Map();\n registries.set(document, documentRegistries);\n }\n const current = documentRegistries.get(key);\n if (current?.element.isConnected) return current;\n\n const existingStyleElements = Array.from(\n document.querySelectorAll<HTMLStyleElement>(`style[${STYLE_REGISTRY_ATTR}]`),\n );\n const styleElement =\n existingStyleElements.find((element) => (element.nonce || undefined) === nonce) ??\n (nonce === undefined && existingStyleElements.length === 1\n ? existingStyleElements[0]\n : undefined) ??\n document.createElement(\"style\");\n if (!styleElement.isConnected) {\n styleElement.setAttribute(STYLE_REGISTRY_ATTR, \"true\");\n if (nonce !== undefined) styleElement.nonce = nonce;\n (document.head ?? document.documentElement).append(styleElement);\n }\n const registry: StyleRegistry = {\n element: styleElement,\n ruleCount: countRegisteredRules(styleElement.textContent),\n rules: new Map(),\n };\n documentRegistries.set(key, registry);\n return registry;\n}\n\nfunction normalizeDeclarations(declarations: string): string {\n return serializeCssString(declarations);\n}\n\nexport function styleDeclarationsToClass(declarations: string | undefined): string | undefined {\n if (typeof declarations !== \"string\") return undefined;\n\n const normalized = normalizeDeclarations(declarations);\n if (!normalized) return undefined;\n\n const entry = styleRuleFor(normalized);\n const nonce = Askr.cspNonce();\n const registry = ensureStyleRegistry(nonce);\n const registered = registry?.rules.get(normalized);\n if (registered) {\n registerSSRStyle(registered);\n return registered.className;\n }\n\n if (registry) {\n if (!registry.rules.has(normalized) && !registry.element.textContent?.includes(entry.rule)) {\n if (registry.ruleCount >= MAX_STYLE_RULES) {\n throw new RangeError(\"Theme style registry capacity exceeded.\");\n }\n }\n if (!registry.element.textContent?.includes(entry.rule)) {\n registry.element.append(entry.rule, \"\\n\");\n registry.ruleCount += 1;\n }\n registry.rules.set(normalized, entry);\n }\n\n rememberStyleRule(entry);\n registerSSRStyle(entry);\n\n return entry.className;\n}\n\nexport function styleRulesForHtml(html: string): string[] {\n const rules = new Map<string, string>();\n const classAttributePattern = /\\sclass=(?:\"([^\"]*)\"|'([^']*)')/g;\n\n for (const attribute of html.matchAll(classAttributePattern)) {\n const value = attribute[1] ?? attribute[2] ?? \"\";\n for (const className of value.split(/\\s+/)) {\n const entry = styleRulesByClass.get(className);\n if (entry) rules.set(className, entry.rule);\n if (rules.size > MAX_STYLE_RULES) {\n throw new RangeError(\"Theme style registry capacity exceeded.\");\n }\n }\n }\n\n return Array.from(rules.values());\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/_internal/style.ts"],"sourcesContent":["import * as Askr from \"@askrjs/askr\";\n\nconst cssPropertyNameCache = new Map<string, string>();\nconst MAX_PROPERTY_CACHE = 256;\n\nconst CSS_UNSAFE_RE = /[{}<>\\\\]/;\nconst CSS_URI_SCHEME_RE = /(?:^|[\\s(,])([a-z][a-z0-9+.-]*):/i;\nconst CSS_FUNCTION_NAME_RE = /([a-z-][a-z0-9-]*)\\s*\\(/gi;\nconst CSS_ALLOWED_FUNCTIONS = new Set([\n \"var\",\n \"calc\",\n \"min\",\n \"max\",\n \"clamp\",\n \"minmax\",\n \"repeat\",\n \"rgb\",\n \"rgba\",\n \"hsl\",\n \"hsla\",\n \"lab\",\n \"lch\",\n \"oklab\",\n \"oklch\",\n \"color\",\n \"color-mix\",\n \"translate\",\n \"translatex\",\n \"translatey\",\n \"translatez\",\n \"scale\",\n \"scalex\",\n \"scaley\",\n \"scalez\",\n \"rotate\",\n \"rotatex\",\n \"rotatey\",\n \"rotatez\",\n \"skew\",\n \"skewx\",\n \"skewy\",\n \"matrix\",\n \"matrix3d\",\n \"linear-gradient\",\n \"radial-gradient\",\n \"conic-gradient\",\n \"repeating-linear-gradient\",\n \"repeating-radial-gradient\",\n \"repeating-conic-gradient\",\n \"cubic-bezier\",\n \"steps\",\n]);\n\nfunction isSafeCssPropertyName(name: string): boolean {\n if (name.startsWith(\"--\")) return /^--[a-zA-Z0-9_-]+$/.test(name);\n return /^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(name);\n}\n\nfunction isSafeCssValue(value: string): boolean {\n if (CSS_UNSAFE_RE.test(value) || CSS_URI_SCHEME_RE.test(value)) return false;\n\n for (const match of value.matchAll(CSS_FUNCTION_NAME_RE)) {\n if (!CSS_ALLOWED_FUNCTIONS.has(match[1]!.toLowerCase())) return false;\n }\n\n return true;\n}\n\nfunction splitCssDeclarations(value: string): string[] {\n const declarations: string[] = [];\n let start = 0;\n let depth = 0;\n let quote: string | undefined;\n\n for (let index = 0; index < value.length; index += 1) {\n const char = value[index]!;\n if (quote) {\n if (char === quote && value[index - 1] !== \"\\\\\") quote = undefined;\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n continue;\n }\n if (char === \"(\") depth += 1;\n if (char === \")\" && depth > 0) depth -= 1;\n if (char === \";\" && depth === 0) {\n declarations.push(value.slice(start, index));\n start = index + 1;\n }\n }\n\n declarations.push(value.slice(start));\n return declarations;\n}\n\nfunction serializeCssString(value: string): string {\n const entries: Array<[string, string]> = [];\n for (const candidate of splitCssDeclarations(value)) {\n const separator = candidate.indexOf(\":\");\n if (separator <= 0) continue;\n const key = candidate.slice(0, separator).trim();\n const cssValue = candidate.slice(separator + 1).trim();\n if (key && cssValue) entries.push([key, cssValue]);\n }\n return serializeCssDeclarations(Object.fromEntries(entries));\n}\n\nfunction cssPropertyName(name: string): string {\n let cached = cssPropertyNameCache.get(name);\n if (cached !== undefined) {\n return cached;\n }\n\n let result = \"\";\n\n for (let index = 0; index < name.length; index += 1) {\n const code = name.charCodeAt(index);\n\n if (code >= 65 && code <= 90) {\n result += `-${String.fromCharCode(code + 32)}`;\n } else {\n result += name[index];\n }\n }\n\n if (cssPropertyNameCache.size < MAX_PROPERTY_CACHE) {\n cssPropertyNameCache.set(name, result);\n }\n return result;\n}\n\nexport function serializeCssDeclarations(styles: Record<string, unknown>): string {\n const keys = Object.keys(styles);\n let result = \"\";\n\n for (const key of keys) {\n const value = styles[key];\n if (value === undefined || value === null) {\n continue;\n }\n\n const rawProperty = key.trim();\n if (!isSafeCssPropertyName(rawProperty)) {\n continue;\n }\n const property = cssPropertyName(rawProperty).trim();\n const cssValue = String(value).trim();\n if (!cssValue || !isSafeCssValue(cssValue)) {\n continue;\n }\n\n const declaration = `${property}:${cssValue}`;\n result = result ? `${result};${declaration}` : declaration;\n }\n\n return result;\n}\n\nexport function mergeCssVar(style: unknown, name: string, value: string): string {\n const decl = `${name}:${value}`;\n\n if (typeof style === \"string\") {\n const trimmed = style.trim();\n return trimmed ? `${trimmed};${decl}` : decl;\n }\n\n if (style && typeof style === \"object\") {\n const entries = serializeCssDeclarations(style as Record<string, unknown>);\n return entries ? `${entries};${decl}` : decl;\n }\n\n return decl;\n}\n\nconst STYLE_REGISTRY_ATTR = \"data-askr-style-registry\";\nconst STYLE_CLASS_PREFIX = \"ak-style-\";\nconst MAX_STYLE_RULES = 512;\nconst MAX_COLLISION_CACHE = 4096;\n\ntype StyleRule = {\n className: string;\n declarations: string;\n rule: string;\n};\n\nconst styleCollisionCache = new Map<string, StyleRule>();\ntype StyleRegistry = {\n element: HTMLStyleElement;\n ruleCount: number;\n rules: Map<string, StyleRule>;\n};\nconst registries = new WeakMap<Document, Map<string, StyleRegistry>>();\nfunction countRegisteredRules(value: string | null): number {\n return value?.match(/\\.ak-style-[a-z0-9]+\\{/g)?.length ?? 0;\n}\n\nfunction styleClassName(declarations: string): string {\n let first = 0xdeadbeef ^ declarations.length;\n let second = 0x41c6ce57 ^ declarations.length;\n\n for (let index = 0; index < declarations.length; index += 1) {\n const code = declarations.charCodeAt(index);\n first = Math.imul(first ^ code, 2_654_435_761);\n second = Math.imul(second ^ code, 1_597_334_677);\n }\n\n first =\n Math.imul(first ^ (first >>> 16), 2_246_822_507) ^\n Math.imul(second ^ (second >>> 13), 3_266_489_909);\n second =\n Math.imul(second ^ (second >>> 16), 2_246_822_507) ^\n Math.imul(first ^ (first >>> 13), 3_266_489_909);\n\n return `${STYLE_CLASS_PREFIX}${(second >>> 0).toString(36)}${(first >>> 0).toString(36)}`;\n}\n\nfunction escapeStyleRawText(value: string): string {\n return value.replace(/<\\//g, \"<\\\\/\");\n}\n\nfunction styleRuleFor(declarations: string): StyleRule {\n const className = styleClassName(declarations);\n const existing = styleCollisionCache.get(className);\n if (existing) {\n if (existing.declarations !== declarations) {\n throw new RangeError(\"Theme style class collision detected.\");\n }\n return existing;\n }\n\n const entry = {\n className,\n declarations,\n rule: `.${className}{${escapeStyleRawText(declarations)}}`,\n };\n return entry;\n}\n\nfunction rememberStyleRule(entry: StyleRule): void {\n styleCollisionCache.delete(entry.className);\n styleCollisionCache.set(entry.className, entry);\n while (styleCollisionCache.size > MAX_COLLISION_CACHE) {\n const oldest = styleCollisionCache.keys().next().value;\n if (oldest === undefined) break;\n styleCollisionCache.delete(oldest);\n }\n}\n\nfunction registerSSRStyle(entry: StyleRule): void {\n const register = (\n Askr as typeof Askr & {\n registerSSRStyle?: (id: string, cssText: string) => void;\n }\n ).registerSSRStyle;\n register?.(entry.className, entry.rule);\n}\n\nfunction ensureStyleRegistry(nonce: string | undefined): StyleRegistry | null {\n if (typeof document === \"undefined\") return null;\n const key = nonce ?? \"\";\n let documentRegistries = registries.get(document);\n if (!documentRegistries) {\n documentRegistries = new Map();\n registries.set(document, documentRegistries);\n }\n const current = documentRegistries.get(key);\n if (current?.element.isConnected) return current;\n\n const existingStyleElements = Array.from(\n document.querySelectorAll<HTMLStyleElement>(`style[${STYLE_REGISTRY_ATTR}]`),\n );\n const styleElement =\n existingStyleElements.find((element) => (element.nonce || undefined) === nonce) ??\n (nonce === undefined && existingStyleElements.length === 1\n ? existingStyleElements[0]\n : undefined) ??\n document.createElement(\"style\");\n if (!styleElement.isConnected) {\n styleElement.setAttribute(STYLE_REGISTRY_ATTR, \"true\");\n if (nonce !== undefined) styleElement.nonce = nonce;\n (document.head ?? document.documentElement).append(styleElement);\n }\n const registry: StyleRegistry = {\n element: styleElement,\n ruleCount: countRegisteredRules(styleElement.textContent),\n rules: new Map(),\n };\n documentRegistries.set(key, registry);\n return registry;\n}\n\nfunction normalizeDeclarations(declarations: string): string {\n return serializeCssString(declarations);\n}\n\nexport function styleDeclarationsToClass(declarations: string | undefined): string | undefined {\n if (typeof declarations !== \"string\") return undefined;\n\n const normalized = normalizeDeclarations(declarations);\n if (!normalized) return undefined;\n\n const entry = styleRuleFor(normalized);\n const nonce = Askr.cspNonce();\n const registry = ensureStyleRegistry(nonce);\n const registered = registry?.rules.get(normalized);\n if (registered) {\n registerSSRStyle(registered);\n return registered.className;\n }\n\n if (registry) {\n if (!registry.rules.has(normalized) && !registry.element.textContent?.includes(entry.rule)) {\n if (registry.ruleCount >= MAX_STYLE_RULES) {\n throw new RangeError(\"Theme style registry capacity exceeded.\");\n }\n }\n if (!registry.element.textContent?.includes(entry.rule)) {\n registry.element.append(entry.rule, \"\\n\");\n registry.ruleCount += 1;\n }\n registry.rules.set(normalized, entry);\n }\n\n rememberStyleRule(entry);\n registerSSRStyle(entry);\n\n return entry.className;\n}\n"],"mappings":";;AAEA,MAAM,uCAAuB,IAAI,IAAoB;AACrD,MAAM,qBAAqB;AAE3B,MAAM,gBAAgB;AACtB,MAAM,oBAAoB;AAC1B,MAAM,uBAAuB;AAC7B,MAAM,wCAAwB,IAAI,IAAI;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,sBAAsB,MAAuB;CACpD,IAAI,KAAK,WAAW,IAAI,GAAG,OAAO,qBAAqB,KAAK,IAAI;CAChE,OAAO,4BAA4B,KAAK,IAAI;AAC9C;AAEA,SAAS,eAAe,OAAwB;CAC9C,IAAI,cAAc,KAAK,KAAK,KAAK,kBAAkB,KAAK,KAAK,GAAG,OAAO;CAEvE,KAAK,MAAM,SAAS,MAAM,SAAS,oBAAoB,GACrD,IAAI,CAAC,sBAAsB,IAAI,MAAM,EAAE,CAAE,YAAY,CAAC,GAAG,OAAO;CAGlE,OAAO;AACT;AAEA,SAAS,qBAAqB,OAAyB;CACrD,MAAM,eAAyB,CAAC;CAChC,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,IAAI;CAEJ,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;EACpD,MAAM,OAAO,MAAM;EACnB,IAAI,OAAO;GACT,IAAI,SAAS,SAAS,MAAM,QAAQ,OAAO,MAAM,QAAQ,KAAA;GACzD;EACF;EACA,IAAI,SAAS,QAAO,SAAS,KAAK;GAChC,QAAQ;GACR;EACF;EACA,IAAI,SAAS,KAAK,SAAS;EAC3B,IAAI,SAAS,OAAO,QAAQ,GAAG,SAAS;EACxC,IAAI,SAAS,OAAO,UAAU,GAAG;GAC/B,aAAa,KAAK,MAAM,MAAM,OAAO,KAAK,CAAC;GAC3C,QAAQ,QAAQ;EAClB;CACF;CAEA,aAAa,KAAK,MAAM,MAAM,KAAK,CAAC;CACpC,OAAO;AACT;AAEA,SAAS,mBAAmB,OAAuB;CACjD,MAAM,UAAmC,CAAC;CAC1C,KAAK,MAAM,aAAa,qBAAqB,KAAK,GAAG;EACnD,MAAM,YAAY,UAAU,QAAQ,GAAG;EACvC,IAAI,aAAa,GAAG;EACpB,MAAM,MAAM,UAAU,MAAM,GAAG,SAAS,CAAC,CAAC,KAAK;EAC/C,MAAM,WAAW,UAAU,MAAM,YAAY,CAAC,CAAC,CAAC,KAAK;EACrD,IAAI,OAAO,UAAU,QAAQ,KAAK,CAAC,KAAK,QAAQ,CAAC;CACnD;CACA,OAAO,yBAAyB,OAAO,YAAY,OAAO,CAAC;AAC7D;AAEA,SAAS,gBAAgB,MAAsB;CAC7C,IAAI,SAAS,qBAAqB,IAAI,IAAI;CAC1C,IAAI,WAAW,KAAA,GACb,OAAO;CAGT,IAAI,SAAS;CAEb,KAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;EACnD,MAAM,OAAO,KAAK,WAAW,KAAK;EAElC,IAAI,QAAQ,MAAM,QAAQ,IACxB,UAAU,IAAI,OAAO,aAAa,OAAO,EAAE;OAE3C,UAAU,KAAK;CAEnB;CAEA,IAAI,qBAAqB,OAAO,oBAC9B,qBAAqB,IAAI,MAAM,MAAM;CAEvC,OAAO;AACT;AAEA,SAAgB,yBAAyB,QAAyC;CAChF,MAAM,OAAO,OAAO,KAAK,MAAM;CAC/B,IAAI,SAAS;CAEb,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,QAAQ,OAAO;EACrB,IAAI,UAAU,KAAA,KAAa,UAAU,MACnC;EAGF,MAAM,cAAc,IAAI,KAAK;EAC7B,IAAI,CAAC,sBAAsB,WAAW,GACpC;EAEF,MAAM,WAAW,gBAAgB,WAAW,CAAC,CAAC,KAAK;EACnD,MAAM,WAAW,OAAO,KAAK,CAAC,CAAC,KAAK;EACpC,IAAI,CAAC,YAAY,CAAC,eAAe,QAAQ,GACvC;EAGF,MAAM,cAAc,GAAG,SAAS,GAAG;EACnC,SAAS,SAAS,GAAG,OAAO,GAAG,gBAAgB;CACjD;CAEA,OAAO;AACT;AAkBA,MAAM,sBAAsB;AAC5B,MAAM,qBAAqB;AAC3B,MAAM,kBAAkB;AACxB,MAAM,sBAAsB;AAQ5B,MAAM,sCAAsB,IAAI,IAAuB;AAMvD,MAAM,6BAAa,IAAI,QAA8C;AACrE,SAAS,qBAAqB,OAA8B;CAC1D,OAAO,OAAO,MAAM,yBAAyB,CAAC,EAAE,UAAU;AAC5D;AAEA,SAAS,eAAe,cAA8B;CACpD,IAAI,QAAQ,aAAa,aAAa;CACtC,IAAI,SAAS,aAAa,aAAa;CAEvC,KAAK,IAAI,QAAQ,GAAG,QAAQ,aAAa,QAAQ,SAAS,GAAG;EAC3D,MAAM,OAAO,aAAa,WAAW,KAAK;EAC1C,QAAQ,KAAK,KAAK,QAAQ,MAAM,UAAa;EAC7C,SAAS,KAAK,KAAK,SAAS,MAAM,UAAa;CACjD;CAEA,QACE,KAAK,KAAK,QAAS,UAAU,IAAK,UAAa,IAC/C,KAAK,KAAK,SAAU,WAAW,IAAK,UAAa;CACnD,SACE,KAAK,KAAK,SAAU,WAAW,IAAK,UAAa,IACjD,KAAK,KAAK,QAAS,UAAU,IAAK,UAAa;CAEjD,OAAO,GAAG,sBAAsB,WAAW,EAAA,CAAG,SAAS,EAAE,KAAK,UAAU,EAAA,CAAG,SAAS,EAAE;AACxF;AAEA,SAAS,mBAAmB,OAAuB;CACjD,OAAO,MAAM,QAAQ,QAAQ,MAAM;AACrC;AAEA,SAAS,aAAa,cAAiC;CACrD,MAAM,YAAY,eAAe,YAAY;CAC7C,MAAM,WAAW,oBAAoB,IAAI,SAAS;CAClD,IAAI,UAAU;EACZ,IAAI,SAAS,iBAAiB,cAC5B,MAAM,IAAI,WAAW,uCAAuC;EAE9D,OAAO;CACT;CAOA,OAAO;EAJL;EACA;EACA,MAAM,IAAI,UAAU,GAAG,mBAAmB,YAAY,EAAE;CAE/C;AACb;AAEA,SAAS,kBAAkB,OAAwB;CACjD,oBAAoB,OAAO,MAAM,SAAS;CAC1C,oBAAoB,IAAI,MAAM,WAAW,KAAK;CAC9C,OAAO,oBAAoB,OAAO,qBAAqB;EACrD,MAAM,SAAS,oBAAoB,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;EACjD,IAAI,WAAW,KAAA,GAAW;EAC1B,oBAAoB,OAAO,MAAM;CACnC;AACF;AAEA,SAAS,iBAAiB,OAAwB;CAChD,MAAM,WACJ,KAGA;CACF,WAAW,MAAM,WAAW,MAAM,IAAI;AACxC;AAEA,SAAS,oBAAoB,OAAiD;CAC5E,IAAI,OAAO,aAAa,aAAa,OAAO;CAC5C,MAAM,MAAM,SAAS;CACrB,IAAI,qBAAqB,WAAW,IAAI,QAAQ;CAChD,IAAI,CAAC,oBAAoB;EACvB,qCAAqB,IAAI,IAAI;EAC7B,WAAW,IAAI,UAAU,kBAAkB;CAC7C;CACA,MAAM,UAAU,mBAAmB,IAAI,GAAG;CAC1C,IAAI,SAAS,QAAQ,aAAa,OAAO;CAEzC,MAAM,wBAAwB,MAAM,KAClC,SAAS,iBAAmC,SAAS,oBAAoB,EAAE,CAC7E;CACA,MAAM,eACJ,sBAAsB,MAAM,aAAa,QAAQ,SAAS,KAAA,OAAe,KAAK,MAC7E,UAAU,KAAA,KAAa,sBAAsB,WAAW,IACrD,sBAAsB,KACtB,KAAA,MACJ,SAAS,cAAc,OAAO;CAChC,IAAI,CAAC,aAAa,aAAa;EAC7B,aAAa,aAAa,qBAAqB,MAAM;EACrD,IAAI,UAAU,KAAA,GAAW,aAAa,QAAQ;EAC9C,CAAC,SAAS,QAAQ,SAAS,gBAAA,CAAiB,OAAO,YAAY;CACjE;CACA,MAAM,WAA0B;EAC9B,SAAS;EACT,WAAW,qBAAqB,aAAa,WAAW;EACxD,uBAAO,IAAI,IAAI;CACjB;CACA,mBAAmB,IAAI,KAAK,QAAQ;CACpC,OAAO;AACT;AAEA,SAAS,sBAAsB,cAA8B;CAC3D,OAAO,mBAAmB,YAAY;AACxC;AAEA,SAAgB,yBAAyB,cAAsD;CAC7F,IAAI,OAAO,iBAAiB,UAAU,OAAO,KAAA;CAE7C,MAAM,aAAa,sBAAsB,YAAY;CACrD,IAAI,CAAC,YAAY,OAAO,KAAA;CAExB,MAAM,QAAQ,aAAa,UAAU;CAErC,MAAM,WAAW,oBADH,KAAK,SACsB,CAAC;CAC1C,MAAM,aAAa,UAAU,MAAM,IAAI,UAAU;CACjD,IAAI,YAAY;EACd,iBAAiB,UAAU;EAC3B,OAAO,WAAW;CACpB;CAEA,IAAI,UAAU;EACZ,IAAI,CAAC,SAAS,MAAM,IAAI,UAAU,KAAK,CAAC,SAAS,QAAQ,aAAa,SAAS,MAAM,IAAI;OACnF,SAAS,aAAa,iBACxB,MAAM,IAAI,WAAW,yCAAyC;EAAA;EAGlE,IAAI,CAAC,SAAS,QAAQ,aAAa,SAAS,MAAM,IAAI,GAAG;GACvD,SAAS,QAAQ,OAAO,MAAM,MAAM,IAAI;GACxC,SAAS,aAAa;EACxB;EACA,SAAS,MAAM,IAAI,YAAY,KAAK;CACtC;CAEA,kBAAkB,KAAK;CACvB,iBAAiB,KAAK;CAEtB,OAAO,MAAM;AACf"}
@@ -1,65 +1,28 @@
1
1
  import { classes } from "../_internal/classes.js";
2
2
  import { mergeProps } from "../_internal/merge-props.js";
3
3
  import { styleDeclarationsToClass } from "../_internal/style.js";
4
- import { mergeLayoutStyles } from "../_internal/block-layout.js";
4
+ import { mergeLayoutStyles, resolveSpaceValue, setResponsiveVar } from "../_internal/block-layout.js";
5
5
  import { intrinsicElement } from "../_internal/jsx.js";
6
6
  //#region src/components/grid/grid.tsx
7
7
  const DEFAULT_ELEMENT = "div";
8
- const BREAKPOINTS = [
9
- "base",
10
- "sm",
11
- "md",
12
- "lg",
13
- "xl"
14
- ];
15
- const SPACE_TOKEN_MAP = {
16
- "0": "0",
17
- xs: "var(--ak-space-xs)",
18
- sm: "var(--ak-space-sm)",
19
- md: "var(--ak-space-md)",
20
- lg: "var(--ak-space-lg)",
21
- xl: "var(--ak-space-xl)",
22
- "2xl": "var(--ak-space-2xl)",
23
- "3xl": "var(--ak-space-3xl)",
24
- page: "var(--ak-layout-page-gutter)"
25
- };
26
- function isResponsiveValue(value) {
27
- return Boolean(value && typeof value === "object" && !Array.isArray(value) && BREAKPOINTS.some((breakpoint) => breakpoint in value));
28
- }
29
- function normalizeResponsiveValue(value) {
30
- if (value === void 0) return void 0;
31
- if (isResponsiveValue(value)) return value;
32
- return { base: value };
33
- }
34
8
  function resolveColumns(value) {
35
9
  if (typeof value === "number") return `repeat(${value}, minmax(0, 1fr))`;
36
10
  return value.trim() || "minmax(0, 1fr)";
37
11
  }
38
12
  function resolveGap(value) {
39
- return SPACE_TOKEN_MAP[value] ?? value;
13
+ return String(resolveSpaceValue(value));
40
14
  }
41
15
  function resolveAlign(value) {
42
16
  if (value === "start") return "start";
43
17
  if (value === "end") return "end";
44
18
  return value;
45
19
  }
46
- function setResponsiveVar(styles, property, value, resolve) {
47
- const normalized = normalizeResponsiveValue(value);
48
- if (!normalized) return;
49
- for (const breakpoint of BREAKPOINTS) {
50
- const breakpointValue = normalized[breakpoint];
51
- if (breakpointValue === void 0) continue;
52
- const resolved = resolve(breakpointValue);
53
- if (resolved === void 0 || resolved === "") continue;
54
- styles[`--ak-grid-${property}-${breakpoint}`] = resolved;
55
- }
56
- }
57
20
  function Grid(props) {
58
21
  const { as, columns, gap, align, children, class: classProp, className, ref, style: userStyle, ...rest } = props;
59
22
  const styles = {};
60
- setResponsiveVar(styles, "columns", columns, resolveColumns);
61
- setResponsiveVar(styles, "gap", gap, resolveGap);
62
- setResponsiveVar(styles, "align", align, resolveAlign);
23
+ setResponsiveVar(styles, "grid-columns", columns, resolveColumns);
24
+ setResponsiveVar(styles, "grid-gap", gap, resolveGap);
25
+ setResponsiveVar(styles, "grid-align", align, resolveAlign);
63
26
  const finalProps = mergeProps(rest, {
64
27
  ref,
65
28
  class: classes("grid", classProp, className, styleDeclarationsToClass(mergeLayoutStyles(styles, userStyle))),
@@ -1 +1 @@
1
- {"version":3,"file":"grid.js","names":[],"sources":["../../../src/components/grid/grid.tsx"],"sourcesContent":["import type { JSX } from \"@askrjs/askr/jsx-runtime\";\nimport { classes } from \"../_internal/classes\";\nimport { mergeLayoutStyles } from \"../_internal/block-layout\";\nimport { mergeProps } from \"../_internal/merge-props\";\nimport { intrinsicElement } from \"../_internal/jsx\";\nimport { styleDeclarationsToClass } from \"../_internal/style\";\nimport type { BlockSpace, LayoutBreakpoint, ResponsiveValue } from \"../_internal/block-layout\";\nimport type { GridAlign, GridColumns, GridElement, GridProps } from \"./grid.types\";\n\nconst DEFAULT_ELEMENT = \"div\";\nconst BREAKPOINTS: readonly LayoutBreakpoint[] = [\"base\", \"sm\", \"md\", \"lg\", \"xl\"];\n\nconst SPACE_TOKEN_MAP: Record<BlockSpace, string> = {\n \"0\": \"0\",\n xs: \"var(--ak-space-xs)\",\n sm: \"var(--ak-space-sm)\",\n md: \"var(--ak-space-md)\",\n lg: \"var(--ak-space-lg)\",\n xl: \"var(--ak-space-xl)\",\n \"2xl\": \"var(--ak-space-2xl)\",\n \"3xl\": \"var(--ak-space-3xl)\",\n page: \"var(--ak-layout-page-gutter)\",\n};\n\nfunction isResponsiveValue<T>(\n value: ResponsiveValue<T> | undefined,\n): value is Partial<Record<LayoutBreakpoint, T>> {\n return Boolean(\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n BREAKPOINTS.some((breakpoint) => breakpoint in value),\n );\n}\n\nfunction normalizeResponsiveValue<T>(\n value: ResponsiveValue<T> | undefined,\n): Partial<Record<LayoutBreakpoint, T>> | undefined {\n if (value === undefined) return undefined;\n if (isResponsiveValue(value)) return value;\n return { base: value };\n}\n\nfunction resolveColumns(value: GridColumns): string {\n if (typeof value === \"number\") {\n return `repeat(${value}, minmax(0, 1fr))`;\n }\n\n const trimmed = value.trim();\n return trimmed || \"minmax(0, 1fr)\";\n}\n\nfunction resolveGap(value: BlockSpace): string {\n return SPACE_TOKEN_MAP[value] ?? value;\n}\n\nfunction resolveAlign(value: GridAlign): string {\n if (value === \"start\") return \"start\";\n if (value === \"end\") return \"end\";\n return value;\n}\n\nfunction setResponsiveVar<T>(\n styles: Record<string, string | number>,\n property: string,\n value: ResponsiveValue<T> | undefined,\n resolve: (value: T) => string | number | undefined,\n) {\n const normalized = normalizeResponsiveValue(value);\n if (!normalized) return;\n\n for (const breakpoint of BREAKPOINTS) {\n const breakpointValue = normalized[breakpoint];\n if (breakpointValue === undefined) continue;\n const resolved = resolve(breakpointValue);\n if (resolved === undefined || resolved === \"\") continue;\n styles[`--ak-grid-${property}-${breakpoint}`] = resolved;\n }\n}\n\nexport function Grid<TElement extends GridElement = \"div\">(\n props: GridProps<TElement>,\n): JSX.Element {\n const {\n as,\n columns,\n gap,\n align,\n children,\n class: classProp,\n className,\n ref,\n style: userStyle,\n ...rest\n } = props as GridProps<GridElement> & {\n class?: unknown;\n className?: unknown;\n style?: unknown;\n };\n\n const styles: Record<string, string | number> = {};\n setResponsiveVar(styles, \"columns\", columns, resolveColumns);\n setResponsiveVar(styles, \"gap\", gap, resolveGap);\n setResponsiveVar(styles, \"align\", align, resolveAlign);\n\n const generatedClass = styleDeclarationsToClass(mergeLayoutStyles(styles, userStyle));\n const finalProps = mergeProps(rest, {\n ref,\n class: classes(\"grid\", classProp, className, generatedClass),\n \"data-slot\": \"grid\",\n });\n\n return intrinsicElement(as ?? DEFAULT_ELEMENT, finalProps, children);\n}\n"],"mappings":";;;;;;AASA,MAAM,kBAAkB;AACxB,MAAM,cAA2C;CAAC;CAAQ;CAAM;CAAM;CAAM;AAAI;AAEhF,MAAM,kBAA8C;CAClD,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,MAAM;AACR;AAEA,SAAS,kBACP,OAC+C;CAC/C,OAAO,QACL,SACA,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,YAAY,MAAM,eAAe,cAAc,KAAK,CACtD;AACF;AAEA,SAAS,yBACP,OACkD;CAClD,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,kBAAkB,KAAK,GAAG,OAAO;CACrC,OAAO,EAAE,MAAM,MAAM;AACvB;AAEA,SAAS,eAAe,OAA4B;CAClD,IAAI,OAAO,UAAU,UACnB,OAAO,UAAU,MAAM;CAIzB,OADgB,MAAM,KACT,KAAK;AACpB;AAEA,SAAS,WAAW,OAA2B;CAC7C,OAAO,gBAAgB,UAAU;AACnC;AAEA,SAAS,aAAa,OAA0B;CAC9C,IAAI,UAAU,SAAS,OAAO;CAC9B,IAAI,UAAU,OAAO,OAAO;CAC5B,OAAO;AACT;AAEA,SAAS,iBACP,QACA,UACA,OACA,SACA;CACA,MAAM,aAAa,yBAAyB,KAAK;CACjD,IAAI,CAAC,YAAY;CAEjB,KAAK,MAAM,cAAc,aAAa;EACpC,MAAM,kBAAkB,WAAW;EACnC,IAAI,oBAAoB,KAAA,GAAW;EACnC,MAAM,WAAW,QAAQ,eAAe;EACxC,IAAI,aAAa,KAAA,KAAa,aAAa,IAAI;EAC/C,OAAO,aAAa,SAAS,GAAG,gBAAgB;CAClD;AACF;AAEA,SAAgB,KACd,OACa;CACb,MAAM,EACJ,IACA,SACA,KACA,OACA,UACA,OAAO,WACP,WACA,KACA,OAAO,WACP,GAAG,SACD;CAMJ,MAAM,SAA0C,CAAC;CACjD,iBAAiB,QAAQ,WAAW,SAAS,cAAc;CAC3D,iBAAiB,QAAQ,OAAO,KAAK,UAAU;CAC/C,iBAAiB,QAAQ,SAAS,OAAO,YAAY;CAGrD,MAAM,aAAa,WAAW,MAAM;EAClC;EACA,OAAO,QAAQ,QAAQ,WAAW,WAHb,yBAAyB,kBAAkB,QAAQ,SAAS,CAGvB,CAAC;EAC3D,aAAa;CACf,CAAC;CAED,OAAO,iBAAiB,MAAM,iBAAiB,YAAY,QAAQ;AACrE"}
1
+ {"version":3,"file":"grid.js","names":[],"sources":["../../../src/components/grid/grid.tsx"],"sourcesContent":["import type { JSX } from \"@askrjs/askr/jsx-runtime\";\nimport { classes } from \"../_internal/classes\";\nimport { mergeLayoutStyles, resolveSpaceValue, setResponsiveVar } from \"../_internal/block-layout\";\nimport { mergeProps } from \"../_internal/merge-props\";\nimport { intrinsicElement } from \"../_internal/jsx\";\nimport { styleDeclarationsToClass } from \"../_internal/style\";\nimport type { BlockSpace } from \"../_internal/block-layout\";\nimport type { GridAlign, GridColumns, GridElement, GridProps } from \"./grid.types\";\n\nconst DEFAULT_ELEMENT = \"div\";\nfunction resolveColumns(value: GridColumns): string {\n if (typeof value === \"number\") {\n return `repeat(${value}, minmax(0, 1fr))`;\n }\n\n const trimmed = value.trim();\n return trimmed || \"minmax(0, 1fr)\";\n}\n\nfunction resolveGap(value: BlockSpace): string {\n return String(resolveSpaceValue(value));\n}\n\nfunction resolveAlign(value: GridAlign): string {\n if (value === \"start\") return \"start\";\n if (value === \"end\") return \"end\";\n return value;\n}\n\nexport function Grid<TElement extends GridElement = \"div\">(\n props: GridProps<TElement>,\n): JSX.Element {\n const {\n as,\n columns,\n gap,\n align,\n children,\n class: classProp,\n className,\n ref,\n style: userStyle,\n ...rest\n } = props as GridProps<GridElement> & {\n class?: unknown;\n className?: unknown;\n style?: unknown;\n };\n\n const styles: Record<string, string | number> = {};\n setResponsiveVar(styles, \"grid-columns\", columns, resolveColumns);\n setResponsiveVar(styles, \"grid-gap\", gap, resolveGap);\n setResponsiveVar(styles, \"grid-align\", align, resolveAlign);\n\n const generatedClass = styleDeclarationsToClass(mergeLayoutStyles(styles, userStyle));\n const finalProps = mergeProps(rest, {\n ref,\n class: classes(\"grid\", classProp, className, generatedClass),\n \"data-slot\": \"grid\",\n });\n\n return intrinsicElement(as ?? DEFAULT_ELEMENT, finalProps, children);\n}\n"],"mappings":";;;;;;AASA,MAAM,kBAAkB;AACxB,SAAS,eAAe,OAA4B;CAClD,IAAI,OAAO,UAAU,UACnB,OAAO,UAAU,MAAM;CAIzB,OADgB,MAAM,KACT,KAAK;AACpB;AAEA,SAAS,WAAW,OAA2B;CAC7C,OAAO,OAAO,kBAAkB,KAAK,CAAC;AACxC;AAEA,SAAS,aAAa,OAA0B;CAC9C,IAAI,UAAU,SAAS,OAAO;CAC9B,IAAI,UAAU,OAAO,OAAO;CAC5B,OAAO;AACT;AAEA,SAAgB,KACd,OACa;CACb,MAAM,EACJ,IACA,SACA,KACA,OACA,UACA,OAAO,WACP,WACA,KACA,OAAO,WACP,GAAG,SACD;CAMJ,MAAM,SAA0C,CAAC;CACjD,iBAAiB,QAAQ,gBAAgB,SAAS,cAAc;CAChE,iBAAiB,QAAQ,YAAY,KAAK,UAAU;CACpD,iBAAiB,QAAQ,cAAc,OAAO,YAAY;CAG1D,MAAM,aAAa,WAAW,MAAM;EAClC;EACA,OAAO,QAAQ,QAAQ,WAAW,WAHb,yBAAyB,kBAAkB,QAAQ,SAAS,CAGvB,CAAC;EAC3D,aAAa;CACf,CAAC;CAED,OAAO,iBAAiB,MAAM,iBAAiB,YAAY,QAAQ;AACrE"}
@@ -5,8 +5,5 @@ declare global {
5
5
  interface Element extends JSXElement {
6
6
  readonly __askrThemesJsxElementBrand?: never;
7
7
  }
8
- interface IntrinsicElements {
9
- [element: string]: Record<string, unknown>;
10
- }
11
8
  }
12
9
  }
@@ -1,6 +1,7 @@
1
1
  import { Button } from "@askrjs/ui";
2
2
  import { jsx } from "@askrjs/askr/jsx-runtime";
3
3
  import { defineScope, getSignal, readScope, state } from "@askrjs/askr";
4
+ import { cloneElement, isElement } from "@askrjs/askr/foundations/structures";
4
5
  //#region src/components/theme/theme.tsx
5
6
  const CAT_THEME_NAMES = [
6
7
  "tabby",
@@ -47,7 +48,6 @@ const CAT_THEME_OPTIONS = [
47
48
  ];
48
49
  const DEFAULT_STORAGE_KEY = "askr-theme";
49
50
  const STATIC_CHILDREN = Symbol.for("askr.static-children");
50
- const STATIC_CHILD_SLOTS_CACHE = Symbol.for("__askrStaticChildSlots");
51
51
  const documentThemeCoordinators = /* @__PURE__ */ new WeakMap();
52
52
  const ThemeScopeContext = defineScope({
53
53
  theme: () => "system",
@@ -131,6 +131,11 @@ function getDefaultThemeCoordinator() {
131
131
  documentThemeCoordinators.set(document, coordinator);
132
132
  return coordinator;
133
133
  }
134
+ function removeEmptyGeneratedStyleRegistries(root) {
135
+ const ownerDocument = root?.nodeType === 9 ? root : root?.ownerDocument ?? (typeof document === "undefined" ? null : document);
136
+ if (!ownerDocument) return;
137
+ for (const registry of ownerDocument.querySelectorAll("style[data-askr-style-registry]")) if (!registry.textContent?.trim()) registry.remove();
138
+ }
134
139
  function createThemeCoordinator() {
135
140
  const scopes = /* @__PURE__ */ new Map();
136
141
  let nextSequence = 0;
@@ -154,6 +159,7 @@ function createThemeCoordinator() {
154
159
  setTimeout(() => {
155
160
  scheduled = false;
156
161
  syncActive();
162
+ if (scopes.size === 0) removeEmptyGeneratedStyleRegistries(root);
157
163
  }, 0);
158
164
  };
159
165
  return Object.freeze({
@@ -296,9 +302,6 @@ function renderThemeToggleIconSlots(theme, icons) {
296
302
  children: cloneThemeToggleIcon(icon, slotTheme)
297
303
  }, slotTheme));
298
304
  }
299
- function isJSXElement(value) {
300
- return typeof value === "object" && value !== null && "$$typeof" in value && "type" in value && "props" in value;
301
- }
302
305
  function cloneThemeToggleIcon(icon, key) {
303
306
  if (Array.isArray(icon)) {
304
307
  const clonedChildren = icon.map((child) => cloneThemeToggleIcon(child));
@@ -308,18 +311,14 @@ function cloneThemeToggleIcon(icon, key) {
308
311
  });
309
312
  return clonedChildren;
310
313
  }
311
- if (!isJSXElement(icon)) return icon;
314
+ if (!isElement(icon)) return icon;
312
315
  const props = icon.props;
313
316
  const clonedProps = props ? { ...props } : {};
314
317
  if ("children" in clonedProps) clonedProps.children = cloneThemeToggleIcon(clonedProps.children);
315
- const iconKey = icon.key ?? key ?? null;
316
- const clonedIcon = {
317
- ...icon,
318
- key: iconKey,
319
- props: clonedProps
318
+ return {
319
+ ...cloneElement(icon, clonedProps),
320
+ key: icon.key ?? key ?? null
320
321
  };
321
- delete clonedIcon[STATIC_CHILD_SLOTS_CACHE];
322
- return clonedIcon;
323
322
  }
324
323
  function syncThemeTarget(html, themeChoice) {
325
324
  if (!html) return;