@waggylabs/yumekit 0.5.0 → 0.5.1-beta.12

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 (166) hide show
  1. package/CHANGELOG.md +91 -1
  2. package/CONTRIBUTING.md +1 -1
  3. package/dist/components/y-appbar.js +473 -132
  4. package/dist/components/y-banner.js +394 -104
  5. package/dist/components/y-breadcrumbs.js +25 -13
  6. package/dist/components/y-break/y-break.d.ts +1 -1
  7. package/dist/components/y-break.d.ts +1 -1
  8. package/dist/components/y-break.js +40 -21
  9. package/dist/components/y-button/y-button.d.ts +14 -0
  10. package/dist/components/y-button.d.ts +14 -0
  11. package/dist/components/y-button.js +370 -92
  12. package/dist/components/y-card.js +2 -1
  13. package/dist/components/y-checkbox.js +36 -16
  14. package/dist/components/y-code/tokenizer.d.ts +2 -0
  15. package/dist/components/y-code/y-code.d.ts +75 -0
  16. package/dist/components/y-code.d.ts +75 -0
  17. package/dist/components/y-code.js +2557 -0
  18. package/dist/components/y-color/y-color.d.ts +6 -0
  19. package/dist/components/y-color.d.ts +6 -0
  20. package/dist/components/y-color.js +219 -38
  21. package/dist/components/y-colorpicker.js +194 -36
  22. package/dist/components/y-data-grid/y-data-grid.d.ts +315 -0
  23. package/dist/components/y-data-grid.d.ts +315 -0
  24. package/dist/components/y-data-grid.js +13094 -0
  25. package/dist/components/y-date/y-date.d.ts +6 -0
  26. package/dist/components/y-date.d.ts +6 -0
  27. package/dist/components/y-date.js +1207 -256
  28. package/dist/components/y-datepicker/y-datepicker.d.ts +9 -0
  29. package/dist/components/y-datepicker.d.ts +9 -0
  30. package/dist/components/y-datepicker.js +1096 -167
  31. package/dist/components/y-dialog.js +2 -1
  32. package/dist/components/y-dock.js +25 -13
  33. package/dist/components/y-drawer.js +4 -1
  34. package/dist/components/y-droplist/y-droplist.d.ts +8 -0
  35. package/dist/components/y-droplist.d.ts +8 -0
  36. package/dist/components/y-droplist.js +50 -4
  37. package/dist/components/y-gallery.js +26 -14
  38. package/dist/components/y-help/y-help.d.ts +144 -0
  39. package/dist/components/y-help.d.ts +144 -0
  40. package/dist/components/y-help.js +4304 -0
  41. package/dist/components/y-icon/y-icon.d.ts +7 -2
  42. package/dist/components/y-icon.d.ts +7 -2
  43. package/dist/components/y-icon.js +25 -13
  44. package/dist/components/y-input/y-input.d.ts +7 -0
  45. package/dist/components/y-input.d.ts +7 -0
  46. package/dist/components/y-input.js +34 -4
  47. package/dist/components/y-menu/y-menu.d.ts +1 -0
  48. package/dist/components/y-menu.d.ts +1 -0
  49. package/dist/components/y-menu.js +98 -38
  50. package/dist/components/y-paginator/y-paginator.d.ts +17 -0
  51. package/dist/components/y-paginator.d.ts +17 -0
  52. package/dist/components/y-paginator.js +704 -124
  53. package/dist/components/y-popover/y-popover.d.ts +164 -0
  54. package/dist/components/y-popover.d.ts +164 -0
  55. package/dist/components/y-popover.js +2157 -0
  56. package/dist/components/y-progress.js +2 -1
  57. package/dist/components/y-radio.js +9 -2
  58. package/dist/components/y-rating/y-rating.d.ts +2 -2
  59. package/dist/components/y-rating.d.ts +2 -2
  60. package/dist/components/y-rating.js +47 -14
  61. package/dist/components/y-select/y-select.d.ts +19 -0
  62. package/dist/components/y-select.d.ts +19 -0
  63. package/dist/components/y-select.js +160 -32
  64. package/dist/components/y-shape/y-shape.d.ts +39 -0
  65. package/dist/components/y-shape.d.ts +39 -0
  66. package/dist/components/y-shape.js +302 -0
  67. package/dist/components/y-sidebar/y-sidebar.d.ts +9 -0
  68. package/dist/components/y-sidebar.d.ts +9 -0
  69. package/dist/components/y-sidebar.js +493 -131
  70. package/dist/components/y-slider.js +4 -2
  71. package/dist/components/y-splitter.js +25 -13
  72. package/dist/components/y-stepper/y-stepper.d.ts +16 -0
  73. package/dist/components/y-stepper.d.ts +16 -0
  74. package/dist/components/y-stepper.js +124 -21
  75. package/dist/components/y-switch.js +21 -5
  76. package/dist/components/y-tabs/y-tabs.d.ts +7 -0
  77. package/dist/components/y-tabs.d.ts +7 -0
  78. package/dist/components/y-tabs.js +102 -28
  79. package/dist/components/y-tag.js +2 -6
  80. package/dist/components/y-textarea/y-textarea.d.ts +6 -0
  81. package/dist/components/y-textarea.d.ts +6 -0
  82. package/dist/components/y-textarea.js +23 -1
  83. package/dist/components/y-theme/y-theme.d.ts +1 -0
  84. package/dist/components/y-theme.d.ts +1 -0
  85. package/dist/components/y-theme.js +197 -33
  86. package/dist/components/y-toast.js +25 -13
  87. package/dist/components/y-tree-item.js +25 -13
  88. package/dist/components/y-tree.js +25 -13
  89. package/dist/icons/all-filled.d.ts +1 -0
  90. package/dist/icons/all-filled.js +362 -0
  91. package/dist/icons/all.js +7 -3
  92. package/dist/icons/registry.d.ts +2 -0
  93. package/dist/icons/registry.js +6 -1
  94. package/dist/index.d.ts +5 -0
  95. package/dist/index.js +21854 -11081
  96. package/dist/modules/floating.d.ts +126 -0
  97. package/dist/modules/floating.js +285 -0
  98. package/dist/modules/floating.test.js +180 -0
  99. package/dist/modules/helpers.d.ts +29 -7
  100. package/dist/modules/helpers.js +42 -15
  101. package/dist/modules/helpers.test.js +107 -0
  102. package/dist/react.d.ts +134 -2
  103. package/dist/styles/ant-blue-dark.css +226 -0
  104. package/dist/styles/ant-blue-light.css +226 -0
  105. package/dist/styles/ant-green-dark.css +226 -0
  106. package/dist/styles/ant-green-light.css +226 -0
  107. package/dist/styles/blue-dark.css +18 -9
  108. package/dist/styles/blue-light.css +16 -7
  109. package/dist/styles/bootstrap-dark.css +227 -0
  110. package/dist/styles/bootstrap-light.css +227 -0
  111. package/dist/styles/brown-dark.css +18 -9
  112. package/dist/styles/brown-light.css +16 -7
  113. package/dist/styles/carbon-dark.css +227 -0
  114. package/dist/styles/carbon-light.css +227 -0
  115. package/dist/styles/catppuccin-frappe.css +215 -0
  116. package/dist/styles/catppuccin-latte.css +215 -0
  117. package/dist/styles/catppuccin-macchiato.css +215 -0
  118. package/dist/styles/catppuccin-mocha.css +215 -0
  119. package/dist/styles/green-dark.css +18 -9
  120. package/dist/styles/green-light.css +16 -7
  121. package/dist/styles/indigo-dark.css +18 -9
  122. package/dist/styles/indigo-light.css +16 -7
  123. package/dist/styles/kepler-amber.css +224 -0
  124. package/dist/styles/kepler-dark.css +224 -0
  125. package/dist/styles/kepler-galaxy.css +224 -0
  126. package/dist/styles/kepler-light.css +224 -0
  127. package/dist/styles/kepler-matrix.css +224 -0
  128. package/dist/styles/material-blue-dark.css +240 -0
  129. package/dist/styles/material-blue-light.css +240 -0
  130. package/dist/styles/material-purple-dark.css +240 -0
  131. package/dist/styles/material-purple-light.css +240 -0
  132. package/dist/styles/mono-dark.css +219 -0
  133. package/dist/styles/mono-light.css +219 -0
  134. package/dist/styles/neobrutalist-dark.css +239 -0
  135. package/dist/styles/neobrutalist.css +239 -0
  136. package/dist/styles/nord-aurora.css +215 -0
  137. package/dist/styles/nord.css +215 -0
  138. package/dist/styles/olive-dark.css +18 -9
  139. package/dist/styles/olive-light.css +16 -7
  140. package/dist/styles/orange-dark.css +18 -9
  141. package/dist/styles/orange-light.css +16 -7
  142. package/dist/styles/pink-dark.css +18 -9
  143. package/dist/styles/pink-light.css +16 -7
  144. package/dist/styles/primer-dark-dimmed.css +238 -0
  145. package/dist/styles/primer-dark.css +238 -0
  146. package/dist/styles/primer-light.css +238 -0
  147. package/dist/styles/purple-dark.css +18 -9
  148. package/dist/styles/purple-light.css +16 -7
  149. package/dist/styles/red-dark.css +18 -9
  150. package/dist/styles/red-light.css +16 -7
  151. package/dist/styles/rose-dark.css +219 -0
  152. package/dist/styles/rose-light.css +219 -0
  153. package/dist/styles/shadcn-blue-dark.css +238 -0
  154. package/dist/styles/shadcn-blue-light.css +238 -0
  155. package/dist/styles/shadcn-dark.css +238 -0
  156. package/dist/styles/shadcn-light.css +238 -0
  157. package/dist/styles/slate-dark.css +219 -0
  158. package/dist/styles/slate-light.css +219 -0
  159. package/dist/styles/teal-dark.css +18 -9
  160. package/dist/styles/teal-light.css +16 -7
  161. package/dist/styles/variables.css +115 -13
  162. package/dist/styles/yellow-dark.css +18 -9
  163. package/dist/styles/yellow-light.css +16 -7
  164. package/dist/yumekit.min.js +1 -1
  165. package/llm.txt +437 -49
  166. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -31,7 +31,97 @@ Delete any empty sections before publishing.
