@spfx-fast/sharepoint-ui 0.4.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/QUICKSTART.md +13 -128
  2. package/README.md +19 -26
  3. package/components.json +240 -5834
  4. package/dist/accordion.d.ts +11 -0
  5. package/dist/accordion.js +4 -0
  6. package/dist/alert.d.ts +3 -0
  7. package/dist/alert.js +4 -0
  8. package/dist/attachment-list.d.ts +15 -0
  9. package/dist/attachment-list.js +14 -0
  10. package/dist/avatar-group.d.ts +12 -0
  11. package/dist/avatar-group.js +7 -0
  12. package/dist/avatar.d.ts +6 -0
  13. package/dist/avatar.js +5 -0
  14. package/dist/badge.d.ts +3 -0
  15. package/dist/badge.js +4 -0
  16. package/dist/breadcrumb.d.ts +10 -0
  17. package/dist/breadcrumb.js +9 -0
  18. package/dist/button-group.d.ts +6 -0
  19. package/dist/button-group.js +4 -0
  20. package/dist/button.d.ts +3 -0
  21. package/dist/button.js +4 -0
  22. package/dist/card.d.ts +3 -0
  23. package/dist/card.js +4 -0
  24. package/dist/carousel.d.ts +11 -0
  25. package/dist/carousel.js +6 -0
  26. package/dist/checkbox.d.ts +3 -0
  27. package/dist/checkbox.js +4 -0
  28. package/dist/combobox.d.ts +9 -0
  29. package/dist/combobox.js +6 -0
  30. package/dist/command-bar.d.ts +6 -0
  31. package/dist/command-bar.js +4 -0
  32. package/dist/copy-button.d.ts +7 -0
  33. package/dist/copy-button.js +19 -0
  34. package/dist/data-grid.d.ts +25 -0
  35. package/dist/data-grid.js +39 -0
  36. package/dist/date-range-picker.d.ts +12 -0
  37. package/dist/date-range-picker.js +4 -0
  38. package/dist/dialog.d.ts +9 -0
  39. package/dist/dialog.js +21 -0
  40. package/dist/divider.d.ts +3 -0
  41. package/dist/divider.js +4 -0
  42. package/dist/drawer.d.ts +6 -0
  43. package/dist/drawer.js +5 -0
  44. package/dist/empty-state.d.ts +7 -0
  45. package/dist/empty-state.js +5 -0
  46. package/dist/field.d.ts +15 -0
  47. package/dist/field.js +11 -0
  48. package/dist/file-dropzone.d.ts +15 -0
  49. package/dist/file-dropzone.js +21 -0
  50. package/dist/filter-bar.d.ts +9 -0
  51. package/dist/filter-bar.js +9 -0
  52. package/dist/image.d.ts +5 -0
  53. package/dist/image.js +4 -0
  54. package/dist/index.d.ts +68 -78
  55. package/dist/index.js +60 -68
  56. package/dist/input.d.ts +3 -0
  57. package/dist/input.js +4 -0
  58. package/dist/label.d.ts +3 -0
  59. package/dist/label.js +4 -0
  60. package/dist/link.d.ts +3 -0
  61. package/dist/link.js +9 -0
  62. package/dist/list-view.d.ts +29 -0
  63. package/dist/list-view.js +14 -0
  64. package/dist/list.d.ts +6 -0
  65. package/dist/list.js +5 -0
  66. package/dist/lookup-picker.d.ts +12 -0
  67. package/dist/lookup-picker.js +4 -0
  68. package/dist/menu.d.ts +6 -0
  69. package/dist/menu.js +4 -0
  70. package/dist/nav.d.ts +12 -0
  71. package/dist/nav.js +4 -0
  72. package/dist/pagination.d.ts +11 -0
  73. package/dist/pagination.js +5 -0
  74. package/dist/person-picker.d.ts +13 -0
  75. package/dist/person-picker.js +4 -0
  76. package/dist/persona.d.ts +7 -0
  77. package/dist/persona.js +5 -0
  78. package/dist/popover.d.ts +6 -0
  79. package/dist/popover.js +4 -0
  80. package/dist/progress-bar.d.ts +5 -0
  81. package/dist/progress-bar.js +5 -0
  82. package/dist/radio-group.d.ts +6 -0
  83. package/dist/radio-group.js +4 -0
  84. package/dist/radio.d.ts +3 -0
  85. package/dist/radio.js +4 -0
  86. package/dist/rating.d.ts +8 -0
  87. package/dist/rating.js +5 -0
  88. package/dist/react.d.ts +1 -4715
  89. package/dist/react.js +1 -7097
  90. package/dist/select.d.ts +3 -0
  91. package/dist/select.js +4 -0
  92. package/dist/sharepoint-field.d.ts +18 -0
  93. package/dist/sharepoint-field.js +54 -0
  94. package/dist/skeleton.d.ts +6 -0
  95. package/dist/skeleton.js +9 -0
  96. package/dist/spinner.d.ts +5 -0
  97. package/dist/spinner.js +4 -0
  98. package/dist/swatch-picker.d.ts +17 -0
  99. package/dist/swatch-picker.js +11 -0
  100. package/dist/switch.d.ts +3 -0
  101. package/dist/switch.js +4 -0
  102. package/dist/table.d.ts +6 -0
  103. package/dist/table.js +4 -0
  104. package/dist/tabs.d.ts +14 -0
  105. package/dist/tabs.js +30 -0
  106. package/dist/tag-group.d.ts +6 -0
  107. package/dist/tag-group.js +4 -0
  108. package/dist/tag-picker.d.ts +12 -0
  109. package/dist/tag-picker.js +4 -0
  110. package/dist/tag.d.ts +7 -0
  111. package/dist/tag.js +5 -0
  112. package/dist/text.d.ts +5 -0
  113. package/dist/text.js +4 -0
  114. package/dist/textarea.d.ts +3 -0
  115. package/dist/textarea.js +4 -0
  116. package/dist/theme.d.ts +15 -175
  117. package/dist/theme.js +36 -239
  118. package/dist/toast.d.ts +9 -0
  119. package/dist/toast.js +12 -0
  120. package/dist/tree.d.ts +13 -0
  121. package/dist/tree.js +9 -0
  122. package/dist/view-card.d.ts +8 -0
  123. package/dist/view-card.js +4 -0
  124. package/dist/view-switcher.d.ts +13 -0
  125. package/dist/view-switcher.js +7 -0
  126. package/dist/virtual-list.d.ts +11 -0
  127. package/dist/virtual-list.js +25 -0
  128. package/measurements.json +365 -0
  129. package/package.json +14 -46
  130. package/src/theme.css +125 -0
  131. package/AGENTS.md +0 -231
  132. package/dist/appearance.d.ts +0 -6
  133. package/dist/appearance.js +0 -217
  134. package/dist/elements/accordion.d.ts +0 -9
  135. package/dist/elements/accordion.js +0 -338
  136. package/dist/elements/alert.d.ts +0 -2
  137. package/dist/elements/alert.js +0 -86
  138. package/dist/elements/avatar-group-primitives.d.ts +0 -3
  139. package/dist/elements/avatar-group-primitives.js +0 -189
  140. package/dist/elements/avatar-group.d.ts +0 -2
  141. package/dist/elements/avatar-group.js +0 -110
  142. package/dist/elements/avatar.d.ts +0 -4
  143. package/dist/elements/avatar.js +0 -251
  144. package/dist/elements/badge.d.ts +0 -8
  145. package/dist/elements/badge.js +0 -182
  146. package/dist/elements/breadcrumb.d.ts +0 -4
  147. package/dist/elements/breadcrumb.js +0 -233
  148. package/dist/elements/button-group.d.ts +0 -1
  149. package/dist/elements/button-group.js +0 -20
  150. package/dist/elements/button-variants.d.ts +0 -6
  151. package/dist/elements/button-variants.js +0 -339
  152. package/dist/elements/button.d.ts +0 -5
  153. package/dist/elements/button.js +0 -233
  154. package/dist/elements/card-primitives.d.ts +0 -3
  155. package/dist/elements/card-primitives.js +0 -83
  156. package/dist/elements/card.d.ts +0 -5
  157. package/dist/elements/card.js +0 -213
  158. package/dist/elements/carousel.d.ts +0 -92
  159. package/dist/elements/carousel.js +0 -1115
  160. package/dist/elements/color-picker.d.ts +0 -24
  161. package/dist/elements/color-picker.js +0 -1004
  162. package/dist/elements/combobox.d.ts +0 -1
  163. package/dist/elements/combobox.js +0 -1012
  164. package/dist/elements/data-grid-model.d.ts +0 -120
  165. package/dist/elements/data-grid-model.js +0 -294
  166. package/dist/elements/data-grid.d.ts +0 -30
  167. package/dist/elements/data-grid.js +0 -1576
  168. package/dist/elements/date-picker.d.ts +0 -1
  169. package/dist/elements/date-picker.js +0 -486
  170. package/dist/elements/dialog.d.ts +0 -23
  171. package/dist/elements/dialog.js +0 -409
  172. package/dist/elements/divider.d.ts +0 -2
  173. package/dist/elements/divider.js +0 -66
  174. package/dist/elements/drawer.d.ts +0 -3
  175. package/dist/elements/drawer.js +0 -308
  176. package/dist/elements/field-composition.d.ts +0 -26
  177. package/dist/elements/field-composition.js +0 -133
  178. package/dist/elements/field.d.ts +0 -1
  179. package/dist/elements/field.js +0 -67
  180. package/dist/elements/file-upload.d.ts +0 -6
  181. package/dist/elements/file-upload.js +0 -211
  182. package/dist/elements/floating-position.d.ts +0 -36
  183. package/dist/elements/floating-position.js +0 -92
  184. package/dist/elements/image.d.ts +0 -28
  185. package/dist/elements/image.js +0 -38
  186. package/dist/elements/info.d.ts +0 -9
  187. package/dist/elements/info.js +0 -102
  188. package/dist/elements/input.d.ts +0 -5
  189. package/dist/elements/input.js +0 -255
  190. package/dist/elements/label.d.ts +0 -15
  191. package/dist/elements/label.js +0 -56
  192. package/dist/elements/link.d.ts +0 -1
  193. package/dist/elements/link.js +0 -92
  194. package/dist/elements/list.d.ts +0 -19
  195. package/dist/elements/list.js +0 -297
  196. package/dist/elements/menu.d.ts +0 -33
  197. package/dist/elements/menu.js +0 -1103
  198. package/dist/elements/message-bar.d.ts +0 -10
  199. package/dist/elements/message-bar.js +0 -327
  200. package/dist/elements/nav.d.ts +0 -32
  201. package/dist/elements/nav.js +0 -794
  202. package/dist/elements/overflow.d.ts +0 -10
  203. package/dist/elements/overflow.js +0 -218
  204. package/dist/elements/persona.d.ts +0 -3
  205. package/dist/elements/persona.js +0 -125
  206. package/dist/elements/popover.d.ts +0 -77
  207. package/dist/elements/popover.js +0 -840
  208. package/dist/elements/progress-bar.d.ts +0 -4
  209. package/dist/elements/progress-bar.js +0 -82
  210. package/dist/elements/radio-group.d.ts +0 -1
  211. package/dist/elements/radio-group.js +0 -303
  212. package/dist/elements/rating-display.d.ts +0 -2
  213. package/dist/elements/rating-display.js +0 -125
  214. package/dist/elements/rating.d.ts +0 -2
  215. package/dist/elements/rating.js +0 -206
  216. package/dist/elements/rich-text-editor.d.ts +0 -32
  217. package/dist/elements/rich-text-editor.js +0 -1367
  218. package/dist/elements/search.d.ts +0 -3
  219. package/dist/elements/search.js +0 -200
  220. package/dist/elements/select.d.ts +0 -6
  221. package/dist/elements/select.js +0 -291
  222. package/dist/elements/shared.d.ts +0 -22
  223. package/dist/elements/shared.js +0 -409
  224. package/dist/elements/sharepoint-field-basic-controls.d.ts +0 -1
  225. package/dist/elements/sharepoint-field-basic-controls.js +0 -14
  226. package/dist/elements/sharepoint-fields.d.ts +0 -29
  227. package/dist/elements/sharepoint-fields.js +0 -460
  228. package/dist/elements/skeleton.d.ts +0 -6
  229. package/dist/elements/skeleton.js +0 -91
  230. package/dist/elements/slider.d.ts +0 -1
  231. package/dist/elements/slider.js +0 -248
  232. package/dist/elements/spin-button.d.ts +0 -7
  233. package/dist/elements/spin-button.js +0 -499
  234. package/dist/elements/spinner.d.ts +0 -4
  235. package/dist/elements/spinner.js +0 -124
  236. package/dist/elements/swatch-picker.d.ts +0 -5
  237. package/dist/elements/swatch-picker.js +0 -363
  238. package/dist/elements/table.d.ts +0 -21
  239. package/dist/elements/table.js +0 -261
  240. package/dist/elements/tabs.d.ts +0 -1
  241. package/dist/elements/tabs.js +0 -276
  242. package/dist/elements/tag-picker.d.ts +0 -29
  243. package/dist/elements/tag-picker.js +0 -715
  244. package/dist/elements/tags.d.ts +0 -21
  245. package/dist/elements/tags.js +0 -421
  246. package/dist/elements/teaching-popover.d.ts +0 -32
  247. package/dist/elements/teaching-popover.js +0 -412
  248. package/dist/elements/text.d.ts +0 -9
  249. package/dist/elements/text.js +0 -75
  250. package/dist/elements/textarea.d.ts +0 -1
  251. package/dist/elements/textarea.js +0 -182
  252. package/dist/elements/toast.d.ts +0 -25
  253. package/dist/elements/toast.js +0 -337
  254. package/dist/elements/toaster.d.ts +0 -6
  255. package/dist/elements/toaster.js +0 -357
  256. package/dist/elements/toggle.d.ts +0 -2
  257. package/dist/elements/toggle.js +0 -246
  258. package/dist/elements/toolbar.d.ts +0 -12
  259. package/dist/elements/toolbar.js +0 -381
  260. package/dist/elements/tooltip.d.ts +0 -76
  261. package/dist/elements/tooltip.js +0 -527
  262. package/dist/elements/tree-model.d.ts +0 -19
  263. package/dist/elements/tree-model.js +0 -34
  264. package/dist/elements/tree.d.ts +0 -5
  265. package/dist/elements/tree.js +0 -273
  266. package/dist/elements/view-card.d.ts +0 -2
  267. package/dist/elements/view-card.js +0 -78
  268. package/dist/elements/virtual-list.d.ts +0 -41
  269. package/dist/elements/virtual-list.js +0 -369
  270. package/dist/elements.d.ts +0 -73
  271. package/dist/elements.js +0 -210
  272. package/dist/sharepoint-fields.d.ts +0 -135
  273. package/dist/sharepoint-fields.js +0 -402
  274. package/dist/virtualizer-hooks.d.ts +0 -80
  275. package/dist/virtualizer-hooks.js +0 -253
  276. package/scripts/generate-token-index.mjs +0 -43
  277. package/scripts/sync-component-catalog-signatures.mjs +0 -55
  278. package/scripts/validate-component-catalog.mjs +0 -44
  279. package/skills/sharepoint-ui/SKILL.md +0 -12
  280. package/skills/sharepoint-ui/references/choosing-components.md +0 -20
  281. package/skills/sharepoint-ui/references/sharepoint-patterns.md +0 -17
  282. package/tokens.json +0 -3777
