fluentui-svelte 0.6.0 → 0.7.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 (243) hide show
  1. package/dist/components/app-surface/app-surface.svelte +96 -0
  2. package/dist/components/app-surface/app-surface.svelte.d.ts +22 -0
  3. package/dist/components/app-surface/docs/llms.md +73 -0
  4. package/dist/components/app-surface/types.d.ts +19 -0
  5. package/dist/components/app-surface/types.js +1 -0
  6. package/dist/components/app-window/app-window.d.ts +3 -0
  7. package/dist/components/app-window/app-window.js +3 -0
  8. package/dist/components/app-window/app-window.svelte +193 -0
  9. package/dist/components/app-window/app-window.svelte.d.ts +25 -0
  10. package/dist/components/app-window/docs/llms.md +119 -0
  11. package/dist/components/app-window/types.d.ts +66 -0
  12. package/dist/components/app-window/types.js +1 -0
  13. package/dist/components/auto-suggest-box/auto-suggest-box.svelte +47 -31
  14. package/dist/components/auto-suggest-box/auto-suggest-box.svelte.d.ts +2 -2
  15. package/dist/components/auto-suggest-box/docs/llms.md +34 -33
  16. package/dist/components/auto-suggest-box/option.svelte +6 -4
  17. package/dist/components/auto-suggest-box/types.d.ts +13 -16
  18. package/dist/components/avatar/avatar.svelte +4 -3
  19. package/dist/components/avatar/docs/llms.md +1 -1
  20. package/dist/components/avatar/type.d.ts +1 -1
  21. package/dist/components/badge/badge-icon.svelte +2 -2
  22. package/dist/components/badge/badge.svelte +2 -2
  23. package/dist/components/badge/docs/llms.md +2 -2
  24. package/dist/components/badge/types.d.ts +2 -2
  25. package/dist/components/breadcrumb/breadcrumb-button.svelte +2 -2
  26. package/dist/components/breadcrumb/breadcrumb-divider.svelte +2 -2
  27. package/dist/components/breadcrumb/breadcrumb-item.svelte +2 -2
  28. package/dist/components/breadcrumb/breadcrumb.svelte +10 -5
  29. package/dist/components/breadcrumb/docs/llms.md +11 -11
  30. package/dist/components/breadcrumb/types.d.ts +7 -7
  31. package/dist/components/button/button.svelte +2 -2
  32. package/dist/components/button/docs/llms.md +17 -17
  33. package/dist/components/button/split-button.svelte +7 -7
  34. package/dist/components/button/types.d.ts +5 -5
  35. package/dist/components/calendar-date-picker/calendar-date-picker.svelte +98 -10
  36. package/dist/components/calendar-date-picker/calendar-date-picker.svelte.d.ts +1 -1
  37. package/dist/components/calendar-date-picker/docs/llms.md +19 -14
  38. package/dist/components/calendar-date-picker/types.d.ts +22 -8
  39. package/dist/components/calendar-view/calendar-view-days.svelte +3 -2
  40. package/dist/components/calendar-view/calendar-view-grid.js +8 -3
  41. package/dist/components/calendar-view/calendar-view-item.svelte +10 -4
  42. package/dist/components/calendar-view/calendar-view-months.svelte +3 -2
  43. package/dist/components/calendar-view/calendar-view-years.svelte +3 -2
  44. package/dist/components/calendar-view/calendar-view.svelte +11 -4
  45. package/dist/components/calendar-view/calendar-view.svelte.js +5 -0
  46. package/dist/components/calendar-view/docs/llms.md +20 -19
  47. package/dist/components/calendar-view/types.d.ts +6 -1
  48. package/dist/components/card/card-footer.svelte +2 -2
  49. package/dist/components/card/card-header.svelte +5 -4
  50. package/dist/components/card/card-preview.svelte +13 -2
  51. package/dist/components/card/card.svelte +5 -5
  52. package/dist/components/card/docs/llms.md +22 -21
  53. package/dist/components/card/types.d.ts +8 -4
  54. package/dist/components/checkbox/checkbox.svelte +47 -26
  55. package/dist/components/checkbox/checkbox.svelte.d.ts +3 -24
  56. package/dist/components/checkbox/docs/llms.md +24 -23
  57. package/dist/components/checkbox/types.d.ts +10 -23
  58. package/dist/components/date-picker/date-picker.svelte +98 -27
  59. package/dist/components/date-picker/date-picker.svelte.d.ts +1 -1
  60. package/dist/components/date-picker/docs/llms.md +23 -20
  61. package/dist/components/date-picker/types.d.ts +24 -15
  62. package/dist/components/dialog/dialog-actions.svelte +2 -2
  63. package/dist/components/dialog/dialog-content.svelte +2 -2
  64. package/dist/components/dialog/dialog-surface.svelte +102 -9
  65. package/dist/components/dialog/dialog-title.svelte +2 -2
  66. package/dist/components/dialog/dialog-trigger.svelte +2 -2
  67. package/dist/components/dialog/dialog.svelte +22 -11
  68. package/dist/components/dialog/docs/llms.md +56 -19
  69. package/dist/components/dialog/types.d.ts +25 -7
  70. package/dist/components/divider/divider.svelte +6 -4
  71. package/dist/components/divider/types.d.ts +1 -1
  72. package/dist/components/dropdown/docs/llms.md +30 -28
  73. package/dist/components/dropdown/dropdown-option.svelte +17 -5
  74. package/dist/components/dropdown/dropdown.svelte +182 -84
  75. package/dist/components/dropdown/dropdown.svelte.d.ts +1 -1
  76. package/dist/components/dropdown/types.d.ts +26 -20
  77. package/dist/components/dropdown-select/docs/llms.md +24 -22
  78. package/dist/components/dropdown-select/dropdown-select-option.svelte +2 -2
  79. package/dist/components/dropdown-select/dropdown-select.svelte +42 -7
  80. package/dist/components/dropdown-select/types.d.ts +4 -4
  81. package/dist/components/expander/docs/llms.md +3 -3
  82. package/dist/components/expander/expander.svelte +13 -8
  83. package/dist/components/expander/types.d.ts +5 -5
  84. package/dist/components/flyout/docs/llms.md +1 -1
  85. package/dist/components/flyout/flyout.svelte +17 -6
  86. package/dist/components/flyout/types.d.ts +1 -1
  87. package/dist/components/hyperlink/docs/llms.md +6 -6
  88. package/dist/components/hyperlink/hyperlink.svelte +13 -4
  89. package/dist/components/hyperlink/types.d.ts +1 -1
  90. package/dist/components/info-bar/docs/llms.md +11 -10
  91. package/dist/components/info-bar/info-bar.svelte +3 -2
  92. package/dist/components/info-bar/types.d.ts +4 -0
  93. package/dist/components/label/docs/llms.md +75 -22
  94. package/dist/components/label/label-context.d.ts +14 -0
  95. package/dist/components/label/label-context.js +10 -0
  96. package/dist/components/label/label.svelte +153 -30
  97. package/dist/components/label/label.svelte.d.ts +1 -1
  98. package/dist/components/label/types.d.ts +48 -4
  99. package/dist/components/list-view/docs/llms.md +103 -33
  100. package/dist/components/list-view/list-view-item-branch.svelte +257 -0
  101. package/dist/components/list-view/list-view-item-branch.svelte.d.ts +4 -0
  102. package/dist/components/list-view/list-view-item.svelte +164 -46
  103. package/dist/components/list-view/list-view-item.svelte.d.ts +5 -5
  104. package/dist/components/list-view/list-view.svelte +73 -25
  105. package/dist/components/list-view/types.d.ts +71 -8
  106. package/dist/components/list-view/utils.d.ts +10 -0
  107. package/dist/components/list-view/utils.js +17 -1
  108. package/dist/components/menu/docs/llms.md +98 -15
  109. package/dist/components/menu/menu-command-bar-item.svelte +61 -0
  110. package/dist/components/menu/menu-command-bar-item.svelte.d.ts +14 -0
  111. package/dist/components/menu/menu-command-bar.svelte +218 -0
  112. package/dist/components/menu/menu-command-bar.svelte.d.ts +21 -0
  113. package/dist/components/menu/menu-group.svelte +6 -3
  114. package/dist/components/menu/menu-item-checkbox.svelte +5 -4
  115. package/dist/components/menu/menu-item-radio.svelte +5 -4
  116. package/dist/components/menu/menu-item-switch.svelte +5 -4
  117. package/dist/components/menu/menu-item.svelte +5 -5
  118. package/dist/components/menu/menu-item.svelte.d.ts +2 -3
  119. package/dist/components/menu/menu-list.svelte +10 -1
  120. package/dist/components/menu/menu-popover.svelte +9 -5
  121. package/dist/components/menu/menu-trigger.svelte +2 -1
  122. package/dist/components/menu/menu.svelte.js +1 -0
  123. package/dist/components/menu/types.d.ts +62 -7
  124. package/dist/components/number-box/docs/llms.md +6 -4
  125. package/dist/components/number-box/number-box.svelte +35 -29
  126. package/dist/components/number-box/number-box.svelte.d.ts +1 -1
  127. package/dist/components/number-box/types.d.ts +1 -1
  128. package/dist/components/persona/docs/llms.md +29 -25
  129. package/dist/components/persona/persona.svelte +8 -6
  130. package/dist/components/persona/types.d.ts +4 -3
  131. package/dist/components/progress-bar/docs/llms.md +13 -13
  132. package/dist/components/progress-bar/progress-bar.svelte +6 -6
  133. package/dist/components/progress-bar/types.d.ts +4 -4
  134. package/dist/components/progress-ring/docs/llms.md +14 -14
  135. package/dist/components/progress-ring/progress-ring.svelte +5 -5
  136. package/dist/components/progress-ring/types.d.ts +3 -3
  137. package/dist/components/radio-button/docs/llms.md +11 -8
  138. package/dist/components/radio-button/radio-button.svelte +38 -12
  139. package/dist/components/radio-button/radio-button.svelte.d.ts +1 -1
  140. package/dist/components/radio-button/types.d.ts +11 -8
  141. package/dist/components/rating/docs/llms.md +15 -14
  142. package/dist/components/rating/rating.svelte +66 -29
  143. package/dist/components/rating/rating.svelte.d.ts +1 -1
  144. package/dist/components/rating/types.d.ts +8 -8
  145. package/dist/components/side-nav/docs/llms.md +110 -0
  146. package/dist/components/side-nav/side-nav-branch.svelte +43 -0
  147. package/dist/components/side-nav/side-nav-branch.svelte.d.ts +4 -0
  148. package/dist/components/side-nav/side-nav-item.svelte +75 -0
  149. package/dist/components/side-nav/side-nav-item.svelte.d.ts +25 -0
  150. package/dist/components/side-nav/side-nav-list.svelte +32 -0
  151. package/dist/components/side-nav/side-nav-list.svelte.d.ts +7 -0
  152. package/dist/components/side-nav/side-nav.d.ts +2 -0
  153. package/dist/components/side-nav/side-nav.js +2 -0
  154. package/dist/components/side-nav/side-nav.svelte +355 -0
  155. package/dist/components/side-nav/side-nav.svelte.d.ts +24 -0
  156. package/dist/components/side-nav/types.d.ts +149 -0
  157. package/dist/components/side-nav/types.js +1 -0
  158. package/dist/components/skeleton/docs/llms.md +1 -1
  159. package/dist/components/skeleton/skeleton.svelte +2 -2
  160. package/dist/components/skeleton/types.d.ts +1 -1
  161. package/dist/components/slider/docs/llms.md +31 -28
  162. package/dist/components/slider/slider.svelte +126 -61
  163. package/dist/components/slider/slider.svelte.d.ts +1 -3
  164. package/dist/components/slider/types.d.ts +21 -14
  165. package/dist/components/tab-view/docs/llms.md +7 -7
  166. package/dist/components/tab-view/tab-view-tab.svelte +16 -14
  167. package/dist/components/tab-view/tab-view.svelte +16 -9
  168. package/dist/components/tab-view/types.d.ts +6 -6
  169. package/dist/components/table/docs/llms.md +38 -33
  170. package/dist/components/table/table-body.svelte +2 -2
  171. package/dist/components/table/table-cell-actions.svelte +8 -2
  172. package/dist/components/table/table-cell-layout.svelte +2 -2
  173. package/dist/components/table/table-cell.svelte +2 -2
  174. package/dist/components/table/table-header-cell.svelte +2 -2
  175. package/dist/components/table/table-header.svelte +2 -2
  176. package/dist/components/table/table-row.svelte +2 -2
  177. package/dist/components/table/table-selection-cell.svelte +6 -6
  178. package/dist/components/table/table.svelte +2 -2
  179. package/dist/components/table/types.d.ts +11 -11
  180. package/dist/components/tag/docs/llms.md +26 -26
  181. package/dist/components/tag/tag-group.svelte +2 -2
  182. package/dist/components/tag/tag.svelte +13 -12
  183. package/dist/components/tag/types.d.ts +6 -4
  184. package/dist/components/tag-picker/docs/llms.md +61 -55
  185. package/dist/components/tag-picker/option-group.svelte +17 -4
  186. package/dist/components/tag-picker/option-group.svelte.d.ts +1 -1
  187. package/dist/components/tag-picker/option.svelte +15 -4
  188. package/dist/components/tag-picker/tag-picker.svelte +137 -65
  189. package/dist/components/tag-picker/tag-picker.svelte.d.ts +2 -2
  190. package/dist/components/tag-picker/types.d.ts +36 -16
  191. package/dist/components/text-box/docs/llms.md +31 -4
  192. package/dist/components/text-box/text-box-button.svelte +3 -3
  193. package/dist/components/text-box/text-box-button.svelte.d.ts +1 -1
  194. package/dist/components/text-box/text-box.svelte +41 -14
  195. package/dist/components/text-box/types.d.ts +5 -5
  196. package/dist/components/textarea/docs/llms.md +4 -3
  197. package/dist/components/textarea/textarea.svelte +14 -6
  198. package/dist/components/textarea/types.d.ts +2 -4
  199. package/dist/components/time-picker/docs/llms.md +18 -15
  200. package/dist/components/time-picker/time-picker.svelte +133 -33
  201. package/dist/components/time-picker/time-picker.svelte.d.ts +1 -1
  202. package/dist/components/time-picker/types.d.ts +23 -13
  203. package/dist/components/title-bar/docs/llms.md +382 -0
  204. package/dist/components/title-bar/title-bar-left-controls.svelte +215 -0
  205. package/dist/components/title-bar/title-bar-left-controls.svelte.d.ts +22 -0
  206. package/dist/components/title-bar/title-bar-right-controls.svelte +190 -0
  207. package/dist/components/title-bar/title-bar-right-controls.svelte.d.ts +27 -0
  208. package/dist/components/title-bar/title-bar.d.ts +3 -0
  209. package/dist/components/title-bar/title-bar.js +4 -0
  210. package/dist/components/title-bar/title-bar.svelte +224 -0
  211. package/dist/components/title-bar/title-bar.svelte.d.ts +26 -0
  212. package/dist/components/title-bar/types.d.ts +165 -0
  213. package/dist/components/title-bar/types.js +1 -0
  214. package/dist/components/toggle-switch/docs/llms.md +11 -9
  215. package/dist/components/toggle-switch/toggle-switch.svelte +23 -14
  216. package/dist/components/toggle-switch/toggle-switch.svelte.d.ts +1 -1
  217. package/dist/components/toggle-switch/types.d.ts +12 -10
  218. package/dist/components/tooltip/docs/llms.md +1 -1
  219. package/dist/components/tooltip/tooltip.svelte +5 -4
  220. package/dist/components/tooltip/types.d.ts +1 -1
  221. package/dist/components/top-nav/docs/llms.md +1 -1
  222. package/dist/components/top-nav/top-nav-item.svelte +2 -2
  223. package/dist/components/top-nav/top-nav.svelte +2 -2
  224. package/dist/components/top-nav/types.d.ts +2 -2
  225. package/dist/components/tree-view/docs/llms.md +11 -11
  226. package/dist/components/tree-view/tree-view-item-content.svelte +3 -3
  227. package/dist/components/tree-view/tree-view-item.svelte +13 -5
  228. package/dist/components/tree-view/tree-view.svelte +20 -5
  229. package/dist/components/tree-view/tree-view.svelte.d.ts +1 -1
  230. package/dist/components/tree-view/tree-view.svelte.js +31 -3
  231. package/dist/components/tree-view/types.d.ts +7 -3
  232. package/dist/index.d.ts +18 -0
  233. package/dist/index.js +20 -0
  234. package/dist/internal/components/dynamic-carousel/dynamic-carousel.svelte +26 -5
  235. package/dist/internal/components/dynamic-carousel/dynamic-carousel.svelte.d.ts +2 -0
  236. package/dist/internal/index.d.ts +1 -0
  237. package/dist/internal/index.js +1 -0
  238. package/dist/internal/native-field.svelte.d.ts +44 -0
  239. package/dist/internal/native-field.svelte.js +85 -0
  240. package/dist/internal/utils.d.ts +16 -2
  241. package/dist/internal/utils.js +25 -3
  242. package/dist/types/index.d.ts +3 -3
  243. package/package.json +50 -36
