@spfx-fast/sharepoint-ui 0.4.2 → 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 (276) hide show
  1. package/QUICKSTART.md +18 -0
  2. package/README.md +19 -24
  3. package/components.json +240 -5694
  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 -76
  55. package/dist/index.js +60 -66
  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 -4583
  89. package/dist/react.js +1 -6837
  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 -167
  117. package/dist/theme.js +36 -162
  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 +19 -42
  130. package/src/theme.css +125 -0
  131. package/AGENTS.md +0 -211
  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 -62
  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 -1112
  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 -117
  165. package/dist/elements/data-grid-model.js +0 -294
  166. package/dist/elements/data-grid.d.ts +0 -29
  167. package/dist/elements/data-grid.js +0 -1567
  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 -26
  183. package/dist/elements/floating-position.js +0 -39
  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 -299
  200. package/dist/elements/nav.d.ts +0 -32
  201. package/dist/elements/nav.js +0 -791
  202. package/dist/elements/overflow.d.ts +0 -9
  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 -18
  217. package/dist/elements/rich-text-editor.js +0 -508
  218. package/dist/elements/search.d.ts +0 -3
  219. package/dist/elements/search.js +0 -207
  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 -19
  223. package/dist/elements/shared.js +0 -396
  224. package/dist/elements/skeleton.d.ts +0 -6
  225. package/dist/elements/skeleton.js +0 -91
  226. package/dist/elements/slider.d.ts +0 -1
  227. package/dist/elements/slider.js +0 -248
  228. package/dist/elements/spin-button.d.ts +0 -7
  229. package/dist/elements/spin-button.js +0 -499
  230. package/dist/elements/spinner.d.ts +0 -4
  231. package/dist/elements/spinner.js +0 -124
  232. package/dist/elements/swatch-picker.d.ts +0 -5
  233. package/dist/elements/swatch-picker.js +0 -363
  234. package/dist/elements/table.d.ts +0 -21
  235. package/dist/elements/table.js +0 -261
  236. package/dist/elements/tabs.d.ts +0 -1
  237. package/dist/elements/tabs.js +0 -276
  238. package/dist/elements/tag-picker.d.ts +0 -29
  239. package/dist/elements/tag-picker.js +0 -697
  240. package/dist/elements/tags.d.ts +0 -21
  241. package/dist/elements/tags.js +0 -421
  242. package/dist/elements/teaching-popover.d.ts +0 -32
  243. package/dist/elements/teaching-popover.js +0 -412
  244. package/dist/elements/text.d.ts +0 -9
  245. package/dist/elements/text.js +0 -75
  246. package/dist/elements/textarea.d.ts +0 -1
  247. package/dist/elements/textarea.js +0 -182
  248. package/dist/elements/toast.d.ts +0 -25
  249. package/dist/elements/toast.js +0 -337
  250. package/dist/elements/toaster.d.ts +0 -6
  251. package/dist/elements/toaster.js +0 -356
  252. package/dist/elements/toggle.d.ts +0 -2
  253. package/dist/elements/toggle.js +0 -246
  254. package/dist/elements/toolbar.d.ts +0 -12
  255. package/dist/elements/toolbar.js +0 -381
  256. package/dist/elements/tooltip.d.ts +0 -76
  257. package/dist/elements/tooltip.js +0 -510
  258. package/dist/elements/tree-model.d.ts +0 -19
  259. package/dist/elements/tree-model.js +0 -34
  260. package/dist/elements/tree.d.ts +0 -5
  261. package/dist/elements/tree.js +0 -273
  262. package/dist/elements/view-card.d.ts +0 -2
  263. package/dist/elements/view-card.js +0 -78
  264. package/dist/elements/virtual-list.d.ts +0 -41
  265. package/dist/elements/virtual-list.js +0 -369
  266. package/dist/elements.d.ts +0 -72
  267. package/dist/elements.js +0 -207
  268. package/dist/virtualizer-hooks.d.ts +0 -80
  269. package/dist/virtualizer-hooks.js +0 -253
  270. package/scripts/generate-token-index.mjs +0 -43
  271. package/scripts/sync-component-catalog-signatures.mjs +0 -55
  272. package/scripts/validate-component-catalog.mjs +0 -44
  273. package/skills/sharepoint-ui/SKILL.md +0 -12
  274. package/skills/sharepoint-ui/references/choosing-components.md +0 -20
  275. package/skills/sharepoint-ui/references/sharepoint-patterns.md +0 -17
  276. package/tokens.json +0 -3777