@@ -1,4 +0,0 @@
1
- export type ProgressBarColor = "brand" | "success" | "warning" | "error";
2
- export type ProgressBarShape = "rounded" | "square";
3
- export type ProgressBarThickness = "medium" | "large";
4
- export declare function defineProgressBar(): void;
@@ -1,82 +0,0 @@
1
- import { base } from "./shared.js";
2
- export function defineProgressBar() {
3
- if (customElements.get("spui-progress-bar"))
4
- return;
5
- class SpuiProgressBar extends HTMLElement {
6
- static observedAttributes = ["value", "max", "label", "aria-label", "aria-labelledby", "aria-describedby", "aria-valuetext", "color", "shape", "thickness"];
7
- generatedLabel;
8
- connectedCallback() {
9
- if (!this.shadowRoot) {
10
- const shadow = this.attachShadow({ mode: "open" });
11
- const progress = document.createElement("div");
12
- progress.className = "track";
13
- progress.setAttribute("aria-hidden", "true");
14
- progress.part.add("track");
15
- const bar = document.createElement("slot");
16
- bar.name = "bar";
17
- bar.append(Object.assign(document.createElement("span"), { className: "indicator" }));
18
- progress.append(bar);
19
- const motion = document.createElement("slot");
20
- motion.name = "indeterminateMotion";
21
- motion.setAttribute("aria-hidden", "true");
22
- progress.append(motion);
23
- const style = document.createElement("style");
24
- style.textContent = `${base}:host{display:block;min-width:0}.track{position:relative;display:block;width:100%;height:2px;overflow:hidden;border-radius:var(--spui-progress-radius,999px);background:var(--spui-progress-track,color-mix(in srgb,currentColor 10%,transparent))}.indicator{position:absolute;inset-block:0;inset-inline-start:0;width:100%;border-radius:inherit;background:var(--spui-progress-color,var(--spui-ui-accent,var(--spui-semantic-focus-border,#0f6cbd)));transform-origin:left center}:host([dir=rtl]) .indicator{transform-origin:right center}:host([data-determinate-transition]) .indicator,:host([data-determinate-transition]) slot[name=bar]::slotted([slot=bar]){transition:transform 300ms ease,width 300ms ease}:host([thickness=large]) .track{height:4px}:host([shape=square]){--spui-progress-radius:0px}:host([color=success]){--spui-progress-color:var(--spui-ui-success,#107c10)}:host([color=warning]){--spui-progress-color:var(--spui-ui-warning,#835b00)}:host([color=error]){--spui-progress-color:var(--spui-ui-danger,#b10e1c)}:host([data-indeterminate]) .indicator{width:33%;animation:spui-progress-indeterminate 3s linear infinite}:host([dir=rtl][data-indeterminate]) .indicator{animation-name:spui-progress-indeterminate-rtl}:host([data-indeterminate][data-custom-motion]) .indicator{display:none}slot[name=bar]::slotted([slot=bar]){width:var(--spui-progress-value,100%);height:100%;border-radius:inherit;background:var(--spui-progress-color,var(--spui-ui-accent,var(--spui-semantic-focus-border,#0f6cbd)))}:host([data-indeterminate]) slot[name=bar]::slotted([slot=bar]){width:33%;animation:spui-progress-indeterminate 3s linear infinite}:host([dir=rtl][data-indeterminate]) slot[name=bar]::slotted([slot=bar]){animation-name:spui-progress-indeterminate-rtl}slot[name=indeterminateMotion]::slotted(*){position:absolute;inset-block:0;inset-inline-start:0;width:33%;height:100%}:host([dir=rtl]) slot[name=indeterminateMotion]::slotted(*){inset-inline-start:auto;inset-inline-end:0}@keyframes spui-progress-indeterminate{from{transform:translateX(-100%)}to{transform:translateX(300%)}}@keyframes spui-progress-indeterminate-rtl{from{transform:translateX(100%)}to{transform:translateX(-300%)}}@media(prefers-reduced-motion:reduce){.indicator{transition:none}:host([data-indeterminate]) .indicator,:host([dir=rtl][data-indeterminate]) .indicator{width:100%;animation:spui-progress-pulse 3s linear infinite}:host([data-indeterminate]) slot[name=bar]::slotted([slot=bar]),:host([dir=rtl][data-indeterminate]) slot[name=bar]::slotted([slot=bar]){width:100%;animation:spui-progress-pulse 3s linear infinite}}@keyframes spui-progress-pulse{0%,100%{opacity:.2}50%{opacity:1}}@media(forced-colors:active){.track{forced-color-adjust:none;background:Canvas;border:1px solid CanvasText}.indicator,slot[name=bar]::slotted([slot=bar]){background:Highlight}}`;
25
- style.textContent += `:host(:not([color])),:host([color=brand]){--spui-progress-color:color-mix(in srgb,var(--spui-ui-accent,#0f6cbd) 45%,currentColor 55%)}:host([color=success]){--spui-progress-color:color-mix(in srgb,var(--spui-ui-success,#107c10) 45%,currentColor 55%)}:host([color=warning]){--spui-progress-color:color-mix(in srgb,var(--spui-ui-warning,#835b00) 45%,currentColor 55%)}:host([color=error]){--spui-progress-color:color-mix(in srgb,var(--spui-ui-danger,#b10e1c) 45%,currentColor 55%)}`;
26
- shadow.append(style, progress);
27
- progress.querySelectorAll("slot").forEach(slot => slot.addEventListener("slotchange", () => this.sync()));
28
- }
29
- this.sync();
30
- }
31
- attributeChangedCallback() { if (this.isConnected)
32
- this.sync(); }
33
- sync() {
34
- const progress = this.shadowRoot?.querySelector(".track");
35
- if (!progress)
36
- return;
37
- this.toggleAttribute("data-custom-motion", (this.shadowRoot?.querySelector('slot[name="indeterminateMotion"]')?.assignedElements().length ?? 0) > 0);
38
- this.setAttribute("role", "progressbar");
39
- const max = Number(this.getAttribute("max"));
40
- const normalizedMax = Number.isFinite(max) && max > 0 ? max : 1;
41
- const raw = this.getAttribute("value");
42
- const value = raw === null ? null : Number(raw);
43
- this.setAttribute("aria-valuemin", "0");
44
- this.setAttribute("aria-valuemax", String(normalizedMax));
45
- if (value === null || !Number.isFinite(value)) {
46
- this.setAttribute("data-indeterminate", "");
47
- this.removeAttribute("data-determinate-transition");
48
- this.removeAttribute("aria-valuenow");
49
- const indicator = this.shadowRoot?.querySelector(".indicator");
50
- if (indicator)
51
- indicator.style.removeProperty("transform");
52
- const slottedBar = this.shadowRoot?.querySelector("slot[name=bar]")?.assignedElements()[0];
53
- slottedBar?.style.removeProperty("--spui-progress-value");
54
- }
55
- else {
56
- this.removeAttribute("data-indeterminate");
57
- const bounded = Math.min(normalizedMax, Math.max(0, value));
58
- this.toggleAttribute("data-determinate-transition", bounded / normalizedMax > 0.01);
59
- this.setAttribute("aria-valuenow", String(bounded));
60
- const indicator = this.shadowRoot?.querySelector(".indicator");
61
- if (indicator)
62
- indicator.style.transform = `scaleX(${bounded / normalizedMax})`;
63
- const slottedBar = this.shadowRoot?.querySelector("slot[name=bar]")?.assignedElements()[0];
64
- slottedBar?.style.setProperty("--spui-progress-value", `${bounded / normalizedMax * 100}%`);
65
- }
66
- if (this.hasAttribute("aria-labelledby")) {
67
- if (this.generatedLabel !== undefined && this.getAttribute("aria-label") === this.generatedLabel)
68
- this.removeAttribute("aria-label");
69
- this.generatedLabel = undefined;
70
- }
71
- else if (this.getAttribute("aria-label") === null || this.getAttribute("aria-label") === this.generatedLabel) {
72
- const label = this.getAttribute("label") ?? "Loading";
73
- this.generatedLabel = label;
74
- if (this.getAttribute("aria-label") !== label)
75
- this.setAttribute("aria-label", label);
76
- }
77
- else
78
- this.generatedLabel = undefined;
79
- }
80
- }
81
- customElements.define("spui-progress-bar", SpuiProgressBar);
82
- }
@@ -1 +0,0 @@
1
- export declare function defineRadioGroup(): void;
@@ -1,303 +0,0 @@
1
- import { base, stopHostAccessibleNameSync, syncHostAccessibleName } from "./shared.js";
2
- function radioOptionLabel(option, fallback) {
3
- const text = [...option.childNodes].filter(node => !(node instanceof Element && ["input", "indicator", "label"].includes(node.getAttribute("slot") ?? ""))).map(node => node.textContent ?? "").join("").trim();
4
- return option.getAttribute("label") ?? (text || fallback);
5
- }
6
- const radioRootInputAttributes = new WeakMap();
7
- const radioManagedInputAttributes = new Set(["checked", "disabled", "hidden", "label", "label-position", "name", "required", "slot", "type", "value"]);
8
- function isForwardableRadioInputAttribute(name) {
9
- return !radioManagedInputAttributes.has(name) && !name.startsWith("on");
10
- }
11
- function syncRadioRootProps(option, input, label) {
12
- label.className = option.getAttribute("class") ?? option.getAttribute("classname") ?? "";
13
- label.style.cssText = option.getAttribute("style") ?? "";
14
- for (const name of radioRootInputAttributes.get(input) ?? [])
15
- input.removeAttribute(name);
16
- const applied = new Set();
17
- for (const attribute of [...option.attributes]) {
18
- if (attribute.name !== "class" && attribute.name !== "style" && isForwardableRadioInputAttribute(attribute.name)) {
19
- input.setAttribute(attribute.name, attribute.value);
20
- applied.add(attribute.name);
21
- }
22
- }
23
- radioRootInputAttributes.set(input, applied);
24
- }
25
- const radioInputSlotAttributes = new WeakMap();
26
- function syncRadioInputSlot(source, input) {
27
- for (const name of radioInputSlotAttributes.get(input) ?? [])
28
- input.removeAttribute(name);
29
- const applied = new Set();
30
- if (!source) {
31
- radioInputSlotAttributes.set(input, applied);
32
- return;
33
- }
34
- for (const attribute of [...source.attributes]) {
35
- if (isForwardableRadioInputAttribute(attribute.name)) {
36
- input.setAttribute(attribute.name, attribute.value);
37
- applied.add(attribute.name);
38
- }
39
- }
40
- radioInputSlotAttributes.set(input, applied);
41
- }
42
- function createRadioIndicator(source) {
43
- const indicator = source?.cloneNode(true) ?? document.createElement("span");
44
- indicator.removeAttribute("slot");
45
- indicator.removeAttribute("hidden");
46
- indicator.setAttribute("aria-hidden", "true");
47
- indicator.classList.add("radio-indicator");
48
- indicator.part.add("indicator");
49
- return indicator;
50
- }
51
- function createRadioLabel(source, text) {
52
- const label = document.createElement("span");
53
- label.dataset.radioLabel = "";
54
- if (source) {
55
- const content = source.cloneNode(true);
56
- content.removeAttribute("slot");
57
- content.removeAttribute("hidden");
58
- label.append(content);
59
- }
60
- else
61
- label.textContent = text;
62
- return label;
63
- }
64
- export function defineRadioGroup() {
65
- if (customElements.get("spui-radio-group"))
66
- return;
67
- class SpuiRadioGroup extends HTMLElement {
68
- static formAssociated = true;
69
- static observedAttributes = ["label", "value", "default-value", "disabled", "required", "name", "orientation", "layout", "aria-label", "aria-labelledby", "aria-description", "aria-describedby", "aria-invalid"];
70
- internals;
71
- observer;
72
- currentValue;
73
- formDisabledValue = false;
74
- constructor() {
75
- super();
76
- try {
77
- this.internals = this.attachInternals();
78
- }
79
- catch { /* Keep the controls usable where custom form association is unavailable. */ }
80
- }
81
- get form() { return this.internals?.form ?? null; }
82
- get validity() { return this.internals?.validity; }
83
- get validationMessage() { return this.internals?.validationMessage ?? ""; }
84
- get willValidate() { return this.internals?.willValidate ?? false; }
85
- checkValidity() { return this.internals?.checkValidity() ?? true; }
86
- reportValidity() { return this.internals?.reportValidity() ?? true; }
87
- connectedCallback() {
88
- this.render();
89
- this.observer = new MutationObserver(records => {
90
- let optionsChanged = false;
91
- const textChanged = new Set();
92
- for (const record of records) {
93
- if (record.type === "attributes") {
94
- const option = record.target instanceof Element ? record.target.closest("spui-radio-option") : null;
95
- if (option?.parentElement === this && record.target === option && ["value", "disabled", "checked"].includes(record.attributeName ?? ""))
96
- optionsChanged = true;
97
- else if (option?.parentElement === this)
98
- textChanged.add(option);
99
- else if (record.target === this)
100
- optionsChanged = true;
101
- continue;
102
- }
103
- const target = record.target instanceof Element ? record.target : record.target.parentElement;
104
- const option = target?.closest("spui-radio-option");
105
- if (option?.parentElement === this)
106
- textChanged.add(option);
107
- else if (record.target === this)
108
- optionsChanged = true;
109
- }
110
- if (optionsChanged)
111
- this.syncOptions();
112
- else
113
- for (const option of textChanged)
114
- this.syncOptionLabel(option);
115
- });
116
- this.observer.observe(this, { childList: true, subtree: true, characterData: true, attributes: true });
117
- }
118
- disconnectedCallback() { this.observer?.disconnect(); stopHostAccessibleNameSync(this); }
119
- attributeChangedCallback(name, _oldValue, value) {
120
- if (!this.isConnected)
121
- return;
122
- const fieldset = this.shadowRoot?.querySelector("fieldset");
123
- if (!fieldset)
124
- return;
125
- if (name === "label") {
126
- const legend = this.shadowRoot?.querySelector("legend");
127
- if (legend)
128
- legend.textContent = value ?? "";
129
- }
130
- if (name === "disabled")
131
- fieldset.disabled = this.formDisabledValue || this.hasAttribute("disabled");
132
- if (name === "orientation" || name === "layout")
133
- fieldset.dataset.layout = this.getLayout();
134
- if (name === "aria-label" || name === "aria-labelledby" || name === "aria-description" || name === "aria-describedby" || name === "aria-invalid") {
135
- const value = this.getAttribute(name);
136
- if (value === null)
137
- fieldset.removeAttribute(name);
138
- else
139
- fieldset.setAttribute(name, value);
140
- syncHostAccessibleName(this, fieldset);
141
- }
142
- if (name === "value")
143
- this.currentValue = value ?? "";
144
- for (const radio of fieldset.querySelectorAll('input[type="radio"]')) {
145
- if (name === "name")
146
- radio.name = value ?? (this.id || "spui-radio-group");
147
- if (name === "required")
148
- radio.required = this.hasAttribute("required");
149
- if (name === "value")
150
- radio.checked = radio.value === (this.currentValue ?? "");
151
- if (name === "disabled")
152
- radio.disabled = this.hasAttribute("disabled") || radio.dataset.optionDisabled === "true";
153
- }
154
- this.syncFormValue();
155
- }
156
- get value() { return this.currentValue ?? this.getAttribute("value") ?? this.shadowRoot?.querySelector('input[type="radio"]:checked')?.value ?? ""; }
157
- set value(value) {
158
- this.currentValue = value;
159
- const fieldset = this.shadowRoot?.querySelector("fieldset");
160
- if (fieldset) {
161
- for (const radio of fieldset.querySelectorAll('input[type="radio"]'))
162
- radio.checked = radio.value === value;
163
- this.syncFormValue();
164
- }
165
- }
166
- get defaultValue() { return this.getAttribute("default-value") ?? this.querySelector(':scope > spui-radio-option[checked]')?.getAttribute("value") ?? ""; }
167
- set defaultValue(value) { this.setAttribute("default-value", value); }
168
- formDisabledCallback(disabled) {
169
- this.formDisabledValue = disabled;
170
- for (const radio of this.shadowRoot?.querySelectorAll('input[type="radio"]') ?? [])
171
- radio.disabled = disabled || this.hasAttribute("disabled") || radio.dataset.optionDisabled === "true";
172
- this.syncFormValue();
173
- }
174
- formResetCallback() {
175
- const options = [...this.querySelectorAll(":scope > spui-radio-option")];
176
- const initial = options.find(option => option.hasAttribute("checked"))?.getAttribute("value") ?? "";
177
- this.value = this.getAttribute("value") ?? this.getAttribute("default-value") ?? initial;
178
- }
179
- formStateRestoreCallback(state) { if (typeof state === "string")
180
- this.value = state; }
181
- syncFormValue() {
182
- const checked = this.shadowRoot?.querySelector('input[type="radio"]:checked');
183
- const disabled = this.formDisabledValue || this.hasAttribute("disabled");
184
- const value = checked?.value ?? "";
185
- for (const label of this.shadowRoot?.querySelectorAll("fieldset > label") ?? [])
186
- label.dataset.checked = String(Boolean(label.querySelector("input")?.checked));
187
- this.internals?.setFormValue(checked && !disabled ? value : null);
188
- try {
189
- const anchor = checked ?? this.shadowRoot?.querySelector('input[type="radio"]');
190
- const missing = !disabled && this.hasAttribute("required") && !checked;
191
- this.internals?.setValidity(missing ? { valueMissing: true } : {}, missing ? anchor?.validationMessage ?? "" : "", missing ? anchor ?? undefined : undefined);
192
- }
193
- catch { /* Some engines do not accept shadow descendants as validity anchors. */ }
194
- }
195
- syncOptionLabel(option) {
196
- const index = [...this.querySelectorAll(":scope > spui-radio-option")].indexOf(option);
197
- const label = this.shadowRoot?.querySelectorAll("fieldset > label")[index];
198
- const input = label?.querySelector("input");
199
- const text = label?.querySelector(":scope > [data-radio-label]");
200
- if (input) {
201
- syncRadioRootProps(option, input, label);
202
- syncRadioInputSlot(option.querySelector(":scope > input[slot=input]"), input);
203
- const sourceIndicator = option.querySelector(":scope > [slot=indicator]");
204
- const currentIndicator = label?.querySelector(".radio-indicator");
205
- if (currentIndicator && sourceIndicator)
206
- currentIndicator.replaceWith(createRadioIndicator(sourceIndicator));
207
- else if (currentIndicator && !sourceIndicator)
208
- currentIndicator.remove();
209
- else if (label && sourceIndicator)
210
- label.insertBefore(createRadioIndicator(sourceIndicator), text ?? null);
211
- label?.toggleAttribute("data-custom-indicator", Boolean(sourceIndicator));
212
- input.dataset.customIndicator = String(Boolean(sourceIndicator));
213
- if (label)
214
- label.dataset.labelPosition = option.getAttribute("label-position") ?? (this.getLayout() === "horizontal-stacked" ? "below" : "after");
215
- }
216
- if (label && input) {
217
- const nextText = createRadioLabel(option.querySelector(":scope > [slot=label]"), radioOptionLabel(option, input.value));
218
- if (text)
219
- text.replaceWith(nextText);
220
- else
221
- label.append(nextText);
222
- }
223
- }
224
- syncOptions() {
225
- const fieldset = this.shadowRoot?.querySelector("fieldset");
226
- if (!fieldset)
227
- return;
228
- const current = this.currentValue ?? this.getAttribute("value") ?? this.getAttribute("default-value") ?? fieldset.querySelector('input[type="radio"]:checked')?.value ?? "";
229
- const options = [...this.querySelectorAll(":scope > spui-radio-option")];
230
- const radios = options.map((option, index) => this.createRadio(option, index));
231
- fieldset.replaceChildren(fieldset.querySelector("legend"), ...radios);
232
- const checked = fieldset.querySelector(`input[type="radio"][value="${CSS.escape(current)}"]`);
233
- if (checked)
234
- checked.checked = true;
235
- this.syncFormValue();
236
- }
237
- createRadio(option, index) {
238
- const label = document.createElement("label");
239
- label.part.add("option");
240
- label.dataset.labelPosition = option.getAttribute("label-position") ?? (this.getLayout() === "horizontal-stacked" ? "below" : "after");
241
- const inputSource = option.querySelector(":scope > input[slot=input]");
242
- const input = (inputSource?.cloneNode(false) ?? document.createElement("input"));
243
- input.removeAttribute("slot");
244
- input.removeAttribute("hidden");
245
- input.type = "radio";
246
- input.name = this.getAttribute("name") ?? (this.id || "spui-radio-group");
247
- input.value = option.getAttribute("value") ?? String(index);
248
- input.disabled = this.formDisabledValue || this.hasAttribute("disabled") || option.hasAttribute("disabled");
249
- input.required = this.hasAttribute("required");
250
- input.dataset.optionDisabled = String(option.hasAttribute("disabled"));
251
- input.part.add("control");
252
- syncRadioRootProps(option, input, label);
253
- syncRadioInputSlot(inputSource, input);
254
- const text = createRadioLabel(option.querySelector(":scope > [slot=label]"), radioOptionLabel(option, input.value));
255
- const indicatorSource = option.querySelector(":scope > [slot=indicator]");
256
- label.toggleAttribute("data-custom-indicator", Boolean(indicatorSource));
257
- input.dataset.customIndicator = String(Boolean(indicatorSource));
258
- label.append(input);
259
- if (indicatorSource)
260
- label.append(createRadioIndicator(indicatorSource));
261
- label.append(text);
262
- input.addEventListener("change", event => {
263
- if (!input.checked)
264
- return;
265
- this.currentValue = input.value;
266
- this.syncFormValue();
267
- option.dispatchEvent(new CustomEvent("spui-radio-change", { detail: { value: input.value, sourceEvent: event }, bubbles: true, composed: true }));
268
- this.dispatchEvent(new CustomEvent("spui-change", { detail: { value: input.value, sourceEvent: event }, bubbles: true, composed: true }));
269
- });
270
- return label;
271
- }
272
- render() {
273
- const shadow = this.shadowRoot ?? this.attachShadow({ mode: "open" });
274
- const fieldset = document.createElement("fieldset");
275
- fieldset.disabled = this.formDisabledValue || this.hasAttribute("disabled");
276
- fieldset.dataset.layout = this.getLayout();
277
- for (const name of ["aria-label", "aria-labelledby", "aria-description", "aria-describedby", "aria-invalid"]) {
278
- const value = this.getAttribute(name);
279
- if (value !== null)
280
- fieldset.setAttribute(name, value);
281
- }
282
- const legend = document.createElement("legend");
283
- legend.textContent = this.getAttribute("label") ?? "";
284
- legend.part.add("label");
285
- const options = [...this.querySelectorAll(":scope > spui-radio-option")];
286
- const radios = options.map((option, index) => this.createRadio(option, index));
287
- const initial = this.currentValue ?? this.getAttribute("value") ?? this.getAttribute("default-value") ?? options.find(option => option.hasAttribute("checked"))?.getAttribute("value") ?? "";
288
- const selected = radios.find(label => label.querySelector("input")?.value === initial)?.querySelector("input");
289
- if (selected)
290
- selected.checked = true;
291
- const style = document.createElement("style");
292
- style.textContent = `${base}:host{display:block}fieldset{display:flex;flex-direction:column;gap:var(--spui-control-gap,8px);min-width:0;margin:0;padding:0;border:0}fieldset[data-layout="horizontal"],fieldset[data-layout="horizontal-stacked"]{flex-direction:row;flex-wrap:wrap;column-gap:var(--spui-control-gap,16px)}label[data-label-position="below"]{flex-direction:column;align-items:flex-start;justify-content:center}legend{margin-bottom:var(--spui-control-gap,8px);padding:0;color:var(--spui-ui-muted,var(--spui-semantic-body-text,inherit));font-size:14px;font-weight:600}label{display:inline-flex;align-items:center;gap:8px;min-height:var(--spui-control-height,32px);color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));cursor:pointer}input{width:18px;height:18px;margin:0;accent-color:var(--spui-ui-accent,var(--spui-semantic-input-background-checked,var(--colorBrandBackground,#0f6cbd)));cursor:pointer}input:focus-visible{outline:2px solid var(--spui-focus-ring,#005a9e);outline-offset:2px}input:disabled{cursor:not-allowed}label:has(input:disabled){opacity:.55;cursor:not-allowed}@media(forced-colors:active){input{accent-color:Highlight}input:focus-visible{outline-color:Highlight}}`;
293
- style.textContent += `.radio-indicator[hidden]{display:none!important}.radio-indicator{box-sizing:border-box;display:inline-grid;place-items:center;flex:none;width:18px;height:18px;border:1px solid var(--spui-ui-stroke,var(--spui-semantic-body-divider,#8a8886));border-radius:50%;color:var(--spui-ui-accent,var(--spui-semantic-accent,#0f6cbd));background:var(--spui-ui-surface,var(--spui-semantic-body-background,#fff))}.radio-indicator::after{content:"";width:10px;height:10px;border-radius:50%;background:currentColor;transform:scale(0);transition:transform var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,ease)}label[data-checked=true] .radio-indicator{border-color:currentColor}label[data-checked=true] .radio-indicator::after{transform:scale(1)}input[data-custom-indicator=true]{position:absolute;inset-inline-start:0;inset-block-start:calc(50% - 9px);z-index:1;opacity:0}input[data-custom-indicator=true]:focus-visible{outline:0}input[data-custom-indicator=true]:focus-visible+.radio-indicator{outline:2px solid var(--spui-focus-ring,#005a9e);outline-offset:2px}@media(prefers-reduced-motion:reduce){.radio-indicator::after{transition:none}}@media(forced-colors:active){.radio-indicator{border-color:ButtonText;background:Canvas;color:Highlight}.radio-indicator::after{background:Highlight}}`;
294
- fieldset.append(legend, ...radios);
295
- fieldset.addEventListener("change", () => this.syncFormValue());
296
- shadow.replaceChildren(style, fieldset);
297
- syncHostAccessibleName(this, fieldset);
298
- this.syncFormValue();
299
- }
300
- getLayout() { return this.getAttribute("layout") ?? this.getAttribute("orientation") ?? "vertical"; }
301
- }
302
- customElements.define("spui-radio-group", SpuiRadioGroup);
303
- }
@@ -1,2 +0,0 @@
1
- export declare function defineRatingItem(): void;
2
- export declare function defineRatingDisplay(): void;
@@ -1,125 +0,0 @@
1
- import { base } from "./shared.js";
2
- function ratingValue(element) {
3
- const parent = element.closest("spui-rating-display");
4
- const maxRaw = Number(parent?.getAttribute("max") ?? element.getAttribute("max") ?? 5);
5
- const max = Number.isInteger(maxRaw) && maxRaw > 1 ? Math.min(20, maxRaw) : 5;
6
- const valueRaw = Number(parent?.getAttribute("value") ?? element.getAttribute("rating") ?? 0);
7
- return { value: Number.isFinite(valueRaw) ? Math.max(0, Math.min(max, valueRaw)) : 0, max };
8
- }
9
- export function defineRatingItem() {
10
- if (customElements.get("spui-rating-item"))
11
- return;
12
- class SpuiRatingItem extends HTMLElement {
13
- static observedAttributes = ["value", "rating", "max", "size", "color"];
14
- connectedCallback() { this.render(); }
15
- attributeChangedCallback() { if (this.isConnected)
16
- this.render(); }
17
- render() {
18
- const { value: rating } = ratingValue(this);
19
- const raw = Number(this.getAttribute("value") ?? 1);
20
- const itemValue = Number.isInteger(raw) && raw > 0 ? raw : 1;
21
- const amount = Math.max(0, Math.min(1, rating - itemValue + 1));
22
- this.setAttribute("aria-hidden", "true");
23
- const shadow = this.shadowRoot ?? this.attachShadow({ mode: "open" });
24
- const style = document.createElement("style");
25
- style.textContent = `${base}:host{position:relative;display:inline-block;flex:none;width:var(--spui-rating-size,24px);height:var(--spui-rating-size,24px);font-size:var(--spui-rating-size,24px);line-height:1;color:var(--spui-rating-empty,color-mix(in srgb,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 65%,var(--spui-ui-surface,var(--spui-semantic-body-background,#ffffff)) 35%));user-select:none}.outline,.filled{position:absolute;inset:0;display:block;overflow:hidden;white-space:nowrap}.outline slot::slotted(*),.filled slot::slotted(*){font:inherit}.outline slot::slotted(*){color:var(--spui-rating-empty,color-mix(in srgb,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 65%,var(--spui-ui-surface,var(--spui-semantic-body-background,#ffffff)) 35%))}.filled{inset-inline-start:0;width:${amount * 100}%;color:var(--spui-rating-color,var(--spui-ui-accent,#0078d4))}.filled slot::slotted(*){color:var(--spui-rating-color,var(--spui-ui-accent,#0078d4))}:host(:not([color])),:host([color=neutral]){--spui-rating-color:var(--spui-ui-text,var(--spui-semantic-body-text,currentColor))}:host([color=brand]){--spui-rating-color:color-mix(in srgb,var(--spui-ui-accent,#0078d4) 65%,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 35%)}:host([color=marigold]){--spui-rating-color:color-mix(in srgb,var(--spui-rating-marigold,#c58b00) 65%,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 35%)}:host([size=small]){--spui-rating-size:18px}:host([size=medium]){--spui-rating-size:24px}:host([size=large]){--spui-rating-size:30px}:host([size=extra-large]){--spui-rating-size:36px}@media(forced-colors:active){:host{color:CanvasText}.filled{color:Highlight}}`;
26
- const outline = document.createElement("span");
27
- outline.className = "outline";
28
- outline.part.add("unselected-icon");
29
- const outlineSlot = document.createElement("slot");
30
- outlineSlot.name = "unselected-icon";
31
- outlineSlot.textContent = "☆";
32
- outline.append(outlineSlot);
33
- const filled = document.createElement("span");
34
- filled.className = "filled";
35
- filled.part.add("selected-icon");
36
- const filledSlot = document.createElement("slot");
37
- filledSlot.name = "selected-icon";
38
- filledSlot.textContent = "★";
39
- filled.append(filledSlot);
40
- shadow.replaceChildren(style, outline, filled);
41
- }
42
- }
43
- customElements.define("spui-rating-item", SpuiRatingItem);
44
- }
45
- export function defineRatingDisplay() {
46
- defineRatingItem();
47
- if (customElements.get("spui-rating-display"))
48
- return;
49
- class SpuiRatingDisplay extends HTMLElement {
50
- static observedAttributes = ["value", "max", "count", "compact", "size", "color", "aria-label", "lang"];
51
- connectedCallback() { this.render(); }
52
- attributeChangedCallback() { if (this.isConnected)
53
- this.render(); }
54
- render() {
55
- const maxRaw = Number(this.getAttribute("max") ?? 5);
56
- const max = Number.isInteger(maxRaw) && maxRaw > 1 ? Math.min(20, maxRaw) : 5;
57
- const hasValue = this.hasAttribute("value");
58
- const valueRaw = Number(this.getAttribute("value") ?? 0);
59
- const value = Number.isFinite(valueRaw) ? Math.max(0, Math.min(max, valueRaw)) : 0;
60
- const countRaw = this.getAttribute("count");
61
- const explicitLabel = this.getAttribute("aria-label");
62
- const shadow = this.shadowRoot ?? this.attachShadow({ mode: "open" });
63
- const style = document.createElement("style");
64
- style.textContent = `${base}:host{display:inline-flex;align-items:center;gap:6px;min-width:0;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font-family:var(--spui-font-family,inherit)}.root{display:inline-flex;align-items:center;gap:6px}.items{display:inline-flex;align-items:center;gap:2px}.value-text,.count-text{color:var(--spui-ui-muted,var(--spui-semantic-body-subtext,#616161));font-size:var(--spui-rating-label-size,14px);font-variant-numeric:tabular-nums}.count-text:before{content:"("}.count-text:after{content:")"}:host([compact]) .items{gap:0}@media(forced-colors:active){:host{color:CanvasText}}`;
65
- const root = document.createElement("span");
66
- root.className = "root";
67
- root.setAttribute("role", "img");
68
- root.setAttribute("aria-label", explicitLabel || `${value} of ${max}${countRaw === null ? "" : `, ${Number(countRaw).toLocaleString(this.lang || undefined)} ratings`}`);
69
- const items = document.createElement("span");
70
- items.className = "items";
71
- items.part.add("items");
72
- const slot = document.createElement("slot");
73
- const hasItems = [...this.children].some(child => child.localName === "spui-rating-item");
74
- if (!hasItems) {
75
- const itemCount = this.hasAttribute("compact") ? 1 : max;
76
- for (let index = 1; index <= itemCount; index++) {
77
- const item = document.createElement("spui-rating-item");
78
- item.setAttribute("value", String(index));
79
- item.setAttribute("rating", String(value));
80
- item.setAttribute("max", String(max));
81
- if (this.hasAttribute("size"))
82
- item.setAttribute("size", this.getAttribute("size"));
83
- if (this.hasAttribute("color"))
84
- item.setAttribute("color", this.getAttribute("color"));
85
- items.append(item);
86
- }
87
- }
88
- else {
89
- slot.addEventListener("slotchange", () => this.syncItems(slot, value, max));
90
- items.append(slot);
91
- }
92
- const valueText = document.createElement("span");
93
- valueText.className = "value-text";
94
- valueText.part.add("value-text");
95
- const valueSlot = document.createElement("slot");
96
- valueSlot.name = "value-text";
97
- valueSlot.textContent = String(value);
98
- valueText.append(valueSlot);
99
- const countText = document.createElement("span");
100
- countText.className = "count-text";
101
- countText.part.add("count-text");
102
- const countSlot = document.createElement("slot");
103
- countSlot.name = "count-text";
104
- countSlot.textContent = countRaw === null ? "" : Number(countRaw).toLocaleString(this.lang || undefined);
105
- countText.append(countSlot);
106
- if (!hasValue)
107
- valueText.hidden = true;
108
- if (countRaw === null)
109
- countText.hidden = true;
110
- root.append(items, valueText, countText);
111
- shadow.replaceChildren(style, root);
112
- if (hasItems)
113
- this.syncItems(slot, value, max);
114
- }
115
- syncItems(slot, value, max) {
116
- for (const item of slot.assignedElements().filter((node) => node.localName === "spui-rating-item")) {
117
- item.setAttribute("rating", String(value));
118
- item.setAttribute("max", String(max));
119
- for (const name of ["size", "color"])
120
- this.hasAttribute(name) ? item.setAttribute(name, this.getAttribute(name)) : item.removeAttribute(name);
121
- }
122
- }
123
- }
124
- customElements.define("spui-rating-display", SpuiRatingDisplay);
125
- }
@@ -1,2 +0,0 @@
1
- /** Selectable, form-associated star rating with optional half steps. */
2
- export declare function defineRating(): void;