@@ -1,7 +1,6 @@
1
- import { Button } from '../../index.js';
2
1
  import type { MenuItemProps } from './types.ts';
3
- import type { ComponentProps } from 'svelte';
4
- type $$ComponentProps = MenuItemProps & ComponentProps<typeof Button>;
2
+ import type { ButtonProps } from '../button/types.ts';
3
+ type $$ComponentProps = MenuItemProps & ButtonProps<'a' | 'button'>;
5
4
  /**
6
5
  * - Usage:
7
6
  * ```tsx
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
- import { getTabspotAttributes } from 'tabspot';
2
+ import { getTabspotAttributes, setTabspotAttributes, unsetTabspotSection } from 'tabspot';
3
+ import type { Attachment } from 'svelte/attachments';
3
4
  import { getMenuContext } from './menu.svelte.js';
4
5
 
5
6
  let { children } = $props();
@@ -7,6 +8,13 @@
7
8
  const context = getMenuContext();
8
9
 
9
10
  let isSubMenu = $derived(context?.config.isSubMenu);
11
+
12
+ // The list mounts when the menu opens, after Tabspot has scanned the page, so the root menu
13
+ // registers itself to get arrow key navigation. A submenu is a grouper inside it instead.
14
+ const registerRoot: Attachment<HTMLElement> = (element) => {
15
+ setTabspotAttributes({ element, config: { root: {} }, merge: true });
16
+ return () => unsetTabspotSection(element, 'root');
17
+ };
10
18
  </script>
11
19
 
12
20
  <div
@@ -21,6 +29,7 @@
21
29
  }
22
30
  : undefined
23
31
  })}
32
+ {@attach isSubMenu ? undefined : registerRoot}
24
33
  >
25
34
  {@render children()}
26
35
  </div>
@@ -10,7 +10,7 @@
10
10
 
11
11
  let {
12
12
  ref: _ref,
13
- open: _open = $bindable(),
13
+ open: _open = $bindable(null),
14
14
  keepMounted = false,
15
15
  placement,
16
16
  positionConfig: floatingPosition = {
@@ -45,11 +45,15 @@
45
45
 
46
46
  let { state: _state } = context;
47
47
 
48
- // The `placement` prop wins over the one coming from the config
48
+ // The `placement` prop wins over the one coming from the config. The strategy is always set, since the CSS position follows it.
49
49
  let config = $derived.by(() => {
50
50
  const base = positionConfig ?? floatingPosition;
51
51
 
52
- return { ...base, placement: placement ?? base.placement ?? (isSubMenu ? 'right-start' : 'bottom-start') };
52
+ return {
53
+ ...base,
54
+ strategy: base.strategy ?? 'fixed',
55
+ placement: placement ?? base.placement ?? (isSubMenu ? 'right-start' : 'bottom-start')
56
+ };
53
57
  });
54
58
 
55
59
  let boundingElement = reactiveBoundingRect();
@@ -93,7 +97,7 @@
93
97
  hidden={!opened}
94
98
  onmouseleave={openOnHover ? (e: MouseEvent) => debounced(e) : undefined}
95
99
  {@attach opened && ref ? floating(ref, config) : undefined}
96
- style={`--position=${isSubMenu ? 'absolute' : 'fixed'} --min-width=${isRefAnElement && !isSubMenu ? `${boundingElement.rect.width}px` : 'max-content'}`}
100
+ style={`--position: ${config.strategy}; --min-width: ${isRefAnElement && !isSubMenu ? `${boundingElement.rect.width}px` : 'max-content'};`}
97
101
  in:flyToOffset={opened && isRefAnElement
98
102
  ? {
99
103
  ...getIntroTransition({ config, anchor: boundingElement.rect, element, ref, isSubMenu }),
@@ -119,7 +123,7 @@
119
123
  z-index: 110;
120
124
  & :global(.fs-flyout),
121
125
  & :global(.fs-flyout::before) {
122
- border-radius: var(--fs-control-border-radius);
126
+ border-radius: var(--fs-control-overlay-border-radius);
123
127
  }
124
128
  & :global(.fs-flyout) {
125
129
  padding: 0;
@@ -55,7 +55,8 @@
55
55
  return;
56
56
  }
57
57
 
58
- if (target === _state.ref) {
58
+ // A click on the icon inside the trigger is a click on the trigger.
59
+ if (target === _state.ref || (_state.ref instanceof Node && _state.ref.contains(target))) {
59
60
  _state.locked = !_state.locked;
60
61
  toggle(e);
61
62
  // Focus the first button in the popover when opening
@@ -75,3 +75,4 @@ export const getIntroTransition = ({ config, anchor, element, ref, isSubMenu = f
75
75
  css: `top: ${top}px; left: ${left}px;`
76
76
  };
77
77
  };
78
+ export const [getMenuCommandBarContext, setMenuCommandBarContext] = createFSContext();
@@ -1,8 +1,8 @@
1
1
  import type { ComputePositionConfig, VirtualElement } from '@floating-ui/dom';
2
2
  import type { FSContext } from '../../internal/index.js';
3
- import type { Component, ComponentProps, Snippet } from 'svelte';
3
+ import type { Component, Snippet } from 'svelte';
4
4
  import type { NoUndefinedField, Shapes } from '../../types/index.js';
5
- import type { Button } from '../../index.ts';
5
+ import type { AriaAttributes, HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
6
6
  import type { ButtonProps } from '../button/types.ts';
7
7
  export type MenuContext = FSContext<{
8
8
  id: string;
@@ -62,11 +62,11 @@ export type MenuProps = {
62
62
  /** @propsmith MenuPopoverProps */
