@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,110 +0,0 @@
1
- import { base } from "./shared.js";
2
- import { defineAvatar } from "./avatar.js";
3
- /** A compact, accessible stack of Avatar elements with an expandable overflow. */
4
- // ponytail: expand in place so the leaf needs no overlay manager; add a popover when hidden members need per-person actions.
5
- export function defineAvatarGroup() {
6
- if (customElements.get("spui-avatar-group"))
7
- return;
8
- defineAvatar();
9
- class SpuiAvatarGroup extends HTMLElement {
10
- static observedAttributes = ["max-visible", "label", "expanded", "show-more-label", "show-less-label", "layout", "size"];
11
- slotElement = document.createElement("slot");
12
- button = document.createElement("button");
13
- group = document.createElement("div");
14
- avatars = document.createElement("div");
15
- internalExpanded = false;
16
- connectedCallback() {
17
- if (!this.shadowRoot)
18
- this.render();
19
- this.sync();
20
- }
21
- attributeChangedCallback() {
22
- this.sync();
23
- }
24
- get expanded() { return this.hasAttribute("expanded") || this.internalExpanded; }
25
- set expanded(value) {
26
- this.internalExpanded = value;
27
- this.toggleAttribute("expanded", value);
28
- }
29
- render() {
30
- const shadow = this.attachShadow({ mode: "open" });
31
- this.group.className = "group";
32
- this.group.part.add("group");
33
- this.avatars.className = "avatars";
34
- this.avatars.part.add("avatars");
35
- this.slotElement.addEventListener("slotchange", () => this.sync());
36
- this.button.type = "button";
37
- this.button.className = "overflow";
38
- this.button.part.add("overflow");
39
- this.button.addEventListener("click", () => {
40
- const next = !this.expanded;
41
- this.expanded = next;
42
- this.dispatchEvent(new CustomEvent("spui-avatar-group-expanded-change", { bubbles: true, composed: true, detail: { expanded: next } }));
43
- });
44
- this.avatars.append(this.slotElement);
45
- this.group.append(this.avatars, this.button);
46
- const style = document.createElement("style");
47
- style.textContent = `${base}:host{display:inline-block;max-width:100%;font-family:var(--spui-font-family,inherit)}.group{display:inline-flex;align-items:center;max-width:100%;direction:inherit}.avatars{display:inline-flex;align-items:center;max-width:100%}.avatars slot{display:contents}slot::slotted(spui-avatar),slot::slotted(spui-avatar-group-item){position:relative;margin-inline-start:var(--spui-avatar-group-overlap,-10px);border:2px solid var(--spui-avatar-group-border,var(--spui-ui-surface,#fff));border-radius:50%;box-sizing:content-box}slot::slotted(spui-avatar:first-child),slot::slotted(spui-avatar-group-item:first-child){margin-inline-start:0}slot::slotted(spui-avatar-group-popover){position:relative;margin-inline-start:var(--spui-avatar-group-overlap,-10px)}slot::slotted([data-spui-avatar-group-hidden]){display:none!important}.overflow{position:relative;display:inline-grid;place-items:center;flex:none;min-width:32px;height:32px;margin-inline-start:var(--spui-avatar-group-overlap,-10px);padding:0 6px;border:2px solid var(--spui-avatar-group-border,var(--spui-ui-surface,#fff));border-radius:999px;background:var(--spui-avatar-group-background,var(--spui-ui-surface-hover,#f5f5f5));color:var(--spui-avatar-group-foreground,var(--spui-ui-text,var(--spui-semantic-body-text,#323130)));font:600 12px/1 var(--spui-font-family,inherit);cursor:pointer}.overflow[hidden]{display:none}.overflow:focus-visible{outline:2px solid var(--spui-focus-ring,var(--spui-semantic-focus-border,#005a9e));outline-offset:2px}.group[data-layout=spread] slot::slotted(spui-avatar),.group[data-layout=spread] slot::slotted(spui-avatar-group-item),.group[data-layout=spread] slot::slotted(spui-avatar-group-popover),.group[data-layout=spread] .overflow{margin-inline-start:var(--spui-avatar-group-gap,4px)}.group[data-layout=spread] slot::slotted(spui-avatar:first-child),.group[data-layout=spread] slot::slotted(spui-avatar-group-item:first-child){margin-inline-start:0}.group[data-layout=pie] .avatars{position:relative;display:inline-block;flex:none;width:var(--spui-avatar-group-size,32px);height:var(--spui-avatar-group-size,32px);overflow:hidden;border-radius:50%;background:var(--spui-avatar-group-border,var(--spui-ui-surface,#fff))}.group[data-layout=pie] slot::slotted(spui-avatar),.group[data-layout=pie] slot::slotted(spui-avatar-group-item){position:absolute;inset:0;width:100%;height:100%;margin:0;border:0;border-radius:0;box-sizing:border-box}.group[data-layout=pie] slot::slotted([data-pie-total="2"][data-pie-index="0"]){clip-path:inset(0 calc(25% + var(--spui-avatar-group-divider-width,1px)) 0 25%);inset-inline-start:-25%}.group[data-layout=pie] slot::slotted([data-pie-total="2"][data-pie-index="1"]){clip-path:inset(0 25% 0 calc(25% + var(--spui-avatar-group-divider-width,1px)));inset-inline-start:25%}.group[data-layout=pie] slot::slotted([data-pie-total="3"][data-pie-index="0"]){clip-path:inset(0 calc(25% + var(--spui-avatar-group-divider-width,1px)) 0 25%);inset-inline-start:-25%}.group[data-layout=pie] slot::slotted([data-pie-total="3"][data-pie-index="1"]){clip-path:inset(0 0 var(--spui-avatar-group-divider-width,1px) var(--spui-avatar-group-divider-width,1px));inset-inline-start:50%;transform:scale(.5);transform-origin:0 0}.group[data-layout=pie] slot::slotted([data-pie-total="3"][data-pie-index="2"]){clip-path:inset(var(--spui-avatar-group-divider-width,1px) 0 0 var(--spui-avatar-group-divider-width,1px));inset-inline-start:50%;inset-block-start:50%;transform:scale(.5);transform-origin:0 0}:host-context([dir=rtl]) .group[data-layout=pie] slot::slotted([data-pie-total="2"][data-pie-index="0"]),:host-context([dir=rtl]) .group[data-layout=pie] slot::slotted([data-pie-total="3"][data-pie-index="0"]){clip-path:inset(0 25% 0 calc(25% + var(--spui-avatar-group-divider-width,1px)))}:host-context([dir=rtl]) .group[data-layout=pie] slot::slotted([data-pie-total="2"][data-pie-index="1"]){clip-path:inset(0 calc(25% + var(--spui-avatar-group-divider-width,1px)) 0 25%)}:host-context([dir=rtl]) .group[data-layout=pie] slot::slotted([data-pie-total="3"][data-pie-index="1"]){clip-path:inset(0 var(--spui-avatar-group-divider-width,1px) var(--spui-avatar-group-divider-width,1px) 0)}:host-context([dir=rtl]) .group[data-layout=pie] slot::slotted([data-pie-total="3"][data-pie-index="2"]){clip-path:inset(var(--spui-avatar-group-divider-width,1px) var(--spui-avatar-group-divider-width,1px) 0 0)}:host-context([dir=rtl]) .group[data-layout=pie] slot::slotted([data-pie-index="1"]),:host-context([dir=rtl]) .group[data-layout=pie] slot::slotted([data-pie-index="2"]){transform-origin:100% 0}.group[data-layout=pie][data-expanded=true] .avatars{display:inline-flex;width:auto;height:auto;overflow:visible;background:transparent;border-radius:0}.group[data-layout=pie][data-expanded=true] slot::slotted(spui-avatar),.group[data-layout=pie][data-expanded=true] slot::slotted(spui-avatar-group-item){position:relative;inset:auto;width:auto;height:auto;margin-inline-start:var(--spui-avatar-group-overlap,-10px);border:2px solid var(--spui-avatar-group-border,var(--spui-ui-surface,#fff));border-radius:50%;transform:none;clip-path:none}.group[data-layout=pie][data-expanded=true] slot::slotted(spui-avatar:first-child),.group[data-layout=pie][data-expanded=true] slot::slotted(spui-avatar-group-item:first-child){margin-inline-start:0}@media(prefers-reduced-motion:reduce){.overflow{scroll-behavior:auto}}@media(forced-colors:active){.overflow{border-color:ButtonText;background:Canvas;color:CanvasText}.group[data-layout=pie] .avatars{background:CanvasText}}`;
48
- shadow.append(style, this.group);
49
- this.setAttribute("role", "group");
50
- }
51
- sync() {
52
- if (!this.shadowRoot)
53
- return;
54
- const label = this.getAttribute("label")?.trim();
55
- if (label && (!this.hasAttribute("aria-label") || this.dataset.autoLabel !== undefined)) {
56
- this.setAttribute("aria-label", label);
57
- this.dataset.autoLabel = "";
58
- }
59
- else if (!label && this.dataset.autoLabel !== undefined) {
60
- this.removeAttribute("aria-label");
61
- delete this.dataset.autoLabel;
62
- }
63
- const max = Math.max(0, Number.parseInt(this.getAttribute("max-visible") || "5", 10) || 0);
64
- const members = this.slotElement.assignedElements({ flatten: true }).filter((element) => element.localName === "spui-avatar" || element.localName === "spui-avatar-group-item");
65
- const size = this.getAttribute("size");
66
- members.forEach(member => {
67
- if (member.dataset.groupSize !== undefined) {
68
- if (size) {
69
- if (member.getAttribute("size") !== size)
70
- member.setAttribute("size", size);
71
- }
72
- else {
73
- member.removeAttribute("size");
74
- delete member.dataset.groupSize;
75
- }
76
- }
77
- else if (size && !member.hasAttribute("size")) {
78
- member.setAttribute("size", size);
79
- member.dataset.groupSize = "";
80
- }
81
- });
82
- const layout = this.getAttribute("layout") === "spread" || this.getAttribute("layout") === "pie" ? this.getAttribute("layout") : "stack";
83
- const visibleLimit = layout === "pie" ? Math.min(3, max) : max;
84
- const hiddenCount = Math.max(0, members.length - visibleLimit);
85
- members.forEach((member, index) => {
86
- member.toggleAttribute("data-spui-avatar-group-hidden", !this.expanded && index >= visibleLimit);
87
- if (layout === "pie" && index < visibleLimit) {
88
- member.dataset.pieIndex = String(index);
89
- member.dataset.pieTotal = String(Math.min(visibleLimit, members.length));
90
- }
91
- else {
92
- delete member.dataset.pieIndex;
93
- delete member.dataset.pieTotal;
94
- }
95
- });
96
- this.group.dataset.layout = layout;
97
- this.group.dataset.expanded = String(this.expanded);
98
- const groupSize = Number.parseFloat(this.getAttribute("size") || "32");
99
- this.group.style.setProperty("--spui-avatar-group-size", `${Number.isFinite(groupSize) && groupSize > 0 ? groupSize : 32}px`);
100
- this.button.hidden = hiddenCount === 0;
101
- this.button.textContent = `+${hiddenCount}`;
102
- this.button.setAttribute("aria-expanded", String(this.expanded));
103
- const more = this.getAttribute("show-more-label") || "Show {count} more people";
104
- const less = this.getAttribute("show-less-label") || "Show fewer people";
105
- // Include the visible count so the accessible name contains the button's visible text.
106
- this.button.setAttribute("aria-label", `+${hiddenCount} ${this.expanded ? less : more.replace("{count}", String(hiddenCount))}`);
107
- }
108
- }
109
- customElements.define("spui-avatar-group", SpuiAvatarGroup);
110
- }
@@ -1,4 +0,0 @@
1
- export type AvatarNamedColor = "dark-red" | "cranberry" | "red" | "pumpkin" | "peach" | "marigold" | "gold" | "brass" | "brown" | "forest" | "seafoam" | "dark-green" | "light-teal" | "teal" | "steel" | "blue" | "royal-blue" | "cornflower" | "navy" | "lavender" | "purple" | "grape" | "lilac" | "pink" | "magenta" | "plum" | "beige" | "mink" | "platinum" | "anchor";
2
- export type AvatarColor = "neutral" | "brand" | "colorful" | AvatarNamedColor;
3
- /** Small, theme-aware people and entity marker. Images are optional; name/initials are the fast fallback. */
4
- export declare function defineAvatar(): void;
@@ -1,251 +0,0 @@
1
- import { base } from "./shared.js";
2
- const themeWatches = new WeakMap();
3
- const namedColorTokens = {
4
- "dark-red": { token: "DarkRed", fallback: "#d69ca5" }, cranberry: { token: "Cranberry", fallback: "#eeacb2" }, red: { token: "Red", fallback: "#f1bbbc" },
5
- pumpkin: { token: "Pumpkin", fallback: "#efc4ad" }, peach: { token: "Peach", fallback: "#ffddb3" }, marigold: { token: "Marigold", fallback: "#f9e2ae" },
6
- gold: { token: "Gold", fallback: "#ecdfa5" }, brass: { token: "Brass", fallback: "#e0cea2" }, brown: { token: "Brown", fallback: "#ddc3b0" },
7
- forest: { token: "Forest", fallback: "#bdd99b" }, seafoam: { token: "Seafoam", fallback: "#a8f0cd" }, "dark-green": { token: "DarkGreen", fallback: "#9ad29a" },
8
- "light-teal": { token: "LightTeal", fallback: "#a6e9ed" }, teal: { token: "Teal", fallback: "#9bd9db" }, steel: { token: "Steel", fallback: "#94c8d4" },
9
- blue: { token: "Blue", fallback: "#a9d3f2" }, "royal-blue": { token: "RoyalBlue", fallback: "#9abfdc" }, cornflower: { token: "Cornflower", fallback: "#c8d1fa" },
10
- navy: { token: "Navy", fallback: "#a3b2e8" }, lavender: { token: "Lavender", fallback: "#d2ccf8" }, purple: { token: "Purple", fallback: "#c6b1de" },
11
- grape: { token: "Grape", fallback: "#d9a7e0" }, lilac: { token: "Lilac", fallback: "#e6bfed" }, pink: { token: "Pink", fallback: "#f7c0e3" },
12
- magenta: { token: "Magenta", fallback: "#eca5d1" }, plum: { token: "Plum", fallback: "#d696c0" }, beige: { token: "Beige", fallback: "#d7d4d4" },
13
- mink: { token: "Mink", fallback: "#cecccb" }, platinum: { token: "Platinum", fallback: "#cdd6d8" }, anchor: { token: "Anchor", fallback: "#bcc3c7" }
14
- };
15
- /** Small, theme-aware people and entity marker. Images are optional; name/initials are the fast fallback. */
16
- export function defineAvatar() {
17
- if (customElements.get("spui-avatar"))
18
- return;
19
- class SpuiAvatar extends HTMLElement {
20
- static observedAttributes = ["name", "image", "initials", "size", "shape", "color", "id-for-color", "decorative"];
21
- imageSource = "";
22
- themeRoot;
23
- image = document.createElement("img");
24
- initials = document.createElement("span");
25
- fallback = document.createElement("span");
26
- surface = document.createElement("span");
27
- connectedCallback() {
28
- if (!this.shadowRoot)
29
- this.render();
30
- this.sync();
31
- this.watchTheme();
32
- }
33
- disconnectedCallback() {
34
- this.unwatchTheme();
35
- }
36
- attributeChangedCallback() {
37
- this.sync();
38
- if (this.isConnected) {
39
- this.unwatchTheme();
40
- this.watchTheme();
41
- }
42
- }
43
- refreshThemeColor() {
44
- const color = this.getAttribute("color");
45
- const named = namedColorTokens[color];
46
- if (named) {
47
- this.dataset.namedColor = "";
48
- this.style.setProperty("--spui-avatar-colorful-background", `var(--colorPalette${named.token}Background2, color-mix(in srgb, ${named.fallback} 18%, var(--spui-ui-surface, #fff)))`);
49
- this.style.setProperty("--spui-avatar-colorful-foreground", `var(--colorPalette${named.token}Foreground2, var(--spui-ui-text, var(--spui-semantic-body-text, #242424)))`);
50
- this.style.setProperty("--spui-avatar-active-color", `var(--colorPalette${named.token}BorderActive, var(--spui-ui-accent, #78716c))`);
51
- return;
52
- }
53
- delete this.dataset.namedColor;
54
- this.style.removeProperty("--spui-avatar-active-color");
55
- if (color !== "colorful")
56
- return;
57
- const key = this.getAttribute("name") || this.getAttribute("id-for-color") || "sharepoint-ui";
58
- const hash = hashString(key);
59
- const rawColor = getComputedStyle(this).getPropertyValue("--spui-palette-theme-primary").trim()
60
- || getComputedStyle(this).getPropertyValue("--spui-ui-accent").trim()
61
- || "#78716c";
62
- const rgb = parseColor(rawColor);
63
- const shade = 0.18 + (hash % 5) * 0.1;
64
- const derived = rgb?.map(channel => Math.round(channel * (1 - shade)));
65
- const derivedColor = derived ? `#${derived.map(channel => channel.toString(16).padStart(2, "0")).join("")}` : rawColor;
66
- this.style.setProperty("--spui-avatar-colorful-background", derivedColor);
67
- this.style.setProperty("--spui-avatar-colorful-foreground", derived ? (relativeLuminance(derived) > 0.179 ? "#000000" : "#ffffff") : "var(--spui-semantic-primary-button-text, #ffffff)");
68
- }
69
- render() {
70
- const shadow = this.attachShadow({ mode: "open" });
71
- this.surface.className = "surface";
72
- this.surface.part.add("surface");
73
- this.image.className = "image";
74
- this.image.part.add("image");
75
- this.image.alt = "";
76
- this.image.loading = "lazy";
77
- this.image.decoding = "async";
78
- this.image.addEventListener("load", () => { this.dataset.imageState = "loaded"; });
79
- this.image.addEventListener("error", () => { this.dataset.imageState = "error"; });
80
- this.initials.className = "initials";
81
- this.initials.part.add("initials");
82
- this.fallback.className = "fallback";
83
- this.fallback.part.add("fallback");
84
- this.fallback.setAttribute("aria-hidden", "true");
85
- this.fallback.innerHTML = '<svg viewBox="0 0 24 24" focusable="false"><path d="M12 12a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9Zm0 2c-4.4 0-8 2.2-8 5v2h16v-2c0-2.8-3.6-5-8-5Z"/></svg>';
86
- this.surface.append(this.image, this.initials, this.fallback);
87
- const style = document.createElement("style");
88
- style.textContent = `${base}:host{--spui-avatar-size:32px;display:inline-grid;flex:none;width:var(--spui-avatar-size);height:var(--spui-avatar-size);vertical-align:middle;line-height:1}:host([size]){width:var(--spui-avatar-size);height:var(--spui-avatar-size)}.surface{position:relative;box-sizing:border-box;display:grid;place-items:center;width:100%;height:100%;overflow:hidden;border:1px solid var(--spui-avatar-border,var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1)));border-radius:var(--spui-avatar-radius,50%);background:var(--spui-avatar-background,var(--spui-semantic-body-subtext,var(--colorNeutralBackground3,#f0f0f0)));color:var(--spui-avatar-foreground,var(--spui-semantic-body-text,var(--colorNeutralForeground1,#323130)));font:600 calc(var(--spui-avatar-size) * .36)/1 var(--spui-font-family,inherit);user-select:none}.image{position:absolute;inset:0;z-index:1;width:100%;height:100%;object-fit:cover}.initials{position:absolute;inset:0;z-index:0;display:flex;align-items:center;justify-content:center;max-width:100%;overflow:hidden;padding:0 2px;text-align:center;line-height:1;white-space:nowrap}.fallback{z-index:0;display:grid;place-items:center;width:62%;height:62%;color:currentColor}.initials:not(:empty)~.fallback{display:none}.fallback svg{display:block;width:100%;height:100%;fill:currentColor}:host([data-image-state=loading]) .image,:host([data-image-state=error]) .image{visibility:hidden}:host([data-image-state=loaded]) .initials,:host([data-image-state=loaded]) .fallback{visibility:hidden}:host([shape=square]) .surface{border-radius:var(--spui-avatar-radius,var(--spui-control-radius,6px))}:host([color=brand]) .surface{background:var(--spui-avatar-brand-background,var(--spui-semantic-primary-button-background,var(--colorBrandBackground,var(--spui-avatar-active-color,var(--spui-ui-accent,#78716c)))));color:var(--spui-avatar-brand-foreground,var(--spui-semantic-primary-button-text,var(--colorNeutralForegroundOnBrand,#fff)))}:host([color=colorful]) .surface,:host([data-named-color]) .surface{background:var(--spui-avatar-colorful-background,var(--spui-semantic-primary-button-background,var(--colorBrandBackground,var(--spui-avatar-active-color,var(--spui-ui-accent,#78716c)))));color:var(--spui-avatar-colorful-foreground,var(--spui-semantic-primary-button-text,#fff))}:host([active=active]:not([active-appearance])) .surface,:host([active=active][active-appearance=ring]) .surface{box-shadow:0 0 0 2px var(--spui-ui-surface,#fff),0 0 0 4px var(--spui-avatar-active-color,var(--spui-ui-accent,#78716c))}:host([active=active][active-appearance=shadow]) .surface{box-shadow:var(--spui-avatar-active-shadow,var(--spui-card-shadow,0 2px 8px rgb(0 0 0 / 24%)))}:host([active=active][active-appearance=ring-shadow]) .surface{box-shadow:0 0 0 2px var(--spui-ui-surface,#fff),0 0 0 4px var(--spui-avatar-active-color,var(--spui-ui-accent,#78716c)),var(--spui-avatar-active-shadow,var(--spui-card-shadow,0 2px 8px rgb(0 0 0 / 24%)))}:host([active=inactive]){opacity:.56}:host([data-custom-icon=true]) .initials,:host([data-custom-icon=true]) .fallback{display:none}:host([data-custom-icon=true]) .icon{z-index:0;display:grid;place-items:center;width:70%;height:70%;color:inherit}:host([data-custom-badge=true]) .badge{position:absolute;z-index:2;inset-block-end:0;inset-inline-end:0;display:grid;place-items:center;min-width:var(--spui-avatar-badge-size,10px);min-height:var(--spui-avatar-badge-size,10px);border:2px solid var(--spui-avatar-badge-border,var(--spui-ui-surface,#fff));border-radius:50%;background:var(--spui-avatar-badge-background,var(--spui-semantic-success-background,#13a10e));color:var(--spui-avatar-badge-foreground,#fff);font:600 9px/1 var(--spui-font-family,inherit)}:host(:not([data-custom-badge=true])) .badge{display:none}@media(forced-colors:active){.surface{border-color:CanvasText;background:Canvas;color:CanvasText;forced-color-adjust:none}:host([data-named-color]) .surface{border-color:CanvasText;background:Canvas;color:CanvasText}.image{forced-color-adjust:auto}:host([active=active]) .surface{outline:2px solid Highlight;outline-offset:2px;box-shadow:none}}`;
89
- style.textContent += `.surface{background:var(--spui-avatar-background,var(--spui-palette-neutral-light,var(--colorNeutralBackground3,#f0f0f0)));font-size:clamp(10px,calc(var(--spui-avatar-size) * .36),48px)}`;
90
- style.textContent += `@media(forced-colors:active){.surface{border-color:CanvasText;background:Canvas;color:CanvasText}}`;
91
- const icon = document.createElement("span");
92
- icon.className = "icon";
93
- icon.part.add("icon");
94
- icon.append(document.createElement("slot"));
95
- icon.firstElementChild.setAttribute("name", "icon");
96
- const badge = document.createElement("span");
97
- badge.className = "badge";
98
- badge.part.add("badge");
99
- badge.append(document.createElement("slot"));
100
- badge.firstElementChild.setAttribute("name", "badge");
101
- const iconSlot = icon.firstElementChild;
102
- const badgeSlot = badge.firstElementChild;
103
- iconSlot.addEventListener("slotchange", () => this.toggleAttribute("data-custom-icon", iconSlot.assignedNodes({ flatten: true }).length > 0));
104
- badgeSlot.addEventListener("slotchange", () => this.toggleAttribute("data-custom-badge", badgeSlot.assignedNodes({ flatten: true }).length > 0));
105
- this.surface.append(icon, badge);
106
- shadow.append(style, this.surface);
107
- }
108
- sync() {
109
- if (!this.shadowRoot)
110
- return;
111
- const size = this.getAttribute("size")?.trim() || "32px";
112
- const normalizedSize = /^\d+(?:\.\d+)?$/.test(size) ? `${size}px` : size;
113
- this.style.setProperty("--spui-avatar-size", CSS.supports("width", normalizedSize) ? normalizedSize : "32px");
114
- const shape = this.getAttribute("shape") === "square" ? "square" : "circular";
115
- this.dataset.shape = shape;
116
- if (this.getAttribute("shape") !== shape)
117
- this.setAttribute("shape", shape);
118
- const color = this.getAttribute("color");
119
- if (!color || (!["neutral", "brand", "colorful"].includes(color) && !Object.hasOwn(namedColorTokens, color)))
120
- this.setAttribute("color", "neutral");
121
- const name = this.getAttribute("name")?.trim() ?? "";
122
- const locale = this.closest("[lang]")?.getAttribute("lang") || this.ownerDocument.documentElement.lang || undefined;
123
- const initials = this.getAttribute("initials")?.trim() || getInitials(name, Number.parseFloat(this.style.getPropertyValue("--spui-avatar-size")), locale, getComputedStyle(this).direction === "rtl");
124
- this.initials.textContent = initials;
125
- const source = this.getAttribute("image")?.trim() ?? "";
126
- if (source !== this.imageSource) {
127
- this.imageSource = source;
128
- if (source) {
129
- this.setAttribute("data-image-state", "loading");
130
- this.image.src = source;
131
- }
132
- else {
133
- this.image.removeAttribute("src");
134
- this.setAttribute("data-image-state", "none");
135
- }
136
- }
137
- else if (source && !this.dataset.imageState)
138
- this.setAttribute("data-image-state", "loading");
139
- const decorative = this.hasAttribute("decorative");
140
- const hasExplicitName = (this.hasAttribute("aria-label") && this.dataset.autoLabel === undefined) || this.hasAttribute("aria-labelledby");
141
- const accessibleName = name || initials;
142
- if (decorative || (!hasExplicitName && !accessibleName)) {
143
- if (this.dataset.autoLabel !== undefined) {
144
- this.removeAttribute("aria-label");
145
- delete this.dataset.autoLabel;
146
- }
147
- if (!this.hasAttribute("aria-hidden")) {
148
- this.setAttribute("aria-hidden", "true");
149
- this.dataset.autoHidden = "";
150
- }
151
- if (!this.hasAttribute("role")) {
152
- this.setAttribute("role", "presentation");
153
- this.dataset.autoRole = "";
154
- }
155
- }
156
- else {
157
- if (this.dataset.autoHidden !== undefined) {
158
- this.removeAttribute("aria-hidden");
159
- delete this.dataset.autoHidden;
160
- }
161
- if (this.dataset.autoRole !== undefined) {
162
- this.removeAttribute("role");
163
- delete this.dataset.autoRole;
164
- }
165
- if (!this.hasAttribute("role")) {
166
- this.setAttribute("role", "img");
167
- this.dataset.autoRole = "";
168
- }
169
- if (!this.hasAttribute("aria-labelledby") && (!this.hasAttribute("aria-label") || this.dataset.autoLabel !== undefined)) {
170
- this.setAttribute("aria-label", accessibleName);
171
- this.dataset.autoLabel = "";
172
- }
173
- }
174
- this.refreshThemeColor();
175
- }
176
- watchTheme() {
177
- if (this.getAttribute("color") !== "colorful" || !this.isConnected)
178
- return;
179
- const root = this.closest("[data-spui-appearance]");
180
- if (!root)
181
- return;
182
- this.unwatchTheme();
183
- this.themeRoot = root;
184
- let watch = themeWatches.get(root);
185
- if (!watch) {
186
- const instances = new Set();
187
- const observer = new MutationObserver(() => instances.forEach(avatar => avatar.refreshThemeColor()));
188
- observer.observe(root, { attributes: true, attributeFilter: ["style"] });
189
- watch = { instances, observer };
190
- themeWatches.set(root, watch);
191
- }
192
- watch.instances.add(this);
193
- }
194
- unwatchTheme() {
195
- if (!this.themeRoot)
196
- return;
197
- const watch = themeWatches.get(this.themeRoot);
198
- watch?.instances.delete(this);
199
- if (watch && watch.instances.size === 0) {
200
- watch.observer.disconnect();
201
- themeWatches.delete(this.themeRoot);
202
- }
203
- this.themeRoot = undefined;
204
- }
205
- }
206
- customElements.define("spui-avatar", SpuiAvatar);
207
- }
208
- function getInitials(name, size, locale, rtl = false) {
209
- const words = name.replace(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, " ").trim().split(/\s+/).filter(Boolean);
210
- if (!words.length)
211
- return "";
212
- const selectedWords = size <= 20 ? [words[0]] : words.length === 2 ? words : words.length === 3 ? [words[0], words[2]] : [words[0]];
213
- let initials = selectedWords.map(word => firstGrapheme(word, locale)).join("");
214
- try {
215
- initials = initials.toLocaleUpperCase(locale);
216
- }
217
- catch {
218
- initials = initials.toUpperCase();
219
- }
220
- const characters = Array.from(initials);
221
- return rtl && characters.length > 1 ? characters.reverse().join("") : initials;
222
- }
223
- function firstGrapheme(value, locale) {
224
- const Segmenter = Intl.Segmenter;
225
- if (Segmenter) {
226
- try {
227
- return [...new Segmenter(locale, { granularity: "grapheme" }).segment(value)][0]?.segment ?? "";
228
- }
229
- catch { /* Fall through for unsupported locale tags or older engines. */ }
230
- }
231
- return Array.from(value.normalize("NFC"))[0] ?? "";
232
- }
233
- function hashString(value) {
234
- let hash = 2166136261;
235
- for (const character of value)
236
- hash = Math.imul(hash ^ character.codePointAt(0), 16777619);
237
- return hash >>> 0;
238
- }
239
- function parseColor(value) {
240
- const hex = /^#([\da-f]{3}|[\da-f]{6})$/i.exec(value);
241
- if (hex) {
242
- const expanded = hex[1].length === 3 ? [...hex[1]].map(character => character + character).join("") : hex[1];
243
- return [0, 2, 4].map(index => parseInt(expanded.slice(index, index + 2), 16));
244
- }
245
- const rgb = /^rgba?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)/i.exec(value);
246
- return rgb ? [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])] : null;
247
- }
248
- function relativeLuminance([red, green, blue]) {
249
- const linear = (channel) => { const value = channel / 255; return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4; };
250
- return linear(red) * 0.2126 + linear(green) * 0.7152 + linear(blue) * 0.0722;
251
- }
@@ -1,8 +0,0 @@
1
- export type BadgeAppearance = "filled" | "ghost" | "outline" | "tint";
2
- export type BadgeColor = "brand" | "danger" | "important" | "informative" | "severe" | "subtle" | "success" | "warning";
3
- export type BadgeShape = "circular" | "rounded" | "square";
4
- export type BadgeSize = "tiny" | "extra-small" | "small" | "medium" | "large" | "extra-large";
5
- export type PresenceBadgeStatus = "busy" | "out-of-office" | "away" | "available" | "offline" | "do-not-disturb" | "unknown" | "blocked";
6
- export declare function defineBadge(): void;
7
- export declare function defineCounterBadge(): void;
8
- export declare function definePresenceBadge(): void;
@@ -1,182 +0,0 @@
1
- import { base } from "./shared.js";
2
- const badgeStyle = `${base}
3
- :host{--badge-size:20px;--badge-pad:6px;--badge-status:var(--spui-ui-accent,var(--colorBrandBackground,#0078d4));--badge-filled-background:var(--spui-ui-accent,var(--colorBrandBackground,#0078d4));--badge-filled-foreground:var(--spui-ui-accent-text,#fff);--badge-filled-border:var(--colorTransparentStroke,transparent);--badge-tint-background:color-mix(in srgb,var(--badge-status) 12%,var(--spui-ui-surface,#fff));--badge-tint-foreground:var(--badge-status);--badge-tint-border:var(--badge-outline-border);--badge-outline-border:var(--badge-status);display:inline-flex;align-items:center;justify-content:center;gap:4px;box-sizing:border-box;min-width:var(--badge-size);min-height:var(--badge-size);padding-inline:var(--badge-pad);border:1px solid var(--badge-outline-border);border-radius:999px;background:var(--badge-filled-background);color:var(--badge-filled-foreground);font:600 12px/1 var(--spui-font-family,inherit);white-space:nowrap;vertical-align:middle}
4
- :host([color=success]){--badge-status:var(--spui-ui-success,#107c10);--badge-color:var(--spui-ui-success-surface,#dff6dd);--badge-foreground:var(--badge-status);--badge-tint:var(--spui-ui-success-surface,#dff6dd)}
5
- :host([color=warning]),:host([color=important]){--badge-status:var(--spui-ui-warning,#835b00);--badge-color:var(--spui-ui-warning-surface,#fff4ce);--badge-foreground:var(--badge-status);--badge-tint:var(--spui-ui-warning-surface,#fff4ce)}
6
- :host([color=danger]),:host([color=severe]){--badge-status:var(--spui-ui-danger,#b10e1c);--badge-color:var(--spui-ui-danger-surface,#fde7e9);--badge-foreground:var(--badge-status);--badge-tint:var(--spui-ui-danger-surface,#fde7e9)}
7
- :host([color=informative]){--badge-status:var(--spui-ui-accent,#0078d4);--badge-color:var(--spui-ui-accent,var(--colorBrandBackground,#0078d4));--badge-tint:color-mix(in srgb,var(--badge-status) 12%,var(--spui-ui-surface,#fff))}
8
- :host([color=subtle]){--badge-status:var(--spui-ui-muted,#616161);--badge-color:color-mix(in srgb,var(--spui-ui-stroke,#d1d1d1) 25%,var(--spui-ui-surface,#fff));--badge-foreground:var(--spui-ui-text,#242424);--badge-tint:var(--badge-color)}
9
- :host([color=brand]){--badge-filled-background:var(--colorBrandBackground,var(--spui-ui-accent,#0078d4));--badge-filled-foreground:var(--colorNeutralForegroundOnBrand,var(--spui-ui-accent-text,#fff));--badge-status:var(--colorBrandForeground1,var(--spui-ui-accent,#0078d4));--badge-tint-background:var(--colorBrandBackground2,color-mix(in srgb,var(--badge-status) 12%,var(--spui-ui-surface,#fff)));--badge-tint-foreground:var(--colorBrandForeground2,var(--badge-status));--badge-tint-border:var(--colorBrandStroke2,var(--badge-status));--badge-outline-border:var(--badge-status)}
10
- :host([color=danger]){--badge-filled-background:var(--colorPaletteRedBackground3,color-mix(in srgb,var(--spui-ui-danger,#b10e1c) 85%,black));--badge-filled-foreground:var(--colorNeutralForegroundOnBrand,#fff);--badge-status:var(--colorPaletteRedForeground3,var(--spui-ui-danger,#b10e1c));--badge-tint-background:var(--colorPaletteRedBackground1,var(--spui-ui-danger-surface,#fde7e9));--badge-tint-foreground:var(--colorPaletteRedForeground1,var(--spui-ui-danger,#b10e1c));--badge-tint-border:var(--colorPaletteRedBorder1,var(--badge-status));--badge-outline-border:var(--colorPaletteRedBorder2,var(--badge-status))}
11
- :host([color=severe]){--badge-filled-background:var(--colorPaletteDarkOrangeBackground3,color-mix(in srgb,var(--spui-ui-warning,#835b00) 88%,black));--badge-filled-foreground:var(--colorNeutralForegroundOnBrand,#fff);--badge-status:var(--colorPaletteDarkOrangeForeground3,var(--spui-ui-warning,#835b00));--badge-tint-background:var(--colorPaletteDarkOrangeBackground1,var(--spui-ui-warning-surface,#fff4ce));--badge-tint-foreground:var(--colorPaletteDarkOrangeForeground1,var(--spui-ui-warning,#835b00));--badge-tint-border:var(--colorPaletteDarkOrangeBorder1,var(--badge-status));--badge-outline-border:var(--badge-status)}
12
- :host([color=success]){--badge-filled-background:var(--colorPaletteGreenBackground3,color-mix(in srgb,var(--spui-ui-success,#107c10) 85%,black));--badge-filled-foreground:var(--colorNeutralForegroundOnBrand,#fff);--badge-status:var(--colorPaletteGreenForeground3,var(--spui-ui-success,#107c10));--badge-tint-background:var(--colorPaletteGreenBackground1,var(--spui-ui-success-surface,#dff6dd));--badge-tint-foreground:var(--colorPaletteGreenForeground1,var(--spui-ui-success,#107c10));--badge-tint-border:var(--colorPaletteGreenBorder1,var(--badge-status));--badge-outline-border:var(--colorPaletteGreenBorder2,var(--badge-status))}
13
- :host([color=warning]){--badge-filled-background:var(--colorPaletteYellowBackground3,color-mix(in srgb,var(--spui-ui-warning,#835b00) 82%,black));--badge-filled-foreground:var(--colorNeutralForeground1Static,#242424);--badge-status:var(--colorPaletteYellowForeground2,var(--spui-ui-warning,#835b00));--badge-tint-background:var(--colorPaletteYellowBackground1,var(--spui-ui-warning-surface,#fff4ce));--badge-tint-foreground:var(--colorPaletteYellowForeground1,var(--spui-ui-warning,#835b00));--badge-tint-border:var(--colorPaletteYellowBorder1,var(--badge-status));--badge-outline-border:var(--badge-status)}
14
- :host([color=important]){--badge-filled-background:var(--colorNeutralForeground1,#242424);--badge-filled-foreground:var(--colorNeutralBackground1,#fff);--badge-status:var(--colorNeutralForeground1,#242424);--badge-tint-background:var(--colorNeutralForeground3,#616161);--badge-tint-foreground:var(--colorNeutralBackground1,#fff);--badge-tint-border:var(--colorTransparentStroke,transparent);--badge-outline-border:var(--colorNeutralStrokeAccessible,#616161)}
15
- :host([color=informative]){--badge-filled-background:var(--colorNeutralBackground5,#e0e0e0);--badge-filled-foreground:var(--colorNeutralForeground3,#616161);--badge-status:var(--colorNeutralForeground3,#616161);--badge-tint-background:var(--colorNeutralBackground4,#f0f0f0);--badge-tint-foreground:var(--colorNeutralForeground3,#616161);--badge-tint-border:var(--colorNeutralStroke2,#d1d1d1);--badge-outline-border:var(--colorNeutralStroke2,#d1d1d1)}
16
- :host([color=subtle]){--badge-filled-background:var(--colorNeutralBackground1,var(--spui-ui-surface,#fff));--badge-filled-foreground:var(--colorNeutralForeground1,var(--spui-ui-text,#242424));--badge-status:var(--colorNeutralForegroundStaticInverted,#fff);--badge-tint-background:var(--colorNeutralBackground1,var(--spui-ui-surface,#fff));--badge-tint-foreground:var(--colorNeutralForeground3,var(--spui-ui-muted,#616161));--badge-tint-border:var(--colorNeutralStroke2,var(--spui-ui-stroke,#d1d1d1));--badge-outline-border:var(--badge-status)}
17
- :host([color=brand]){--badge-outline-foreground:var(--colorBrandForeground1,var(--spui-ui-accent,#0078d4))}:host([color=danger]){--badge-outline-foreground:var(--colorPaletteRedForeground3,var(--spui-ui-danger,#b10e1c))}:host([color=important]){--badge-outline-foreground:var(--colorNeutralForeground3,#616161)}:host([color=informative]){--badge-outline-foreground:var(--colorNeutralForeground3,#616161)}:host([color=severe]){--badge-outline-foreground:var(--colorPaletteDarkOrangeForeground3,var(--spui-ui-warning,#835b00))}:host([color=subtle]){--badge-outline-foreground:var(--colorNeutralForegroundStaticInverted,#fff)}:host([color=success]){--badge-outline-foreground:var(--colorPaletteGreenForeground3,var(--spui-ui-success,#107c10))}:host([color=warning]){--badge-outline-foreground:var(--colorPaletteYellowForeground2,var(--spui-ui-warning,#835b00))}
18
- :host([appearance=ghost]){border-color:transparent;background:transparent;color:var(--badge-status)}
19
- :host([appearance=outline]){background:transparent;color:var(--badge-outline-foreground,var(--badge-status))}
20
- :host([appearance=filled]){border-color:var(--badge-filled-border)}:host([appearance=ghost]){border-color:transparent}:host([appearance=outline]){border-color:var(--badge-outline-border)}:host([appearance=tint]){border-color:var(--badge-tint-border);background:var(--badge-tint-background);color:var(--badge-tint-foreground)}
21
- :host([shape=rounded]){border-radius:6px}:host([shape=square]){border-radius:2px}:host([shape=circular]){border-radius:999px}
22
- :host([size=tiny]){--badge-size:6px;--badge-pad:0;width:6px;min-width:0;min-height:0;height:6px;padding:0;font-size:4px}:host([size=extra-small]){--badge-size:10px;--badge-pad:0;width:10px;min-width:0;min-height:0;height:10px;padding:0;font-size:6px}:host([size=small]){--badge-size:16px;--badge-pad:4px;font-size:10px}:host([size=large]){--badge-size:24px;--badge-pad:7px;font-size:14px}:host([size=extra-large]){--badge-size:32px;--badge-pad:9px;font-size:16px}
23
- .content{display:inline-flex;align-items:center;justify-content:center;order:1}.icon{display:inline-flex;align-items:center;justify-content:center;order:0;line-height:0}slot[name=icon]{display:contents}
24
- :host([icon-position=after]) .icon{order:2}:host([icon-position=after]) .content{order:1}
25
- :host([dot]){width:var(--badge-size);min-width:var(--badge-size);padding:0}:host([dot]) .content,:host([dot]) .icon{display:none}:host([hidden]){display:none}
26
- :host([kind=presence]){position:relative;width:var(--badge-size);min-width:var(--badge-size);padding:0;border-width:1px;background:var(--badge-color)}
27
- :host([kind=presence]){background:var(--colorNeutralBackground1,var(--spui-ui-surface,#fff));border-color:var(--colorTransparentStroke,transparent);color:var(--badge-status)}:host([kind=presence][status=available]){--badge-status:var(--colorPaletteLightGreenForeground3,var(--spui-ui-success,#13a10e))}:host([kind=presence][status=away]){--badge-status:var(--colorPaletteMarigoldBackground3,var(--spui-ui-warning,#835b00))}:host([kind=presence][status=busy]),:host([kind=presence][status=do-not-disturb]),:host([kind=presence][status=blocked]){--badge-status:var(--colorPaletteRedBackground3,var(--spui-ui-danger,#c50f1f))}:host([kind=presence][status=out-of-office]){--badge-status:var(--colorPaletteBerryForeground3,var(--spui-ui-danger,#c50f1f))}:host([kind=presence][status=offline]),:host([kind=presence][status=unknown]){--badge-status:var(--colorNeutralForeground3,var(--spui-ui-muted,#616161))}
28
- :host([kind=presence][status=available]){--badge-color:var(--spui-ui-success-surface,#dff6dd);--badge-foreground:var(--spui-ui-success,#107c10)}
29
- :host([kind=presence][status=away]){--badge-color:var(--spui-ui-warning-surface,#fff4ce);--badge-foreground:var(--spui-ui-warning,#835b00)}
30
- :host([kind=presence][status=busy]),:host([kind=presence][status=do-not-disturb]),:host([kind=presence][status=blocked]),:host([kind=presence][status=out-of-office]){--badge-color:var(--spui-ui-danger-surface,#fde7e9);--badge-foreground:var(--spui-ui-danger,#b10e1c)}
31
- :host([kind=presence][status=offline]),:host([kind=presence][status=unknown]){--badge-color:color-mix(in srgb,var(--spui-ui-stroke,#d1d1d1) 25%,var(--spui-ui-surface,#fff));--badge-foreground:var(--spui-ui-muted,#616161)}
32
- .icon svg{display:block;width:100%;height:100%}:host([kind=presence]) .icon{width:68%;height:68%}
33
- @media(forced-colors:active){:host{border-color:CanvasText}:host([appearance=ghost]),:host([appearance=tint]){color:CanvasText}:host([kind=presence]){background:Canvas;color:CanvasText;border-color:CanvasText}}
34
- @media(prefers-reduced-motion:reduce){:host{transition:none}}`;
35
- function presenceIcon(status, outOfOffice) {
36
- const ns = "http://www.w3.org/2000/svg";
37
- const svg = document.createElementNS(ns, "svg");
38
- svg.setAttribute("viewBox", "0 0 16 16");
39
- svg.setAttribute("aria-hidden", "true");
40
- svg.setAttribute("focusable", "false");
41
- const shape = (name, attributes) => {
42
- const element = document.createElementNS(ns, name);
43
- for (const [key, value] of Object.entries(attributes))
44
- element.setAttribute(key, value);
45
- svg.append(element);
46
- };
47
- const stroke = { fill: "none", stroke: "currentColor", "stroke-width": "1.6", "stroke-linecap": "round", "stroke-linejoin": "round" };
48
- if (status === "available")
49
- shape("path", { ...stroke, d: "M3.4 8.2 6.5 11.3 12.8 4.9" });
50
- else if (status === "away") {
51
- shape("circle", { ...stroke, cx: "8", cy: "8", r: "5.4" });
52
- shape("path", { ...stroke, d: "M8 4.8V8l2.3 1.5" });
53
- }
54
- else if (status === "busy")
55
- shape("circle", { cx: "8", cy: "8", r: "4.7", fill: "currentColor" });
56
- else if (status === "do-not-disturb") {
57
- shape("circle", { ...stroke, cx: "8", cy: "8", r: "5.4" });
58
- shape("path", { ...stroke, d: "M5.2 8h5.6" });
59
- }
60
- else if (status === "offline")
61
- shape("circle", { ...stroke, cx: "8", cy: "8", r: "5.1" });
62
- else if (status === "blocked") {
63
- shape("circle", { ...stroke, cx: "8", cy: "8", r: "5.2" });
64
- shape("path", { ...stroke, d: "m4.3 11.7 7.4-7.4" });
65
- }
66
- else if (status === "out-of-office") {
67
- shape("path", { ...stroke, d: "M3.5 13.2V4.5l4.5-2 4.5 2v8.7M2.5 13.2h11M6 6.2h.1M9.9 6.2h.1M7.2 13.1V9.8h1.6v3.3" });
68
- }
69
- else {
70
- shape("path", { ...stroke, d: "M5.8 5.7a2.3 2.3 0 1 1 3.8 1.7c-1 .8-1.6 1.1-1.6 2.3" });
71
- shape("circle", { cx: "8", cy: "12.3", r: ".5", fill: "currentColor" });
72
- }
73
- if (outOfOffice && status !== "out-of-office") {
74
- shape("circle", { cx: "12.1", cy: "12.1", r: "3.25", fill: "var(--spui-ui-surface,#fff)", stroke: "var(--spui-ui-danger,#b10e1c)", "stroke-width": ".75" });
75
- shape("path", { d: "M10.7 13.4v-2.7h2.8v2.7m-1.9-2.7v.9m1-.9v.9", fill: "none", stroke: "var(--spui-ui-danger,#b10e1c)", "stroke-width": ".55", "stroke-linecap": "round", "stroke-linejoin": "round" });
76
- }
77
- return svg;
78
- }
79
- function renderBadge(host, shadow, options) {
80
- const style = document.createElement("style");
81
- style.textContent = badgeStyle;
82
- const content = document.createElement("span");
83
- content.className = "content";
84
- content.part.add("content");
85
- const defaultSlot = document.createElement("slot");
86
- if (options.content !== undefined)
87
- content.textContent = options.content;
88
- else
89
- content.append(defaultSlot);
90
- const icon = document.createElement("span");
91
- icon.className = "icon";
92
- icon.part.add("icon");
93
- const iconSlot = document.createElement("slot");
94
- iconSlot.name = "icon";
95
- if (options.icon && !host.querySelector('[slot="icon"]'))
96
- icon.append(options.icon);
97
- else
98
- icon.append(iconSlot);
99
- shadow.replaceChildren(style, icon, content);
100
- if (options.presence) {
101
- const status = host.getAttribute("status") ?? "available";
102
- if (host.getAttribute("role") !== "img")
103
- host.setAttribute("role", "img");
104
- }
105
- }
106
- export function defineBadge() {
107
- if (customElements.get("spui-badge"))
108
- return;
109
- class SpuiBadge extends HTMLElement {
110
- static observedAttributes = ["appearance", "color", "icon-position", "shape", "size"];
111
- connectedCallback() { if (!this.shadowRoot)
112
- this.render(); }
113
- attributeChangedCallback() { if (this.isConnected)
114
- this.render(); }
115
- render() { renderBadge(this, this.shadowRoot ?? this.attachShadow({ mode: "open" }), {}); }
116
- }
117
- customElements.define("spui-badge", SpuiBadge);
118
- }
119
- export function defineCounterBadge() {
120
- if (customElements.get("spui-counter-badge"))
121
- return;
122
- class SpuiCounterBadge extends HTMLElement {
123
- static observedAttributes = ["appearance", "aria-label", "color", "count", "dot", "overflow-count", "shape", "show-zero", "size"];
124
- generatedLabel;
125
- customLabel = false;
126
- connectedCallback() { this.render(); }
127
- attributeChangedCallback(name, _oldValue, newValue) {
128
- if (name === "aria-label")
129
- this.customLabel = newValue !== null && newValue !== this.generatedLabel;
130
- if (this.isConnected)
131
- this.render();
132
- }
133
- render() {
134
- const parsedCount = Number(this.getAttribute("count") ?? 0);
135
- const parsedMax = Number(this.getAttribute("overflow-count") ?? 99);
136
- const count = Number.isFinite(parsedCount) ? Math.max(0, parsedCount) : 0;
137
- const max = Number.isFinite(parsedMax) ? Math.max(0, parsedMax) : 99;
138
- const dot = this.hasAttribute("dot");
139
- const visible = dot || count > 0 || this.hasAttribute("show-zero");
140
- this.toggleAttribute("hidden", !visible);
141
- if (!dot && !this.customLabel) {
142
- const label = `${count > max ? `${max}+` : count}`;
143
- this.generatedLabel = label;
144
- if (this.getAttribute("aria-label") !== label)
145
- this.setAttribute("aria-label", label);
146
- }
147
- this.setAttribute("kind", "counter");
148
- const content = dot ? undefined : String(count > max ? `${max}+` : count);
149
- renderBadge(this, this.shadowRoot ?? this.attachShadow({ mode: "open" }), { content });
150
- }
151
- }
152
- customElements.define("spui-counter-badge", SpuiCounterBadge);
153
- }
154
- export function definePresenceBadge() {
155
- if (customElements.get("spui-presence-badge"))
156
- return;
157
- class SpuiPresenceBadge extends HTMLElement {
158
- static observedAttributes = ["out-of-office", "size", "status", "aria-label"];
159
- generatedLabel;
160
- customLabel = false;
161
- connectedCallback() { this.render(); }
162
- attributeChangedCallback(name, _oldValue, newValue) {
163
- if (name === "aria-label")
164
- this.customLabel = newValue !== null && newValue !== this.generatedLabel;
165
- if (this.isConnected)
166
- this.render();
167
- }
168
- render() {
169
- this.setAttribute("kind", "presence");
170
- const status = this.getAttribute("status") ?? "available";
171
- if (!this.customLabel) {
172
- const status = this.getAttribute("status") ?? "available";
173
- const label = `${status.replaceAll("-", " ")}${this.hasAttribute("out-of-office") && status !== "out-of-office" ? ", out of office" : ""}`;
174
- this.generatedLabel = label;
175
- if (this.getAttribute("aria-label") !== label)
176
- this.setAttribute("aria-label", label);
177
- }
178
- renderBadge(this, this.shadowRoot ?? this.attachShadow({ mode: "open" }), { icon: presenceIcon(status, this.hasAttribute("out-of-office")), presence: true });
179
- }
180
- }
181
- customElements.define("spui-presence-badge", SpuiPresenceBadge);
182
- }
@@ -1,4 +0,0 @@
1
- export declare function defineBreadcrumb(): void;
2
- export declare function defineBreadcrumbItem(): void;
3
- export declare function defineBreadcrumbDivider(): void;
4
- export declare function defineBreadcrumbButton(): void;