@@ -1,356 +0,0 @@
1
- import { defineToast } from "./toast.js";
2
- export function defineToaster() {
3
- if (customElements.get("spui-toaster"))
4
- return;
5
- defineToast();
6
- class SpuiToaster extends HTMLElement {
7
- static observedAttributes = ["position", "aria-label", "limit"];
8
- announce;
9
- lastFocused = null;
10
- previousToastCount = 0;
11
- restorePending = false;
12
- toastSlot;
13
- politeRegion;
14
- assertiveRegion;
15
- announcementQueue = [];
16
- activeAnnouncement;
17
- announcementTimer;
18
- announceEnabled = true;
19
- queuedToasts = new Set();
20
- activeToasts = new Set();
21
- toastById = new Map();
22
- connectedCallback() {
23
- if (!this.shadowRoot)
24
- this.render();
25
- this.setAttribute("role", "region");
26
- if (!this.hasAttribute("position"))
27
- this.setAttribute("position", "top-end");
28
- if (!this.hasAttribute("aria-label"))
29
- this.setAttribute("aria-label", "Notifications");
30
- this.toastSlot.addEventListener("slotchange", this.onSlotChange);
31
- this.addEventListener("spui-dismiss", this.onDismiss);
32
- this.addEventListener("spui-toast-announce", this.onAnnounce);
33
- this.addEventListener("keydown", this.onKeyDown);
34
- this.addEventListener("focusin", this.onFocusIn);
35
- this.addEventListener("focusout", this.onFocusOut);
36
- }
37
- disconnectedCallback() {
38
- this.removeEventListener("spui-dismiss", this.onDismiss);
39
- this.removeEventListener("spui-toast-announce", this.onAnnounce);
40
- this.removeEventListener("keydown", this.onKeyDown);
41
- this.removeEventListener("focusin", this.onFocusIn);
42
- this.removeEventListener("focusout", this.onFocusOut);
43
- this.toastSlot.removeEventListener("slotchange", this.onSlotChange);
44
- if (this.announcementTimer !== undefined)
45
- this.ownerDocument.defaultView?.clearTimeout(this.announcementTimer);
46
- this.announcementTimer = undefined;
47
- this.announcementQueue = [];
48
- this.activeAnnouncement = undefined;
49
- }
50
- attributeChangedCallback(name) {
51
- if (name === "position" && !["top-start", "top-end", "bottom-start", "bottom-end"].includes(this.getAttribute(name) ?? ""))
52
- this.setAttribute(name, "top-end");
53
- if (name === "limit")
54
- this.syncQueue();
55
- }
56
- show(options) {
57
- const existing = options.id ? this.toastById.get(options.id) : undefined;
58
- if (existing) {
59
- const id = existing.configure(options);
60
- this.syncQueue();
61
- return id;
62
- }
63
- this.captureFocus();
64
- const toast = this.ownerDocument.createElement("spui-toast");
65
- toast.slot = "toast";
66
- toast.tabIndex = -1;
67
- const id = toast.configure(options);
68
- this.append(toast);
69
- return id;
70
- }
71
- registerToast(toast) {
72
- if (toast.localName !== "spui-toast")
73
- return;
74
- const node = toast;
75
- if (!node.toastId || (node.hidden && !this.queuedToasts.has(node)))
76
- return;
77
- this.toastById.set(node.toastId, node);
78
- if (this.queuedToasts.has(node)) {
79
- node.hidden = true;
80
- node.pause("queue");
81
- return;
82
- }
83
- if (this.activeToasts.has(node))
84
- return;
85
- if (this.activeToasts.size >= this.limit)
86
- this.queueToast(node);
87
- else
88
- this.activeToasts.add(node);
89
- }
90
- refreshQueue() { this.syncQueue(); }
91
- captureFocus() {
92
- const active = this.ownerDocument.activeElement;
93
- if (!this.activeToasts.size && !this.queuedToasts.size && active && active !== this.ownerDocument.body && active.nodeType === 1 && !this.contains(active))
94
- this.lastFocused = active;
95
- }
96
- update(id, options) {
97
- const toast = this.toastById.get(id);
98
- if (!toast)
99
- return false;
100
- toast.configure({ ...options, priority: options.priority ?? (Number(toast.getAttribute("priority")) || 0), id });
101
- this.syncQueue();
102
- return true;
103
- }
104
- dismiss(id, reason = "dismiss") {
105
- const toast = this.toastById.get(id);
106
- if (!toast)
107
- return false;
108
- if (this.queuedToasts.has(toast)) {
109
- this.queuedToasts.delete(toast);
110
- toast.hidden = false;
111
- toast.play("queue");
112
- }
113
- toast.dismiss(reason);
114
- return true;
115
- }
116
- dismissAll(reason = "dismiss-all") {
117
- const toasts = [...this.toasts];
118
- toasts.forEach(toast => this.dismiss(toast.toastId, reason));
119
- return toasts.length;
120
- }
121
- pause(id) {
122
- const toast = this.toastById.get(id);
123
- if (!toast)
124
- return false;
125
- toast.pause();
126
- return true;
127
- }
128
- play(id) {
129
- const toast = this.toastById.get(id);
130
- if (!toast)
131
- return false;
132
- toast.play();
133
- return true;
134
- }
135
- focusNewest() {
136
- const toast = [...this.toasts].reverse().find(item => !item.hidden);
137
- if (!toast)
138
- return false;
139
- toast.focus();
140
- return true;
141
- }
142
- get toasts() {
143
- return Array.from(this.children).filter(element => element.localName === "spui-toast");
144
- }
145
- get limit() {
146
- if (!this.hasAttribute("limit"))
147
- return Number.POSITIVE_INFINITY;
148
- const value = Number(this.getAttribute("limit"));
149
- return Number.isFinite(value) && value >= 0 ? Math.floor(value) : Number.POSITIVE_INFINITY;
150
- }
151
- get visibleToasts() { return [...this.activeToasts].filter(toast => toast.isConnected && !toast.hidden); }
152
- queueToast(toast) {
153
- this.activeToasts.delete(toast);
154
- this.queuedToasts.add(toast);
155
- toast.hidden = true;
156
- toast.pause("queue");
157
- }
158
- syncQueue() {
159
- if (!this.isConnected)
160
- return;
161
- const toasts = this.toasts;
162
- const children = new Set(toasts);
163
- for (const [id, toast] of this.toastById)
164
- if (!children.has(toast))
165
- this.toastById.delete(id);
166
- for (const toast of this.activeToasts)
167
- if (!children.has(toast))
168
- this.activeToasts.delete(toast);
169
- for (const toast of this.queuedToasts)
170
- if (!children.has(toast))
171
- this.queuedToasts.delete(toast);
172
- for (const toast of toasts)
173
- this.registerToast(toast);
174
- const limit = this.limit;
175
- const visible = toasts.filter(toast => this.activeToasts.has(toast));
176
- for (const toast of visible.slice(limit))
177
- this.queueToast(toast);
178
- const order = new Map(toasts.map((toast, index) => [toast, index]));
179
- const queued = [...this.queuedToasts].filter(toast => children.has(toast)).sort((a, b) => {
180
- const priorityA = Number(a.getAttribute("priority")) || 0;
181
- const priorityB = Number(b.getAttribute("priority")) || 0;
182
- return priorityA - priorityB || order.get(a) - order.get(b);
183
- });
184
- for (const toast of queued.slice(0, Math.max(0, limit - visible.length))) {
185
- this.queuedToasts.delete(toast);
186
- this.activeToasts.add(toast);
187
- toast.hidden = false;
188
- toast.play("queue");
189
- }
190
- }
191
- onSlotChange = () => {
192
- this.syncQueue();
193
- const count = this.visibleToasts.length;
194
- if (!this.previousToastCount && count && !this.lastFocused) {
195
- const active = this.ownerDocument.activeElement;
196
- if (active && active !== this.ownerDocument.body && active.nodeType === 1 && !this.contains(active))
197
- this.lastFocused = active;
198
- }
199
- if (!count && this.previousToastCount && !this.restorePending)
200
- this.lastFocused = null;
201
- this.previousToastCount = count;
202
- };
203
- onDismiss = (event) => {
204
- const toast = event.target;
205
- if (!(toast instanceof HTMLElement) || toast.localName !== "spui-toast")
206
- return;
207
- const detail = event.detail;
208
- const hadFocus = Boolean(detail?.hadFocus) || (this.contains(this.ownerDocument.activeElement) && (this.ownerDocument.activeElement === toast || toast.contains(this.ownerDocument.activeElement)));
209
- if (hadFocus) {
210
- this.restorePending = true;
211
- this.ownerDocument.defaultView?.setTimeout(() => { this.restorePending = false; this.restoreFocus(toast); }, 0);
212
- }
213
- this.activeToasts.delete(toast);
214
- this.queuedToasts.delete(toast);
215
- const toastId = toast.toastId;
216
- if (this.toastById.get(toastId) === toast)
217
- this.toastById.delete(toastId);
218
- this.syncQueue();
219
- if (!this.hasAttribute("managed"))
220
- this.ownerDocument.defaultView?.setTimeout(() => toast.remove(), 0);
221
- };
222
- onAnnounce = (event) => {
223
- const detail = event.detail;
224
- if (!this.announceEnabled || !detail?.message?.trim() || (this.activeAnnouncement?.message === detail.message))
225
- return;
226
- if (this.announcementQueue.some(item => item.id === detail.id && item.message === detail.message))
227
- return;
228
- const item = { ...detail, politeness: detail.politeness === "assertive" ? "assertive" : "polite" };
229
- if (this.announce) {
230
- this.announce(item.message, { politeness: item.politeness });
231
- return;
232
- }
233
- const index = item.politeness === "assertive" ? this.announcementQueue.findIndex(queued => queued.politeness === "polite") : -1;
234
- if (index < 0)
235
- this.announcementQueue.push(item);
236
- else
237
- this.announcementQueue.splice(index, 0, item);
238
- this.presentNextAnnouncement();
239
- };
240
- presentNextAnnouncement() {
241
- if (this.activeAnnouncement || !this.announcementQueue.length)
242
- return;
243
- const announcement = this.announcementQueue.shift();
244
- this.activeAnnouncement = announcement;
245
- this.politeRegion.textContent = "";
246
- this.assertiveRegion.textContent = "";
247
- this.announcementTimer = this.ownerDocument.defaultView.setTimeout(() => {
248
- const region = announcement.politeness === "assertive" ? this.assertiveRegion : this.politeRegion;
249
- region.textContent = announcement.message;
250
- this.announcementTimer = this.ownerDocument.defaultView.setTimeout(() => {
251
- this.politeRegion.textContent = "";
252
- this.assertiveRegion.textContent = "";
253
- this.activeAnnouncement = undefined;
254
- this.announcementTimer = undefined;
255
- this.presentNextAnnouncement();
256
- }, 500);
257
- }, 50);
258
- }
259
- getVisibleFocusables() {
260
- const focusables = [];
261
- const visit = (node) => {
262
- if (node instanceof HTMLElement) {
263
- if (node.matches('a[href],button,input:not([type="hidden"]),select,textarea,[tabindex]') && node.tabIndex >= 0 && !node.hasAttribute("disabled") && !node.hidden && node.getAttribute("aria-hidden") !== "true" && node.getClientRects().length)
264
- focusables.push(node);
265
- if (node.shadowRoot) {
266
- for (const child of node.shadowRoot.childNodes)
267
- visit(child);
268
- return;
269
- }
270
- }
271
- if (node instanceof HTMLSlotElement) {
272
- const assigned = node.assignedNodes();
273
- for (const child of assigned.length ? assigned : node.childNodes)
274
- visit(child);
275
- return;
276
- }
277
- for (const child of node.childNodes)
278
- visit(child);
279
- };
280
- for (const toast of this.visibleToasts)
281
- visit(toast);
282
- return focusables;
283
- }
284
- onKeyDown = (event) => {
285
- if (event.key === "Tab") {
286
- const focusables = this.getVisibleFocusables();
287
- const target = event.composedPath()[0];
288
- const current = focusables.findIndex(element => element === target || (target instanceof Node && element.contains(target)));
289
- const edge = event.shiftKey ? 0 : focusables.length - 1;
290
- if (focusables.length > 1 && current === edge) {
291
- event.preventDefault();
292
- focusables[event.shiftKey ? focusables.length - 1 : 0].focus();
293
- }
294
- return;
295
- }
296
- if (event.key === "ArrowUp" || event.key === "ArrowDown") {
297
- const visible = this.toasts.filter(toast => !toast.hidden);
298
- if (!visible.length)
299
- return;
300
- const active = this.ownerDocument.activeElement;
301
- const current = visible.findIndex(toast => toast === active || toast.contains(active));
302
- const delta = event.key === "ArrowUp" ? -1 : 1;
303
- const next = current < 0 ? visible.length - 1 : (current + delta + visible.length) % visible.length;
304
- event.preventDefault();
305
- visible[next].focus();
306
- return;
307
- }
308
- if (event.key !== "Escape" && event.key !== "Delete")
309
- return;
310
- const active = this.ownerDocument.activeElement;
311
- const focused = this.toasts.find(toast => toast === active || toast.contains(active));
312
- const target = event.key === "Delete" ? focused : focused ?? [...this.toasts].reverse().find(toast => !toast.hidden);
313
- if (!target)
314
- return;
315
- event.preventDefault();
316
- target.dismiss("keyboard");
317
- };
318
- onFocusIn = () => { this.announceEnabled = false; for (const toast of this.toasts)
319
- toast.pause("toaster-focus"); };
320
- onFocusOut = (event) => {
321
- if (this.contains(event.relatedTarget))
322
- return;
323
- this.announceEnabled = true;
324
- for (const toast of this.toasts)
325
- toast.play("toaster-focus");
326
- };
327
- restoreFocus(dismissed) {
328
- const next = [...this.toasts].reverse().find(item => item !== dismissed && !item.hidden);
329
- if (next)
330
- next.focus();
331
- else {
332
- if (this.lastFocused?.isConnected)
333
- this.lastFocused.focus();
334
- this.lastFocused = null;
335
- }
336
- }
337
- render() {
338
- const shadow = this.attachShadow({ mode: "open" });
339
- this.toastSlot = this.ownerDocument.createElement("slot");
340
- this.toastSlot.name = "toast";
341
- const announcer = this.ownerDocument.createElement("div");
342
- announcer.className = "announcer";
343
- this.assertiveRegion = this.ownerDocument.createElement("div");
344
- this.assertiveRegion.setAttribute("aria-live", "assertive");
345
- this.assertiveRegion.setAttribute("aria-atomic", "true");
346
- this.politeRegion = this.ownerDocument.createElement("div");
347
- this.politeRegion.setAttribute("aria-live", "polite");
348
- this.politeRegion.setAttribute("aria-atomic", "true");
349
- announcer.append(this.assertiveRegion, this.politeRegion);
350
- const style = this.ownerDocument.createElement("style");
351
- style.textContent = `:host{position:fixed;z-index:var(--spui-toaster-z-index,var(--spui-layer-toast,10000));display:flex;flex-direction:column;gap:var(--spui-toaster-gap,10px);box-sizing:border-box;inline-size:min(100vw,460px);max-block-size:calc(100dvh - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px));overflow:auto;overscroll-behavior:contain;padding:calc(16px + env(safe-area-inset-top,0px)) calc(16px + env(safe-area-inset-right,0px)) calc(16px + env(safe-area-inset-bottom,0px)) calc(16px + env(safe-area-inset-left,0px));pointer-events:none}:host([position=top-start]){inset-block-start:0;inset-inline-start:0;align-items:flex-start}:host([position=top-end]){inset-block-start:0;inset-inline-end:0;align-items:flex-end}:host([position=bottom-start]){inset-block-end:0;inset-inline-start:0;align-items:flex-start;flex-direction:column-reverse}:host([position=bottom-end]){inset-block-end:0;inset-inline-end:0;align-items:flex-end;flex-direction:column-reverse}slot{display:contents}::slotted(spui-toast){max-inline-size:100%}.announcer{position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;clip-path:inset(50%);border:0}:host([inline]){position:relative;inset:auto;inline-size:100%;max-block-size:none;overflow:visible;padding:0}:host([inline][position^=bottom]){flex-direction:column}`;
352
- shadow.replaceChildren(style, this.toastSlot, announcer);
353
- }
354
- }
355
- customElements.define("spui-toaster", SpuiToaster);
356
- }
@@ -1,2 +0,0 @@
1
- export declare const defineCheckbox: () => void;
2
- export declare const defineSwitch: () => void;
@@ -1,246 +0,0 @@
1
- import { base, rememberNativeFormControlDefaults, stopHostAccessibleNameSync, syncHostAccessibleName } from "./shared.js";
2
- function defineToggle(name, type) {
3
- if (customElements.get(name))
4
- return;
5
- class SpuiToggle extends HTMLElement {
6
- static formAssociated = true;
7
- static observedAttributes = ["checked", "default-checked", "disabled", "disabled-focusable", "required", "name", "value", "aria-label", "aria-labelledby", "aria-description", "aria-describedby", "aria-invalid"];
8
- internals;
9
- checkedValue;
10
- defaultCheckedValue;
11
- formDisabledValue = false;
12
- boundInput;
13
- slotInputDefaults;
14
- generatedLabelInput;
15
- generatedLabel = "";
16
- handleInputChange = (event) => {
17
- const input = this.getInput();
18
- if (!input)
19
- return;
20
- if (this.isDisabled()) {
21
- this.syncInput();
22
- this.syncFormState();
23
- return;
24
- }
25
- const indicator = this.shadowRoot?.querySelector(".indicator");
26
- if (indicator)
27
- indicator.dataset.state = input.indeterminate ? "mixed" : input.checked ? "checked" : "unchecked";
28
- this.syncFormState();
29
- this.dispatchEvent(new CustomEvent("spui-change", { bubbles: true, composed: true, detail: { checked: input.indeterminate ? "mixed" : input.checked, value: input.value, sourceEvent: event } }));
30
- };
31
- handleInputClick = (event) => {
32
- if (this.isDisabled() && this.isDisabledFocusable())
33
- event.preventDefault();
34
- };
35
- constructor() { super(); this.internals = this.attachInternals(); }
36
- get checked() { const input = this.getInput(); return input ? (input.indeterminate ? "mixed" : input.checked) : this.checkedValue ?? this.initialChecked(); }
37
- set checked(value) { this.checkedValue = this.normalizeChecked(value); this.syncInput(); this.syncFormState(); }
38
- get defaultChecked() { return this.defaultCheckedValue ?? this.initialDefaultChecked(); }
39
- set defaultChecked(value) { this.defaultCheckedValue = this.normalizeChecked(value); if (this.checkedValue === undefined)
40
- this.syncInput(); this.syncFormState(); }
41
- get form() { return this.internals.form; }
42
- get validity() { return this.internals.validity; }
43
- get validationMessage() { return this.internals.validationMessage; }
44
- get willValidate() { return this.internals.willValidate; }
45
- checkValidity() { return this.internals.checkValidity(); }
46
- reportValidity() { return this.internals.reportValidity(); }
47
- formResetCallback() { this.checked = this.defaultChecked; }
48
- formDisabledCallback(disabled) { this.formDisabledValue = disabled; this.syncInput(); this.syncFormState(); }
49
- formStateRestoreCallback(state) {
50
- if (typeof state === "string")
51
- this.checked = state === "mixed" ? "mixed" : state === "checked";
52
- }
53
- getInput() {
54
- const slot = this.shadowRoot?.querySelector('slot[name="input"]');
55
- const assigned = slot?.assignedElements().find((element) => element instanceof HTMLInputElement);
56
- const fallback = this.shadowRoot?.querySelector(".input-fallback");
57
- if (fallback) {
58
- fallback.hidden = Boolean(assigned);
59
- fallback.toggleAttribute("aria-hidden", Boolean(assigned));
60
- }
61
- return assigned ?? fallback ?? this.shadowRoot?.querySelector("input") ?? null;
62
- }
63
- bindInput(input) {
64
- if (this.boundInput === input)
65
- return;
66
- this.boundInput?.removeEventListener("change", this.handleInputChange);
67
- this.boundInput?.removeEventListener("click", this.handleInputClick);
68
- input.addEventListener("change", this.handleInputChange);
69
- input.addEventListener("click", this.handleInputClick);
70
- this.boundInput = input;
71
- }
72
- syncInputSlot() {
73
- const slot = this.shadowRoot?.querySelector('slot[name="input"]');
74
- const assigned = slot?.assignedElements().some(element => element instanceof HTMLInputElement) ?? false;
75
- const fallback = this.shadowRoot?.querySelector(".input-fallback");
76
- if (fallback)
77
- fallback.hidden = assigned;
78
- const input = this.getInput();
79
- if (input && !input.classList.contains("input-fallback"))
80
- this.slotInputDefaults = rememberNativeFormControlDefaults(this.slotInputDefaults, input);
81
- if (input)
82
- this.bindInput(input);
83
- this.syncInput();
84
- this.syncFormState();
85
- }
86
- isDisabled() { return this.formDisabledValue || this.hasAttribute("disabled"); }
87
- isDisabledFocusable() { return this.isDisabled() && this.hasAttribute("disabled-focusable"); }
88
- initialChecked() {
89
- const initial = this.getAttribute("checked") ?? this.getAttribute("default-checked");
90
- if (initial === null && this.slotInputDefaults)
91
- return this.slotInputDefaults.checked;
92
- return type === "checkbox" && initial === "mixed" ? "mixed" : initial !== null;
93
- }
94
- initialDefaultChecked() {
95
- const initial = this.getAttribute("checked") ?? this.getAttribute("default-checked");
96
- if (initial === null && this.slotInputDefaults)
97
- return this.slotInputDefaults.defaultChecked;
98
- return type === "checkbox" && initial === "mixed" ? "mixed" : initial !== null;
99
- }
100
- normalizeChecked(value) { return type === "checkbox" && value === "mixed" ? "mixed" : Boolean(value); }
101
- syncInput() {
102
- const input = this.getInput();
103
- if (!input)
104
- return;
105
- if (!input.classList.contains("input-fallback"))
106
- this.slotInputDefaults = rememberNativeFormControlDefaults(this.slotInputDefaults, input);
107
- const defaults = input.classList.contains("input-fallback") ? undefined : this.slotInputDefaults;
108
- const checked = this.checkedValue ?? this.defaultCheckedValue ?? this.initialChecked();
109
- input.checked = checked === true;
110
- input.indeterminate = checked === "mixed";
111
- input.disabled = (this.isDisabled() && !this.isDisabledFocusable()) || Boolean(defaults?.disabled);
112
- input.type = "checkbox";
113
- if (type === "switch")
114
- input.setAttribute("role", "switch");
115
- input.required = this.hasAttribute("required") || Boolean(defaults?.required);
116
- input.value = this.getAttribute("value") ?? defaults?.value ?? "on";
117
- input.removeAttribute("name");
118
- for (const attr of ["aria-label", "aria-labelledby", "aria-description", "aria-describedby", "aria-invalid"]) {
119
- const value = this.getAttribute(attr);
120
- if (value !== null && !input.hasAttribute(attr))
121
- input.setAttribute(attr, value);
122
- }
123
- syncHostAccessibleName(this, input);
124
- if (this.generatedLabelInput && this.generatedLabelInput.getAttribute("aria-label") === this.generatedLabel)
125
- this.generatedLabelInput.removeAttribute("aria-label");
126
- this.generatedLabelInput = undefined;
127
- this.generatedLabel = "";
128
- if (!input.classList.contains("input-fallback") && !input.hasAttribute("aria-label") && !input.hasAttribute("aria-labelledby")) {
129
- const labelSlot = this.shadowRoot?.querySelector('slot[name="label"]');
130
- const label = labelSlot?.assignedNodes({ flatten: true }).map(node => node.textContent ?? "").join("").trim();
131
- if (label) {
132
- input.setAttribute("aria-label", label);
133
- this.generatedLabelInput = input;
134
- this.generatedLabel = label;
135
- }
136
- }
137
- const indicator = this.shadowRoot?.querySelector(".indicator");
138
- if (indicator)
139
- indicator.dataset.state = input.indeterminate ? "mixed" : input.checked ? "checked" : "unchecked";
140
- if (this.isDisabledFocusable()) {
141
- input.setAttribute("aria-disabled", "true");
142
- input.tabIndex = 0;
143
- }
144
- else {
145
- input.removeAttribute("aria-disabled");
146
- input.removeAttribute("tabindex");
147
- }
148
- }
149
- syncFormState() {
150
- const input = this.getInput();
151
- if (!input)
152
- return;
153
- const disabled = this.formDisabledValue || input.disabled || this.hasAttribute("disabled");
154
- const checked = input.checked && !disabled;
155
- this.internals.setFormValue(checked ? input.value : null, checked ? "checked" : input.indeterminate ? "mixed" : "unchecked");
156
- const missing = !disabled && input.required && !input.checked;
157
- this.internals.setValidity(missing ? { valueMissing: true } : {}, missing ? input.validationMessage : "", missing ? input : undefined);
158
- }
159
- connectedCallback() {
160
- if (!this.shadowRoot) {
161
- const shadow = this.attachShadow({ mode: "open" });
162
- const label = document.createElement("label");
163
- const input = document.createElement("input");
164
- input.type = "checkbox";
165
- input.className = "input-fallback";
166
- if (type === "switch")
167
- input.setAttribute("role", "switch");
168
- input.part.add("control");
169
- label.part.add("label");
170
- input.required = this.hasAttribute("required");
171
- input.name = this.getAttribute("name") ?? "";
172
- input.value = this.getAttribute("value") ?? "on";
173
- for (const attr of ["aria-label", "aria-labelledby", "aria-description", "aria-describedby", "aria-invalid"]) {
174
- const value = this.getAttribute(attr);
175
- if (value !== null)
176
- input.setAttribute(attr, value);
177
- }
178
- const text = document.createElement("span");
179
- const labelSlot = document.createElement("slot");
180
- labelSlot.name = "label";
181
- labelSlot.part.add("label");
182
- labelSlot.append(document.createElement("slot"));
183
- labelSlot.addEventListener("slotchange", () => this.syncInput());
184
- text.append(labelSlot);
185
- const inputSlot = document.createElement("slot");
186
- inputSlot.name = "input";
187
- inputSlot.part.add("input");
188
- inputSlot.append(input);
189
- inputSlot.addEventListener("slotchange", () => this.syncInputSlot());
190
- const control = document.createElement("span");
191
- control.className = "control";
192
- control.part.add("control");
193
- const indicator = document.createElement("span");
194
- indicator.className = "indicator";
195
- indicator.part.add("indicator");
196
- indicator.setAttribute("aria-hidden", "true");
197
- const indicatorSlot = document.createElement("slot");
198
- indicatorSlot.name = "indicator";
199
- const mark = document.createElement("span");
200
- mark.className = "indicator-mark";
201
- indicatorSlot.append(mark);
202
- indicatorSlot.addEventListener("slotchange", () => indicator.toggleAttribute("data-custom", indicatorSlot.assignedElements().length > 0));
203
- indicator.append(indicatorSlot);
204
- this.bindInput(input);
205
- control.append(inputSlot, indicator);
206
- label.append(control, text);
207
- const styles = type === "switch"
208
- ? `input{appearance:none;position:relative;box-sizing:border-box;width:38px;height:22px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,var(--colorNeutralStroke1,#8a8886))));border-radius:999px;background:var(--spui-control-background,var(--spui-ui-surface-hover,var(--spui-semantic-input-background,var(--colorNeutralBackground1,#fff))));cursor:pointer;transition:background-color var(--spui-motion-duration-normal,.15s) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1))}input::after{content:'';position:absolute;top:2px;inset-inline-start:2px;width:16px;height:16px;border-radius:50%;background:var(--spui-ui-muted,var(--spui-semantic-input-foreground,var(--colorNeutralForeground2,#605e5c)));transition:transform var(--spui-motion-duration-normal,.15s) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1))}input:checked{border-color:var(--spui-primary-background,var(--spui-ui-accent,var(--spui-semantic-primary-button-background,var(--colorBrandBackground,#0078d4))));background:var(--spui-primary-background,var(--spui-ui-accent,var(--spui-semantic-primary-button-background,var(--colorBrandBackground,#0078d4))))}input:checked::after{background:var(--spui-ui-accent-text,var(--colorNeutralForegroundOnBrand,#fff));transform:translateX(16px)}@media(prefers-reduced-motion:reduce){input,input::after{transition:none}}`
209
- : `input{appearance:none;display:grid;place-content:center;box-sizing:border-box;width:16px;height:16px;margin:0;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886)));border-radius:3px;background:var(--spui-control-background,var(--spui-ui-surface,#fff));color:var(--spui-ui-accent-text,#fff);cursor:pointer}input::before{content:'';width:4px;height:8px;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg) translate(-1px,-1px);opacity:0}input:checked{border-color:var(--spui-ui-accent,var(--spui-semantic-input-background-checked,#0f6cbd));background:var(--spui-ui-accent,var(--spui-semantic-input-background-checked,#0f6cbd))}input:checked::before{opacity:1}input:indeterminate{border-color:var(--spui-ui-accent,var(--spui-semantic-input-background-checked,#0f6cbd));background:var(--spui-ui-accent,var(--spui-semantic-input-background-checked,#0f6cbd))}input:indeterminate::before{width:8px;height:2px;border:0;border-radius:1px;background:currentColor;transform:none;opacity:1}:host([shape=circular]) input{border-radius:50%}:host([shape=circular]) input:indeterminate::before{width:6px;height:6px;border-radius:50%}`;
210
- const style = document.createElement("style");
211
- style.textContent = `${base}:host{display:inline-block}label{display:inline-flex;align-items:center;gap:8px;min-height:32px;padding-inline:4px;cursor:pointer}input{flex:none}input:disabled,input[aria-disabled=true]{cursor:not-allowed}label:has(input:disabled),label:has(input[aria-disabled=true]){opacity:.55;cursor:not-allowed}input:focus-visible{outline:2px solid var(--spui-focus-ring,var(--spui-semantic-focus-border,var(--colorStrokeFocus2,#005a9e)));outline-offset:2px}${styles}:host(:not([size=small])) input[role=switch]{width:40px;height:20px}:host(:not([size=small])) input[role=switch]::after{top:0;width:18px;height:18px}:host(:not([size=small])) input[role=switch]:checked::after{transform:translateX(18px)}:host([dir=rtl]:not([size=small])) input[role=switch]:checked::after,:host-context([dir=rtl]) :host(:not([size=small])) input[role=switch]:checked::after{transform:translateX(-18px)}:host([label-position=before]) label{flex-direction:row-reverse}:host([label-position=above]) label{flex-direction:column;align-items:flex-start}:host([size=small]) label{min-height:24px;gap:6px;padding-inline:5px}:host([size=small]) input[type=checkbox]{width:14px;height:14px}:host([size=small]) input[role=switch]{width:32px;height:16px}:host([size=small]) input[role=switch]::after{top:0;width:14px;height:14px}:host([size=small]) input[role=switch]:checked::after{transform:translateX(14px)}:host([size=small][dir=rtl]) input[role=switch]:checked::after,:host-context([dir=rtl]) :host([size=small]) input[role=switch]:checked::after{transform:translateX(-14px)}:host([size=large]) label{min-height:44px;gap:10px}:host([size=large]) input[type=checkbox]{width:20px;height:20px}:host([dir=rtl]) input:checked::after,:host-context([dir=rtl]) input:checked::after{transform:translateX(-16px)}@media(forced-colors:active){input{forced-color-adjust:none;border-color:ButtonText;background:Canvas}input:checked,input:indeterminate{border-color:Highlight;background:Highlight}input::before,input:checked::before,input:indeterminate::before{color:HighlightText;background:HighlightText}}`;
212
- if (type === "checkbox")
213
- style.textContent += `.control{position:relative;display:grid;place-items:center;flex:none;width:16px;height:16px}.control>slot[name=input]{position:absolute;inset:0;z-index:1;width:100%;height:100%}.control>slot[name=input]::slotted(input){position:absolute;inset:0;box-sizing:border-box;width:100%;height:100%;margin:0;appearance:none;opacity:0;cursor:pointer}.indicator{box-sizing:border-box;display:grid;place-items:center;width:100%;height:100%;border:1px solid var(--spui-checkbox-indicator-border,var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886))));border-radius:var(--spui-checkbox-indicator-radius,3px);background:var(--spui-checkbox-indicator-background,var(--spui-control-background,var(--spui-ui-surface,#fff)));color:var(--spui-checkbox-indicator-foreground,var(--spui-ui-accent-text,#fff));transition:background-color var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1)),border-color var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1));pointer-events:none}.indicator[data-state=checked],.indicator[data-state=mixed]{border-color:var(--spui-checkbox-checked-background,var(--spui-ui-accent,var(--colorBrandBackground,#0f6cbd)));background:var(--spui-checkbox-checked-background,var(--spui-ui-accent,var(--colorBrandBackground,#0f6cbd)))}.indicator:not([data-custom])[data-state=checked]::after{content:"";width:4px;height:8px;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg) translate(-1px,-1px)}.indicator:not([data-custom])[data-state=mixed]::after{content:"";width:8px;height:2px;border-radius:1px;background:currentColor}:host([shape=circular]) .indicator{border-radius:50%}:host([shape=circular]) .indicator:not([data-custom])[data-state=mixed]::after{width:6px;height:6px;border-radius:50%}.control:has(input:focus-visible) .indicator{outline:2px solid var(--spui-focus-ring,var(--spui-semantic-focus-border,var(--colorStrokeFocus2,#005a9e)));outline-offset:2px}:host([size=small]) .control{width:14px;height:14px}:host([size=large]) .control{width:20px;height:20px}:host([disabled]) .indicator{opacity:.55}slot[name=indicator]::slotted(*){display:grid;place-items:center;max-width:100%;max-height:100%}@media(prefers-reduced-motion:reduce){.indicator{transition:none}}@media(forced-colors:active){.indicator{forced-color-adjust:none;border-color:ButtonText;background:Canvas;color:CanvasText}.indicator[data-state=checked],.indicator[data-state=mixed]{border-color:Highlight;background:Highlight;color:HighlightText}.control:has(input:focus-visible) .indicator{outline-color:Highlight}}`;
214
- else
215
- style.textContent += `.control{position:relative;display:grid;align-items:center;flex:none;width:40px;height:20px}.control>slot[name=input]{position:absolute;inset:0;z-index:1;width:100%;height:100%}.control>slot[name=input] input,.control>slot[name=input]::slotted(input){position:absolute;inset:0;box-sizing:border-box;width:100%;height:100%;margin:0;appearance:none;opacity:0;cursor:pointer}.indicator{position:relative;box-sizing:border-box;width:100%;height:100%;border:1px solid var(--spui-switch-track-border,var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886))));border-radius:999px;background:var(--spui-switch-track-background,var(--spui-control-background,var(--spui-ui-surface-hover,var(--colorNeutralBackground1,#fff))));transition:background-color var(--spui-motion-duration-normal,.15s) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1)),border-color var(--spui-motion-duration-normal,.15s) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1));pointer-events:none}.indicator:not([data-custom])::after{content:"";position:absolute;top:0;inset-inline-start:2px;width:18px;height:18px;border-radius:50%;background:var(--spui-switch-thumb,var(--spui-ui-muted,var(--spui-semantic-input-foreground,var(--colorNeutralForeground2,#605e5c))));transition:transform var(--spui-motion-duration-normal,.15s) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1)),background-color var(--spui-motion-duration-fast,.12s) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1))}.indicator[data-state=checked]{border-color:var(--spui-switch-checked-background,var(--spui-ui-accent,var(--colorBrandBackground,#0078d4)));background:var(--spui-switch-checked-background,var(--spui-ui-accent,var(--colorBrandBackground,#0078d4)))}.indicator:not([data-custom])[data-state=checked]::after{background:var(--spui-ui-accent-text,var(--colorNeutralForegroundOnBrand,#fff));transform:translateX(18px)}:host([size=small]) .control{width:32px;height:16px}:host([size=small]) .indicator:not([data-custom])::after{width:14px;height:14px}:host([size=small]) .indicator:not([data-custom])[data-state=checked]::after{transform:translateX(14px)}:host([dir=rtl]) .indicator:not([data-custom])[data-state=checked]::after,:host-context([dir=rtl]) :host .indicator:not([data-custom])[data-state=checked]::after{transform:translateX(-18px)}:host([dir=rtl][size=small]) .indicator:not([data-custom])[data-state=checked]::after,:host-context([dir=rtl]) :host([size=small]) .indicator:not([data-custom])[data-state=checked]::after{transform:translateX(-14px)}.control:has(input:focus-visible) .indicator{outline:2px solid var(--spui-focus-ring,var(--spui-ui-accent,#005a9e));outline-offset:2px}:host([disabled]) .indicator{opacity:.55}slot[name=indicator]::slotted(*){display:grid;place-items:center;max-width:100%;max-height:100%}@media(prefers-reduced-motion:reduce){.indicator,.indicator::after{transition:none}}@media(forced-colors:active){.indicator{forced-color-adjust:none;border-color:ButtonText;background:Canvas}.indicator[data-state=checked]{border-color:Highlight;background:Highlight}.indicator:not([data-custom])::after{background:ButtonText}.control:has(input:focus-visible) .indicator{outline-color:Highlight}}`;
216
- shadow.append(style, label);
217
- }
218
- this.syncInputSlot();
219
- }
220
- disconnectedCallback() { stopHostAccessibleNameSync(this); }
221
- attributeChangedCallback(name) {
222
- const input = this.getInput();
223
- if (!input)
224
- return;
225
- if ((name === "checked" || name === "default-checked") && this.checkedValue === undefined)
226
- this.syncInput();
227
- if (name === "disabled" || name === "disabled-focusable")
228
- this.syncInput();
229
- if (name === "required")
230
- input.required = this.hasAttribute(name) || Boolean(this.slotInputDefaults?.required);
231
- if (name === "name")
232
- input.removeAttribute("name");
233
- if (name === "value")
234
- input.value = this.getAttribute(name) ?? this.slotInputDefaults?.value ?? "on";
235
- if (name === "aria-label" || name === "aria-labelledby" || name === "aria-description" || name === "aria-describedby" || name === "aria-invalid") {
236
- const value = this.getAttribute(name);
237
- value === null ? input.removeAttribute(name) : input.setAttribute(name, value);
238
- syncHostAccessibleName(this, input);
239
- }
240
- this.syncFormState();
241
- }
242
- }
243
- customElements.define(name, SpuiToggle);
244
- }
245
- export const defineCheckbox = () => defineToggle("spui-checkbox", "checkbox");
246
- export const defineSwitch = () => defineToggle("spui-switch", "switch");
@@ -1,12 +0,0 @@
1
- export type ToolbarCheckedValues = Record<string, readonly string[]>;
2
- export type ToolbarCheckedValueChange = {
3
- name: string;
4
- checkedItems: string[];
5
- sourceEvent?: Event;
6
- currentTarget?: HTMLElement;
7
- };
8
- export declare function defineToolbarGroup(): void;
9
- export declare function defineToolbarSeparator(): void;
10
- export declare function defineToolbarRadioGroup(): void;
11
- export declare function defineToolbarRadioButton(): void;
12
- export declare function defineToolbar(): void;