63
63
  export type MenuPopoverProps = {
64
64
  /** The element used to position the popover. */
65
- ref?: HTMLElement;
65
+ ref?: HTMLElement | null;
66
66
  /** Controls the open state of the popover.
67
67
  * @bindable
68
68
  */
69
- open?: boolean;
69
+ open?: boolean | null;
70
70
  /** Keeps the popover mounted in the DOM while it is closed.
71
71
  * @default false
72
72
  */
@@ -106,7 +106,7 @@ export type MenuGroupProps = {
106
106
  /** The DOM reference of the group element.
107
107
  * @bindable
108
108
  */
109
- ref?: HTMLDivElement;
109
+ ref?: HTMLDivElement | null;
110
110
  /** The label of the group. */
111
111
  header?: string;
112
112
  /** The items of the group. */
@@ -136,7 +136,7 @@ export type MenuItemActionableProps = {
136
136
  /** Whether the item is checked.
137
137
  * @bindable
138
138
  */
139
- checked?: boolean;
139
+ checked?: boolean | null;
140
140
  /** The value reported to the menu when the item is checked. Falls back to the id of the item.
141
141
  * @default id
142
142
  */
@@ -145,4 +145,59 @@ export type MenuItemActionableProps = {
145
145
  * @default id
146
146
  */
147
147
  name?: string;
148
- } & Omit<MenuItemProps, 'href'> & ComponentProps<typeof Button<'div'>>;
148
+ } & Omit<MenuItemProps, 'href'> & ButtonProps<'button'>;
149
+ /** @propsmith MenuCommandBarProps */
150
+ export type MenuCommandBarProps = {
151
+ /** The DOM reference of the command bar element.
152
+ * @bindable
153
+ */
154
+ ref?: HTMLDivElement | null;
155
+ /** Where the bar sits in the menu. A bar at the top has its divider below it, and one at the bottom has it above.
156
+ * @type 'top' | 'bottom'
157
+ * @default 'top'
158
+ */
159
+ position?: 'top' | 'bottom';
160
+ /** The accessible name of the group of commands.
161
+ * @default 'Commands'
162
+ */
163
+ label?: string;
164
+ /** The accessible name of the button that opens the overflow.
165
+ * @default 'More options'
166
+ */
167
+ overflowLabel?: string;
168
+ /** The secondary commands. When present, a "more" button at the end of the bar opens them in a submenu. */
169
+ overflow?: Snippet;
170
+ /** Shows the label of every command below its icon. Without labels, every command is a square.
171
+ * @default false
172
+ */
173
+ showLabels?: boolean;
174
+ /** Draws a divider between every two commands.
175
+ * @default false
176
+ */
177
+ showDividers?: boolean;
178
+ /** The primary commands, as `MenuCommandBarItem`s. */
179
+ children?: Snippet;
180
+ } & Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'role'>;
181
+ /** @propsmith MenuCommandBarItemProps */
182
+ export type MenuCommandBarItemProps = {
183
+ /** The DOM reference of the button element.
184
+ * @bindable
185
+ */
186
+ ref?: HTMLButtonElement | null;
187
+ /** The icon of the command.
188
+ * @type Snippet | Component
189
+ */
190
+ icon: Snippet<[{
191
+ class: string;
192
+ }]> | Component<{
193
+ class: string;
194
+ }>;
195
+ /** The name of the command. Without visible labels it is the accessible name of the button and shows as its tooltip; with them it shows below the icon. */
196
+ label: string;
197
+ /** Disables the user interaction. */
198
+ disabled?: boolean;
199
+ /** Called when the command is activated. The menu closes afterwards, unless it persists on item activation.
200
+ * @type (e: MouseEvent) => void
201
+ */
202
+ onclick?: (e: MouseEvent) => void;
203
+ } & Omit<AriaAttributes, 'aria-label'> & Pick<HTMLButtonAttributes, 'id' | 'class' | 'onkeydown' | 'onfocus' | 'onblur'>;
@@ -9,7 +9,7 @@ The NumberBox component allows users to input numeric values with specified cons
9
9
  import { NumberBox } from 'fluentui-svelte';
10
10
  </script>
11
11
 
12
- <NumberBox value={0} min={0} max={100} step={1} />
12
+ <NumberBox aria-label="Quantity" value={0} min={0} max={100} step={1} />
13
13
  ```
14
14
 
15
15
  ## Component API
@@ -23,10 +23,12 @@ A brief explanation of the props that really need explaining. You can see the re
23
23
  The variant prop determines the visual style of the NumberBox.
24
24
 
25
25
  ```svelte
26
- <NumberBox hideActionButtons min={0} max={100} step={1} />
27
- <NumberBox hideActionButtons min={0} max={100} step={1} variant="compact" />
26
+ <NumberBox aria-label="Quantity" hideActionButtons min={0} max={100} step={1} />
27
+ <NumberBox aria-label="Quantity" hideActionButtons min={0} max={100} step={1} variant="compact" />
28
28
  ```
29
29
 
30
+ HTML attributes, including class, id and ARIA attributes, apply to the control element. Bind ref to access that control. Use wrapperAttributes and wrapperRef for the outer container.
31
+
30
32
  ## Component Props
31
33
 
32
34
  <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
@@ -34,7 +36,7 @@ The variant prop determines the visual style of the NumberBox.
34
36
 
35
37
  | Name | Type | Default | Description |
36
38
  | ----------------------------- | ----------------------------- | ---------- | ----------------------------------------------------- |
37
- | `value` _bindable_ | `number` | | The current value of the input. |
39
+ | `value` _bindable_ | `number` &#124; `null` | | The current value of the input. |
38
40
  | `variant` | `'inline'` &#124; `'compact'` | `'inline'` | How the increment and decrement buttons are laid out. |
39
41
  | `TextBoxProps` without `type` | | | |
40
42
 
@@ -1,38 +1,36 @@
1
1
  <script lang="ts">
2
- import { on } from 'svelte/events';
2
+ import { claimLabel } from '../label/label-context.js';
3
3
  import { floating } from '../../internal/index.js';
4
4
  import { offset, shift } from '@floating-ui/dom';
5
5
  import { Flyout, TextBoxButton, TextBox } from '../../index.js';
6
6
  import { ChevronUpFilled, ChevronDownFilled, ChevronUpDownFilled } from 'fluentui-icons-svelte';
7
7
  import type { NumberBoxProps } from './types.js';
8
+ import { onClickOutside } from 'runed';
8
9
 
9
10
  const ID = $props.id();
11
+ /** Half of the width of the button that opens the flyout of the compact variant. */
12
+ const BUTTON_HALF_WIDTH = 16;
13
+
14
+ const label = claimLabel(() => id);
10
15
 
11
16
  let {
12
- id = 'input-' + ID,
17
+ id = label?.fieldId ?? 'input-' + ID,
13
18
  name = id,
14
- value = $bindable(),
19
+ value = $bindable(null),
15
20
  variant = 'inline',
16
- ref = $bindable(),
21
+ ref = $bindable(null),
22
+ wrapperRef = $bindable(null),
23
+ wrapperAttributes,
17
24
  placeholder = '',
18
- class: classes,
19
25
  ...attributes
20
26
  }: NumberBoxProps = $props();
21
27
 
22
28
  let openFlyout = $state(false);
23
- let cleanEvent: () => void;
24
-
25
- let handler = (e: Event) => {
26
- if (!(e.target as HTMLElement).closest(`.${id}`)) {
27
- openFlyout = false;
28
- cleanEvent();
29
- }
30
- };
31
29
 
32
- const compactToggler = () => {
33
- openFlyout = true;
34
- cleanEvent = on(document, 'click', handler);
35
- };
30
+ onClickOutside(
31
+ () => wrapperRef,
32
+ () => (openFlyout = false)
33
+ );
36
34
  </script>
37
35
 
38
36
  <!-- @component
@@ -46,7 +44,18 @@
46
44
  <NumberBox />
47
45
  ```
48
46
  -->
49
- <TextBox class={['fs-number-box', classes]} type="number" {id} {name} {placeholder} bind:value bind:ref {...attributes}>
47
+ <TextBox
48
+ {...attributes}
49
+ bind:wrapperRef
50
+ wrapperAttributes={{ ...wrapperAttributes, class: ['fs-number-box', wrapperAttributes?.class] }}
51
+ type="number"
52
+ {id}
53
+ {name}
54
+ {placeholder}
55
+ bind:value
56
+ bind:ref
57
+ inputmode="numeric"
58
+ >
50
59
  {#if variant === 'inline'}
51
60
  <TextBoxButton aria-label="Increase Number" onclick={() => (value = value ? ++value : 1)}>
52
61
  <ChevronUpFilled />
@@ -55,22 +64,19 @@
55
64
  <ChevronDownFilled />
56
65
  </TextBoxButton>
57
66
  {:else}
58
- <TextBoxButton aria-label="Open" onclick={() => compactToggler()}>
67
+ <TextBoxButton aria-label="Open" onclick={() => (openFlyout = !openFlyout)}>
59
68
  <ChevronUpDownFilled />
60
69
  </TextBoxButton>
61
70
  {#if openFlyout}
62
71
  <div
63
72
  class="flyout-absolute"
64
- {@attach ref
65
- ? floating(ref, {
73
+ {@attach wrapperRef
74
+ ? floating(wrapperRef, {
66
75
  placement: 'right',
67
76
  middleware: [
68
- shift({
69
- crossAxis: true
70
- }),
71
- offset(({ rects }) => {
72
- return -rects.reference.width / 1.4;
73
- })
77
+ // Centers the flyout on the button that opened it, whatever the width of the box.
78
+ offset(({ rects }) => -(rects.floating.width / 2 + BUTTON_HALF_WIDTH)),
79
+ shift({ crossAxis: true, padding: 8 })
74
80
  ]
75
81
  })
76
82
  : undefined}
@@ -93,9 +99,9 @@
93
99
  <style>
94
100
  .flyout-absolute {
95
101
  position: absolute;
96
- right: 0;
102
+ left: 0;
97
103
  top: 0;
98
- z-index: 2;
104
+ z-index: 3;
99
105
  & :global(.fs-flyout) {
100
106
  padding: 8px;
101
107
  }
@@ -10,6 +10,6 @@ import type { NumberBoxProps } from './types.ts';
10
10
  * <NumberBox />
11
11
  * ```
12
12
  */
13
- declare const NumberBox: import("svelte").Component<NumberBoxProps, {}, "ref" | "value">;
13
+ declare const NumberBox: import("svelte").Component<NumberBoxProps, {}, "ref" | "value" | "wrapperRef">;
14
14
  type NumberBox = ReturnType<typeof NumberBox>;
15
15
  export default NumberBox;
@@ -4,7 +4,7 @@ export type NumberBoxProps = {
4
4
  /** The current value of the input.
5
5
  * @bindable
6
6
  */
7
- value?: number;
7
+ value?: number | null;
8
8
  /** How the increment and decrement buttons are laid out.
9
9
  *
10
10
  * `inline`: the buttons sit inside the input, one next to the other.
@@ -15,7 +15,7 @@ A Persona is a visual representation of a person that combines an avatar, presen
15
15
  secondaryText="Intranet"
16
16
  tertiaryText="Team A"
17
17
  presence={{ status: 'available' }}
18
- avatar={{ color: 'colorful' }}
18
+ avatarProps={{ color: 'colorful' }}
19
19
  />
20
20
  ```
21
21
 
@@ -26,9 +26,9 @@ A Persona is a visual representation of a person that combines an avatar, presen
26
26
  A Persona supports three text alignments, with 'left' as the default position.
27
27
 
28
28
  ```svelte
29
- <Persona name="Alex Johnson" avatar={{ initials: 'AJ' }} secondaryText="Available" />
30
- <Persona name="Alex Johnson" avatar={{ initials: 'AJ' }} secondaryText="Available" textAlign="center" />
31
- <Persona name="Alex Johnson" avatar={{ initials: 'AJ' }} secondaryText="Available" textAlign="right" />
29
+ <Persona name="Alex Johnson" avatarProps={{ initials: 'AJ' }} secondaryText="Available" />
30
+ <Persona name="Alex Johnson" avatarProps={{ initials: 'AJ' }} secondaryText="Available" textAlign="center" />
31
+ <Persona name="Alex Johnson" avatarProps={{ initials: 'AJ' }} secondaryText="Available" textAlign="right" />
32
32
  ```
33
33
 
34
34
  ### Text Position
@@ -36,18 +36,18 @@ A Persona supports three text alignments, with 'left' as the default position.
36
36
  A Persona supports four text positions: 'top', 'bottom', 'left', and 'right'. The default position is 'right'.
37
37
 
38
38
  ```svelte
39
- <Persona name="Alex Johnson" avatar={{ initials: 'AJ' }} secondaryText="Available" />
39
+ <Persona name="Alex Johnson" avatarProps={{ initials: 'AJ' }} secondaryText="Available" />
40
40
  <Persona
41
41
  name="Alex Johnson"
42
- avatar={{ initials: 'AJ' }}
42
+ avatarProps={{ initials: 'AJ' }}
43
43
  secondaryText="Available"
44
44
  textPosition="bottom"
45
45
  textAlign="center"
46
46
  />
47
- <Persona name="Alex Johnson" avatar={{ initials: 'AJ' }} secondaryText="Available" textPosition="left" />
47
+ <Persona name="Alex Johnson" avatarProps={{ initials: 'AJ' }} secondaryText="Available" textPosition="left" />
48
48
  <Persona
49
49
  name="Alex Johnson"
50
- avatar={{ initials: 'AJ' }}
50
+ avatarProps={{ initials: 'AJ' }}
51
51
  secondaryText="Available"
52
52
  textPosition="top"
53
53
  textAlign="center"
@@ -69,9 +69,12 @@ A Persona supports custom sizes, with a default of 42px. You can set the size us
69
69
  A Persona wraps an avatar inside it, which can be customized with all the props available to the Avatar component.
70
70
 
71
71
  ```svelte
72
- <Persona name="John Doe" avatar={{ color: 'attention' }} />
73
- <Persona name="John Doe" avatar={{ color: 'colorful', idForColor: '' }} />
74
- <Persona name="John Doe" avatar={{ image: { src: 'https://placehold.co/96x96/jpeg', alt: 'Placeholder Image' } }} />
72
+ <Persona name="John Doe" avatarProps={{ color: 'attention' }} />
73
+ <Persona name="John Doe" avatarProps={{ color: 'colorful', idForColor: '' }} />
74
+ <Persona
75
+ name="John Doe"
76
+ avatarProps={{ image: { src: 'https://placehold.co/96x96/jpeg', alt: 'Placeholder Image' } }}
77
+ />
75
78
  ```
76
79
 
77
80
  ### Presence
@@ -94,19 +97,20 @@ A Persona can display presence information, such as online status or availabilit
94
97
  <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
95
98
  <!-- props:PersonaProps -->
96
99
 
97
- | Name | Type | Default | Description |
98
- | -------------------- | ---------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
99
- | `name` | `string` | | The name of the person or entity represented by this Persona. It is also used by the avatar for its initials. |
100
- | `size` | `number` | `42` | The size of the avatar in pixels. The text scales with it. |
101
- | `primaryText` | `string` | | Text to display below the name. |
102
- | `secondaryText` | `string` | | Text to display below the primary text. |
103
- | `tertiaryText` | `string` | | Text to display below the secondary text. |
104
- | `textAlign` | `'left'` &#124; `'center'` &#124; `'right'` | `'left'` | How the text block is aligned. |
105
- | `textPosition` | `'top'` &#124; `'bottom'` &#124; `'left'` &#124; `'right'` | `'right'` | Where the text block sits relative to the avatar. |
106
- | `presenceOnly` | `boolean` | | Renders the presence badge on its own, without the avatar behind it. |
107
- | `avatarAlign` | `'start'` &#124; `'center'` &#124; `'end'` | `'center'` | How the avatar is aligned against the text block. |
108
- | `element` _bindable_ | `HTMLDivElement` | | The DOM reference of the persona element. |
109
- | `avatar` | `AvatarProps` | | The props to spread on the avatar. |
110
- | `presence` | `BadgePresence` | | The presence badge to display as a status indicator. |
100
+ | Name | Type | Default | Description |
101
+ | -------------------------- | ---------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
102
+ | `name` | `string` | | The name of the person or entity represented by this Persona. It is also used by the avatar for its initials. |
103
+ | `size` | `number` | `42` | The size of the avatar in pixels. The text scales with it. |
104
+ | `primaryText` | `string` | | Text to display below the name. |
105
+ | `secondaryText` | `string` | | Text to display below the primary text. |
106
+ | `tertiaryText` | `string` | | Text to display below the secondary text. |
107
+ | `textAlign` | `'left'` &#124; `'center'` &#124; `'right'` | `'left'` | How the text block is aligned. |
108
+ | `textPosition` | `'top'` &#124; `'bottom'` &#124; `'left'` &#124; `'right'` | `'right'` | Where the text block sits relative to the avatar. |
109
+ | `presenceOnly` | `boolean` | | Renders the presence badge on its own, without the avatar behind it. |
110
+ | `avatarAlign` | `'start'` &#124; `'center'` &#124; `'end'` | `'center'` | How the avatar is aligned against the text block. |
111
+ | `element` _bindable_ | `HTMLDivElement` &#124; `null` | | The DOM reference of the persona element. |
112
+ | `avatarProps` | `AvatarProps` | | The props to spread on the avatar. |
113
+ | `presence` | `BadgePresence` | | The presence badge to display as a status indicator. |
114
+ | Element Attributes (`div`) | | | |
111
115
 
112
116
  <!-- /props:PersonaProps -->
@@ -11,8 +11,8 @@
11
11
  textAlign = 'left',
12
12
  textPosition: dir = 'right',
13
13
  avatarAlign = 'center',
14
- element = $bindable(),
15
- avatar,
14
+ element = $bindable(null),
15
+ avatarProps,
16
16
  presence,
17
17
  presenceOnly,
18
18
  ...attributes
@@ -27,15 +27,17 @@
27
27
  </script>
28
28
 
29
29
  <div
30
- bind:this={element}
31
- class="persona"
32
- style="--p-size: {size}px; --avatar-align: {avatarAlign}; flex-direction: {position[dir]}; text-align: {textAlign};"
33
30
  {...attributes}
31
+ bind:this={element}
32
+ class={['persona', attributes?.class]}
33
+ style="{attributes?.style ?? ''}; --p-size: {size}px; --avatar-align: {avatarAlign}; flex-direction: {position[
34
+ dir
35
+ ]}; text-align: {textAlign};"
34
36
  >
35
37
  {#if presenceOnly && presence?.status}
36
38
  <BadgeIcon {size} icon={presence?.icon || undefined} status={presence.status} outOfOffice={presence?.outOfOffice} />
37
39
  {:else}
38
- <Avatar {name} {size} {...avatar} badge={presence} />
40
+ <Avatar {...avatarProps} {name} {size} badge={presence} />
39
41
  {/if}
40
42
  <div class="persona-data">
41
43
  <p class="persona-name">{name}</p>
@@ -1,3 +1,4 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
1
2
  import type { AvatarProps } from '../avatar/type.ts';
2
3
  /** @propsmith PersonaProps */
3
4
  export type PersonaProps = {
@@ -30,13 +31,13 @@ export type PersonaProps = {
30
31
  /** The DOM reference of the persona element.
31
32
  * @bindable
32
33
  */
33
- element?: HTMLDivElement;
34
+ element?: HTMLDivElement | null;
34
35
  /** The props to spread on the avatar.
35
36
  * @type AvatarProps
36
37
  */
37
- avatar?: AvatarProps;
38
+ avatarProps?: AvatarProps;
38
39
  /** The presence badge to display as a status indicator.
39
40
  * @type BadgePresence
40
41
  */
41
42
  presence?: AvatarProps['badge'];
42
- };
43
+ } & HTMLAttributes<HTMLDivElement>;
@@ -58,18 +58,18 @@ The status prop allows you to set the status of the progress bar to 'paused' or
58
58
  <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
59
59
  <!-- props:ProgressBarProps -->
60
60
 
61
- | Name | Type | Default | Description |
62
- | ---------------------------------- | --------------------------- | ------- | ------------------------------------------------------------------------------- |
63
- | `value` _bindable_ | `number` &#124; `null` | | The current value of the progress bar. Leave it unset for an indeterminate bar. |
64
- | `class` | `string` | | The class to apply to the progress bar. |
65
- | `ref` _bindable_ | `SVGElement` | | The DOM reference of the progress bar element. |
66
- | `min` | `number` | `0` | The minimum value of the progress bar. |
67
- | `max` | `number` | `100` | The maximum value of the progress bar. |
68
- | `hideRail` | `boolean` | | Whether to hide the rail element. |
69
- | `railElement` _bindable_ | `SVGRectElement` | | The DOM reference of the rail element. |
70
- | `secondaryTrackElement` _bindable_ | `SVGRectElement` | | The DOM reference of the secondary track element, used while indeterminate. |
71
- | `trackElement` _bindable_ | `SVGRectElement` | | The DOM reference of the track element. |
72
- | `status` | `'paused'` &#124; `'error'` | | The current status of the progress bar, which recolors the track. |
73
- | Element Attributes | | | |
61
+ | Name | Type | Default | Description |
62
+ | ---------------------------------- | ------------------------------ | ------- | ------------------------------------------------------------------------------- |
63
+ | `value` _bindable_ | `number` &#124; `null` | | The current value of the progress bar. Leave it unset for an indeterminate bar. |
64
+ | `class` | `string` | | The class to apply to the progress bar. |
65
+ | `ref` _bindable_ | `SVGElement` &#124; `null` | | The DOM reference of the progress bar element. |
66
+ | `min` | `number` | `0` | The minimum value of the progress bar. |
67
+ | `max` | `number` | `100` | The maximum value of the progress bar. |
68
+ | `hideRail` | `boolean` | | Whether to hide the rail element. |
69
+ | `railElement` _bindable_ | `SVGRectElement` &#124; `null` | | The DOM reference of the rail element. |
70
+ | `secondaryTrackElement` _bindable_ | `SVGRectElement` &#124; `null` | | The DOM reference of the secondary track element, used while indeterminate. |
71
+ | `trackElement` _bindable_ | `SVGRectElement` &#124; `null` | | The DOM reference of the track element. |
72
+ | `status` | `'paused'` &#124; `'error'` | | The current status of the progress bar, which recolors the track. |
73
+ | Element Attributes | | | |
74
74
 
75
75
  <!-- /props:ProgressBarProps -->
@@ -8,11 +8,11 @@
8
8
  'aria-label': ariaLabel,
9
9
  min = 0,
10
10
  max = 100,
11
- value = $bindable(),
12
- ref = $bindable(),
13
- railElement = $bindable(),
14
- trackElement = $bindable(),
15
- secondaryTrackElement = $bindable(),
11
+ value = $bindable(null),
12
+ ref = $bindable(null),
13
+ railElement = $bindable(null),
14
+ trackElement = $bindable(null),
15
+ secondaryTrackElement = $bindable(null),
16
16
  ...attributes
17
17
  }: ProgressBarProps = $props();
18
18
 
@@ -31,6 +31,7 @@
31
31
  ```
32
32
  -->
33
33
  <svg
34
+ {...attributes}
34
35
  class={['fs-progress-bar', status && `status-${status}`, classes, typeof value !== 'number' && 'indeterminate']}
35
36
  role="progressbar"
36
37
  aria-label={ariaLabel ??
@@ -41,7 +42,6 @@
41
42
  aria-valuemax={max}
42
43
  aria-valuenow={checkValue}
43
44
  bind:this={ref}
44
- {...attributes}
45
45
  >
46
46
  {#if !hideRail}
47
47
  <rect bind:this={railElement} height="1" rx="0.5" y="1" width="100%" class="progress-bar-rail" />
@@ -11,7 +11,7 @@ export type ProgressBarProps = {
11
11
  /** The DOM reference of the progress bar element.
12
12
  * @bindable
13
13
  */
14
- ref?: SVGElement;
14
+ ref?: SVGElement | null;
15
15
  /** The minimum value of the progress bar.
16
16
  * @default 0
17
17
  */
@@ -25,15 +25,15 @@ export type ProgressBarProps = {
25
25
  /** The DOM reference of the rail element.
26
26
  * @bindable
27
27
  */
28
- railElement?: SVGRectElement;
28
+ railElement?: SVGRectElement | null;
29
29
  /** The DOM reference of the secondary track element, used while indeterminate.
30
30
  * @bindable
31
31
  */
32
- secondaryTrackElement?: SVGRectElement;
32
+ secondaryTrackElement?: SVGRectElement | null;
33
33
  /** The DOM reference of the track element.
34
34
  * @bindable
35
35
  */
36
- trackElement?: SVGRectElement;
36
+ trackElement?: SVGRectElement | null;
37
37
  /** The current status of the progress bar, which recolors the track. */
38
38
  status?: ProgressStatus;
39
39
  } & SVGAttributes<SVGElement>;