31
31
  <!-- ### Security -->
32
32
  <!-- Vulnerability patches or hardening changes -->
33
33
 
34
- ## [0.5.0]
34
+ ## [0.5.1]
35
+
36
+ ### Added
37
+
38
+ - `y-checkbox` / `y-radio` — checked-state color hooks so themes can fill the control on selection: `--component-checkbox-checked-background` / `-checked-border-color` / `-checked-icon-color` and `--component-radio-background` / `-checked-background` / `-checked-border-color` / `-checked-dot-color`. Each falls back to the matching unchecked value, so existing themes are unchanged. The design-system themes now use them — checked checkboxes (and Shadcn/Bootstrap/Primer radios) fill with the primary color and draw the check/dot in the primary-inverse color, matching each system's native look.
39
+
40
+ - Several theme color variations including `Slate`, `Rose`, the `Catppuccin` and `Nord` color schemes, two `Neobrutalist` themes, as well as several new themes based on some of the most popular design systems. This includes Material, Carbon, Ant, Shadcn, Primer, Bootstrap, and a few throwback themes inspired by Yumekit's spiritual ancestor: `Kepler UI`.
41
+
42
+ - `y-tabs` — new `variant="accent"` style: minimal tabs where the active tab shows a primary-colored indicator border on its content-facing edge (bottom for top tabs, etc.). The default bordered style is unchanged. Adds `--component-tabs-accent-width` (indicator thickness). The border-width token is normalized to `--component-tabs-border-width` (matching `--component-tabs-border-color`); the legacy `--component-tab-border-width` is still honored as a fallback.
43
+
44
+ - Form fields (`y-input`, `y-textarea`, `y-select`, `y-color`, `y-date`) — new `variant="underline"` style: a bottom-only border with square bottom corners (the Material/Carbon text-field look) instead of the full-border `"default"`. Hover/focus/invalid states still color the underline. Helps match design systems that use underlined fields.
45
+
46
+ - New `y-data-grid` component — interactive grid for large or dynamic datasets with client- or server-side sorting, filtering, and pagination, single/multi row selection, inline cell editing, nested row grouping with aggregates, multi-column header groups, virtual scrolling, an optional per-column header menu (filter, sort, visibility, reorder), and a sticky header.
47
+
48
+ - New `y-popover` component — target-anchored floating panel with rich slotted content, composable triggers (`click` / `hover` / `focus` / `context-menu` / `manual`), flip-on-collision positioning, optional modal mode with focus trap, and an opt-in `portal` mode that renders into `<body>` to escape ancestor stacking contexts.
49
+
50
+ - New `y-help` component — guided product-tour / onboarding overlay. Walks users through an ordered list of steps with a dimmed SVG highlight, anchored tooltip, prev/next controls, overlay-edge arrows, and keyboard shortcuts.
51
+
52
+ - New `y-code` component — code-block container with line numbers, copy-to-clipboard (block and per-line), `max-lines` collapse, and an optional filename header. Built-in tokenizer covers JavaScript, TypeScript, JSON, CSS, Python, Bash, and HTML; emits Prism-compatible classes so existing Prism stylesheets layer on cleanly, or pipe an external highlighter's output through the sanitized `highlighted` slot.
53
+
54
+ - New `y-shape` component — presentational container that clips its slotted content into a geometric shape (rectangle, circle, ellipse, star, heart, chat-bubble, times, cross, or a custom `polygon`) via CSS `clip-path`. Suitable for avatar masks, decorative panels, and non-rectangular skeletons.
55
+
56
+ - `y-stepper` — `responsive` and `responsive-breakpoint` attributes; auto-flips horizontal layouts to vertical below the breakpoint (600px default). Enabled by default; set `responsive="false"` to opt out.
57
+
58
+ - Filled icon variants for `y-icon` via a new `weight="filled"` value, with automatic fallback to the line icon when no filled version is registered. 116 filled icons ship under `icons/all-filled.js` (also pulled in by `icons/all.js`); the remaining component-illustration icons fall back to their line versions.
59
+
60
+ - New theming hooks: `--component-control-height-{size}` (shared min-height for `y-button` and `y-input` so fields and buttons match per theme, falling back to `--sizing-{size}`), `--component-checkbox-border-radius` (lets checkboxes use a tighter radius than text inputs). Outlined `y-button`s now source their border from the matching semantic border token (`--base-border`, `--error-border`, …) per color, falling back to the button's text color when that token is unset; `--component-button-outline-border` / `--component-button-outline-border-color` remain available as optional global overrides. Defaults preserve the existing look for all current themes.
61
+
62
+ ### Changed
63
+
64
+ - `y-radio` — the default YumeKit color themes and the Kepler themes now color a selected radio's border with the primary color (via `--component-radio-checked-border-color`); the fill and dot are unchanged. Neobrutalist and the design-system themes already define their own checked styling and are unchanged.
65
+
66
+ - `y-checkbox` — the default YumeKit color themes and the Kepler themes now mark a checked box with a translucent primary-colored fill, a primary border, and a primary-colored check (via the existing `--component-checkbox-checked-background` / `-checked-border-color` / `-checked-icon-color` hooks).
67
+
68
+ - `y-switch` — the "on" state now fills the track with a translucent tint of the switch color and colors the border to match (derived from `on-color`, custom colors included), making it clearer which state is active; the tint strength is themeable via `--component-switch-on-fill-opacity` (16% default).
69
+
70
+ - `y-break` — the divider line now uses the semantic border color (`base.border`) instead of `base.content.lightest`, matching other component borders, and the host now applies default perpendicular spacing (above/below a horizontal break, left/right of a vertical one) via the new `--component-break-spacing` token (defaults to `--spacing-medium`) so a break separates content out of the box. The line color and thickness also gained `--base-border` / `1px` fallbacks for use without a full token set.
71
+
72
+ - `y-button` — `--component-button-border-width` is now applied as the `border-width` longhand instead of being baked into the `border` shorthand, so it accepts a 1–4 value pattern for per-side widths (e.g. `0 0 2px 0` for a bottom-only border). Default (`1px`) is unchanged. The `--component-button-outline-border` shorthand override now controls border style + color only; its width is superseded by `--component-button-border-width`.
73
+
74
+ - Every bordered component now applies its `--component-*-border-width` token as the `border-width` longhand (out of the `border` shorthand), so each accepts a 1–4 value pattern for per-side borders, consistent with `y-button` and the form fields: surfaces/containers (`y-card`, `y-menu`, `y-dialog`, `y-popover`, `y-datepicker`, `y-data-grid`, `y-appbar`, `y-sidebar`, `y-tabs`) and controls (`y-checkbox`, `y-radio`, `y-switch`, `y-slider`, `y-progress`). Default rendering is unchanged.
75
+
76
+ - Form fields (`y-input`, `y-textarea`, `y-select`, `y-color`, `y-date`) — `--component-inputs-border-width` is now applied as the `border-width` longhand (out of the `border` shorthand) on every field surface, including the `y-select` dropdown panel and the `y-color` picker popup, so like `y-button` it accepts a 1–4 value pattern for per-side borders.
77
+
78
+ - `y-button` — Outlined button borders were changed to use semantic border values instead of content color. Padding can now be set per-axis via `--component-button-padding-block-{size}` / `--component-button-padding-inline-{size}` (overriding, and falling back to, the all-sides `--component-button-padding-{size}`), plus a new `padding-mode` attribute (`auto` (default) / `square` / `wide`) controlling whether the inline axis collapses to the block value. `auto` makes icon-only buttons square automatically; `square`/`wide` force it. The Material themes use this for wide pill buttons that stay round when icon-only; `y-paginator` number buttons and `y-datepicker` day / month / year buttons set `padding-mode="square"` so they don't bloat under the wide Material padding.
79
+
80
+ - Custom color support expanded to the browser-native color functions — `hwb()`, `lab()`, `lch()`, `oklab()`, `oklch()`, and `color()` — in addition to `#hex`, `rgb()`/`rgba()`, and `hsl()`/`hsla()`. The shared `isSafeCssColor` gate now also tightens its argument allowlist (rejecting semicolons, braces, angle brackets, and nested functions). Applies anywhere a `color` accepts a custom value, including `y-badge`, `y-select`, `y-popover`, `y-button`, `y-tag`, `y-icon`, and `y-rating`.
81
+
82
+ - `y-rating` — selected icons now swap in the registered `filled` weight variant instead of just thickening the line stroke, falling back to the thick stroke when no filled variant is available.
83
+
84
+ - `y-paginator` — page-button list now auto-shrinks to fit the host width, growing back when space allows.
85
+
86
+ - `y-select` — new opt-in `portal` attribute renders the dropdown into `<body>` so it escapes scrollable or clipped ancestors (e.g. inside a data-grid cell editor).
87
+
88
+ - **Breaking** `y-break`: `inset` values renamed from `"sm"` / `"md"` / `"lg"` to `"small"` / `"medium"` / `"large"` to match the size scale used by every other component. Spacing mapping is unchanged (`small` → `--spacing-x-small`, `medium` → `--spacing-medium`, `large` → `--spacing-x-large`), so visual output is identical after the find-and-replace.
89
+
90
+ ### Fixed
91
+
92
+ - `y-menu` — a menu anchored to a disabled trigger no longer opens when the trigger is clicked. The anchor's disabled state (native `disabled`, a custom element's reflected `disabled` attribute, or `aria-disabled="true"`) is checked at click time, so toggling it back on restores normal behavior.
93
+
94
+ - `y-sidebar` — nav/footer icons now stay in the same position between the expanded and collapsed states under themes whose borders use a multi-value width (e.g. the Neobrutalist offset border `2px 2px 6px 2px`). The icon-column width is now derived from the sidebar's resolved horizontal border (flat buttons render no border) instead of an invalid `calc()` that multiplied the multi-value token, which had collapsed the column to `auto` and shifted icons.
95
+
96
+ - `y-drawer` — corners closest to the screen's edge are now squared in all themes.
97
+
98
+ - `y-datepicker` — the month and year pickers were reworked. The month picker (`show-days="false"`) now shows a selectable year dropdown in its header (toggled by `show-years`, omitted when `false`) above the twelve months, and the year picker (`show-months="false"`) now bounds its scrollable year grid with two start/end year inputs. Clicking a month or year now selects it and fires `change`; clicking a year in the year picker no longer shifts the visible range.
99
+
100
+ - `y-theme` — switching themes now clears the previous theme's CSS custom properties from the host before applying the new ones. Variables defined only by the outgoing theme (e.g. a theme-specific token like `--component-tabs-inactive-background`) previously lingered inline and "stuck" until a page reload; they are now removed on every switch.
101
+
102
+ - `y-tabs` — unselected tabs now use a dedicated `--component-tabs-inactive-background` (falling back to `--component-tabs-border-color`, so existing themes are unchanged) instead of always painting the tab background with the border color. This fixes the Neobrutalist themes, where the border color equals the text color and made unselected tab labels unreadable; both Neobrutalist themes now set it to a distinct surface tone.
103
+
104
+ - Portaled overlays now inherit the active theme. `y-help` (tour overlay/tooltip), `y-popover` (`portal` mode), and `y-select` (`portal` mode) previously rendered into `document.body`, escaping the `<y-theme>` subtree that scopes the theme's CSS custom properties — so they fell back to the default un-themed palette. They now mount into the nearest enclosing `<y-theme>`, walking up across shadow boundaries so the fix also applies when the component is used inside another component's shadow root (e.g. `y-data-grid`'s per-column header menus), falling back to `document.body` when there is no theme ancestor. The portaled surface matches the active theme and tracks live theme switches. Keep the component inside your `<y-theme>`.
105
+
106
+ - Form field components now share one field background. `y-select` (trigger and dropdown) used `base.background.app` while `y-input` / `y-textarea` / `y-color` / `y-date` used `base.background.component`; `select.background` is now `base.background.component` across all themes, so fields match when placed together on a form (most visible in the Material and Carbon themes). The select dropdown panel now also matches menus/popovers.
107
+
108
+ - `y-avatar` — the three `shape` values are now visually distinct. Added a `--component-avatar-border-radius-rounded` token (medium radius) and changed `square` to a zero radius (sharp corners); `circle` is unchanged.
109
+
110
+ - `y-tag` — Increased the inline padding size for all sizes of `y-tag` component.
111
+
112
+ - `y-tabs` — the tab panel no longer creates a stacking context (`z-index: 0` removed), which was trapping `position: fixed` overlays rendered by slotted components (e.g. `y-gallery`'s lightbox) underneath the tab strip and surrounding page content.
113
+
114
+ - `y-gallery` — the lightbox overlay's default z-index was raised from 1000 to 9000 so it layers above fixed chrome like `y-dock` (8000); override via `--component-gallery-expand-z-index`.
115
+
116
+ - `y-menu` — selected items now use the primary inverse content color for their text, so the label stays readable against the primary-colored selected background across all themes.
117
+
118
+ - `y-button` — no longer throws when `color` is set to an unrecognized value that isn't a valid custom color; it now falls back to the `base` theme instead of crashing while reading the color-token map.
119
+
120
+ - `y-droplist` — touch drag now works reliably on iOS Safari and Chrome Android. `touch-action: none` is applied to the press target at decoration time instead of from inside `pointerdown`, so mobile browsers stop preempting the press as a scroll gesture.
121
+
122
+ - Corrected the arrow direction on the `left-from-bracket`, `right-from-bracket`, and `left-to-bracket` icons, which previously pointed the wrong way relative to their bracket (the `*-from-*` arrows now exit the bracket and the `*-to-*` arrow enters it).
123
+
124
+ ## [0.5.0] - 2026-05-25
35
125
 
36
126
  ### Added
37
127
 
package/CONTRIBUTING.md CHANGED
@@ -87,7 +87,7 @@ if (this.querySelector('[slot="icon"]')) { ... }
87
87
 
88
88
  The DOM-element, icon, and slot rules above exist primarily to keep user-controlled values out of `innerHTML` template strings, where attribute interpolation can break out of the surrounding quote. Building the shadow tree with `_el` and writing values through `setAttribute` makes that breakout impossible — the entire string becomes a single attribute value, no matter what quotes or angle brackets it contains. Two shared helpers cover the cases where `_el` alone isn't enough:
89
89
 
90
- - **CSS color literals (`isSafeCssColor` from `src/modules/helpers.js`).** When a component paints a user-supplied color into any CSS context — an inline `style` attribute, a `<style>` block built via `replaceSync`, or a CSS variable — gate the value through `isSafeCssColor` first. It accepts only `#hex`, `rgb()`/`rgba()`, and `hsl()`/`hsla()` literals; everything else (including named colors, `var(...)`, `currentColor`, and anything containing whitespace, semicolons, or braces) is rejected. Fall back to a semantic theme default when the check fails. `y-badge` and `y-select` (per-option `color`) follow this pattern.
90
+ - **CSS color literals (`isSafeCssColor` from `src/modules/helpers.js`).** When a component paints a user-supplied color into any CSS context — an inline `style` attribute, a `<style>` block built via `replaceSync`, or a CSS variable — gate the value through `isSafeCssColor` first. It accepts `#hex` and the browser-native color functions (`rgb()`/`rgba()`, `hsl()`/`hsla()`, `hwb()`, `lab()`, `lch()`, `oklab()`, `oklch()`, `color()`); the function body may contain only the characters those forms use, so named colors, `var(...)`, `currentColor`, nested functions, and anything with semicolons, braces, or angle brackets are rejected. Fall back to a semantic theme default when the check fails. `y-badge` and `y-select` (per-option `color`) follow this pattern.
91
91
 
92
92
  - **SVG markup (`getSanitizedIcon` / `sanitizeSvg` from `src/modules/svg-sanitizer.js`).** Any time you would render an SVG that originated outside the bundled icon set — e.g. anything coming back from `getIcon(name)` where `name` could resolve to a `registerIcon` payload — run it through the shared sanitizer first. `<y-icon>` is the simplest path; if you need raw markup, call `getSanitizedIcon(name)` and inject the returned string. The sanitizer strips every element and attribute outside the SVG allowlist (no `<script>`, no `onload`, no `xlink:href`, …) and memoizes results per icon name.
93
93