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
@@ -9,7 +9,7 @@ A toggle switch represents a physical switch that allows someone to choose betwe
9
9
  import { ToggleSwitch } from 'fluentui-svelte';
10
10
  </script>
11
11
 
12
- <ToggleSwitch />
12
+ <ToggleSwitch aria-label="Notifications" />
13
13
  <ToggleSwitch label="Toggle me" />
14
14
  <ToggleSwitch label="I'm disabled" disabled />
15
15
  ```
@@ -26,18 +26,20 @@ A toggle switch can be labeled, checked, or disabled.
26
26
  <ToggleSwitch label="Disabled" disabled />
27
27
  ```
28
28
 
29
+ 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.
30
+
29
31
  ## Component Props
30
32
 
31
33
  <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
32
34
  <!-- props:ToggleSwitchProps -->
33
35
 
34
- | Name | Type | Default | Description |
35
- | ----------------------------- | --------------------- | ------- | ---------------------------------------------------------- |
36
- | `checked` _bindable_ | `boolean` | | Whether the switch is on. |
37
- | `ref` _bindable_ | `HTMLInputElement` | | The DOM reference of the input element. |
38
- | `label` | `string` | | The label displayed next to the input element. |
39
- | `labelAttributes` | `HTMLLabelAttributes` | | The attributes to spread on the label wrapping the switch. |
40
- | `labelElement` | `HTMLLabelElement` | | The DOM reference of the label element. |
41
- | `SvelteHTMLElements['input']` | | | |
36
+ | Name | Type | Default | Description |
37
+ | ---------------------------- | -------------------------------- | ------- | ----------------------------------------------------------------------------------- |
38
+ | `checked` _bindable_ | `boolean` &#124; `null` | | Whether the switch is on. |
39
+ | `ref` _bindable_ | `HTMLInputElement` &#124; `null` | | The DOM reference of the input element. |
40
+ | `label` | `string` | | The label displayed next to the input element. Inside a `Label`, it is not rendered |
41
+ | `wrapperAttributes` | `HTMLAttributes` | | The attributes to spread on the wrapper element. |
42
+ | `wrapperRef` _bindable_ | `HTMLDivElement` &#124; `null` | | The DOM reference of the wrapper element. |
43
+ | Element Attributes (`input`) | | | |
42
44
 
43
45
  <!-- /props:ToggleSwitchProps -->
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { claimLabel } from '../label/label-context.js';
2
3
  import { PREFIX } from '../../internal/constants.js';
3
4
  import type { ToggleSwitchProps } from './types.js';
4
5
 
@@ -6,14 +7,16 @@
6
7
  const COMPONENT_NAME = 'toggle-switch';
7
8
  const ID = `${PREFIX}${COMPONENT_NAME}-${FALLBACK_ID}`;
8
9
 
10
+ const labelContext = claimLabel(() => id);
11
+
9
12
  let {
10
- ref = $bindable(),
11
- checked = $bindable(),
12
- id = ID,
13
+ ref = $bindable(null),
14
+ checked = $bindable(null),
15
+ id = labelContext?.fieldId ?? ID,
13
16
  name = id,
14
17
  label,
15
- labelAttributes,
16
- labelElement,
18
+ wrapperAttributes,
19
+ wrapperRef = $bindable(null),
17
20
  ...attributes
18
21
  }: ToggleSwitchProps = $props();
19
22
  </script>
@@ -33,17 +36,18 @@
33
36
  <ToggleSwitch label="Toggle Switch" />
34
37
  ```
35
38
  -->
36
- <label class="fs-toggle-switch" {...labelAttributes} bind:this={labelElement}>
37
- <input type="checkbox" role="switch" {id} {name} bind:checked bind:this={ref} {...attributes} />
38
- {#if label}
39
- <span>
39
+ <div {...wrapperAttributes} class={['fs-toggle-switch', wrapperAttributes?.class]} bind:this={wrapperRef}>
40
+ <input {...attributes} type="checkbox" role="switch" {id} {name} bind:checked bind:this={ref} />
41
+ <!-- Inside a Label, the Label names the field instead. -->
42
+ {#if label && !labelContext}
43
+ <label for={id}>
40
44
  {label}
41
- </span>
45
+ </label>
42
46
  {/if}
43
- </label>
47
+ </div>
44
48
 
45
49
  <style>
46
- label {
50
+ .fs-toggle-switch {
47
51
  display: flex;
48
52
  align-items: center;
49
53
  border-radius: 1.125rem;
@@ -53,7 +57,7 @@
53
57
  &:has(input:focus-visible) {
54
58
  outline: 0.125rem var(--fs-focus-stroke-outer) solid;
55
59
  outline-offset: 0.125rem;
56
- &:has(span) {
60
+ &:has(> label) {
57
61
  border-radius: 0.063rem;
58
62
  outline-offset: 0.313rem;
59
63
  }
@@ -130,6 +134,9 @@
130
134
  &:active::after {
131
135
  width: 1rem;
132
136
  }
137
+ &:is(:user-invalid, [aria-invalid='true']) {
138
+ border-color: var(--fs-system-critical);
139
+ }
133
140
  &:checked {
134
141
  background-color: var(--fs-accent-fill-default);
135
142
  border-color: var(--fs-accent-fill-default);
@@ -142,7 +149,9 @@
142
149
  }
143
150
  }
144
151
  }
145
- & span {
152
+ & > label {
153
+ flex-grow: 1;
154
+ cursor: pointer;
146
155
  font-size: inherit;
147
156
  color: inherit;
148
157
  padding-inline: 0.8rem;
@@ -12,6 +12,6 @@ import type { ToggleSwitchProps } from './types.ts';
12
12
  * <ToggleSwitch label="Toggle Switch" />
13
13
  * ```
14
14
  */
15
- declare const ToggleSwitch: import("svelte").Component<ToggleSwitchProps, {}, "ref" | "checked">;
15
+ declare const ToggleSwitch: import("svelte").Component<ToggleSwitchProps, {}, "ref" | "checked" | "wrapperRef">;
16
16
  type ToggleSwitch = ReturnType<typeof ToggleSwitch>;
17
17
  export default ToggleSwitch;
@@ -1,20 +1,22 @@
1
- import type { HTMLLabelAttributes, SvelteHTMLElements } from 'svelte/elements';
1
+ import type { HTMLAttributes, HTMLInputAttributes } from 'svelte/elements';
2
2
  /** @propsmith ToggleSwitchProps */
3
3
  export type ToggleSwitchProps = {
4
4
  /** Whether the switch is on.
5
5
  * @bindable
6
6
  */
7
- checked?: boolean;
7
+ checked?: boolean | null;
8
8
  /** The DOM reference of the input element.
9
9
  * @bindable
10
10
  */
11
- ref?: HTMLInputElement;
12
- /** The label displayed next to the input element. */
11
+ ref?: HTMLInputElement | null;
12
+ /** The label displayed next to the input element. Inside a `Label`, it is not rendered */
13
13
  label?: string;
14
- /** The attributes to spread on the label wrapping the switch.
15
- * @type HTMLLabelAttributes
14
+ /** The attributes to spread on the wrapper element.
15
+ * @type HTMLAttributes
16
16
  */
17
- labelAttributes?: HTMLLabelAttributes;
18
- /** The DOM reference of the label element. */
19
- labelElement?: HTMLLabelElement;
20
- } & SvelteHTMLElements['input'];
17
+ wrapperAttributes?: HTMLAttributes<HTMLDivElement>;
18
+ /** The DOM reference of the wrapper element.
19
+ * @bindable
20
+ */
21
+ wrapperRef?: HTMLDivElement | null;
22
+ } & HTMLInputAttributes;
@@ -69,7 +69,7 @@ The relationship prop allows you to specify the relationship between the tooltip
69
69
  | --------------------------------------------------- | -------------------------------------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------- |
70
70
  | `content` | `string` &#124; `Snippet` &#124; `Component` | `'I am a tooltip'` | The content to display in the tooltip. |
71
71
  | `class` | `string` | | The class to apply to the tooltip. |
72
- | `ref` _bindable_ | `HTMLElement` | | The DOM reference of the tooltip element. |
72
+ | `ref` _bindable_ | `HTMLElement` &#124; `null` | | The DOM reference of the tooltip element. |
73
73
  | `target` | `HTMLElement` | | The element the tooltip is anchored to. Falls back to the rendered children. |
74
74
  | `open` _bindable_ | `boolean` | `false` | Controls the open state of the tooltip. |
75
75
  | `withArrow` | `boolean` | `false` | Whether the tooltip has an arrow pointing at its target. |
@@ -13,7 +13,7 @@
13
13
  const ID = `${PREFIX}${COMPONENT_NAME}-${FALLBACK_ID}`;
14
14
 
15
15
  let {
16
- ref = $bindable(),
16
+ ref = $bindable(null),
17
17
  content = 'I am a tooltip',
18
18
  placement,
19
19
  target,
@@ -75,7 +75,7 @@
75
75
  placement: placement ?? _config?.placement ?? 'top',
76
76
  strategy: 'fixed' as const,
77
77
  middleware: [
78
- ...(_config?.middleware ?? [offset(8), flip(), shift({ padding: 8 }), hide()]),
78
+ ...(_config?.middleware ?? [offset(8), flip({ padding: 100 }), shift({ padding: 100 }), hide()]),
79
79
  ...(withArrow && arrowElement ? [arrow({ element: arrowElement })] : [])
80
80
  ]
81
81
  });
@@ -174,11 +174,11 @@
174
174
  ```
175
175
  -->
176
176
  <Flyout
177
+ {...attributes}
177
178
  {id}
178
179
  class={['fs-tooltip', !open && 'tooltip-hidden', classes]}
179
180
  role="tooltip"
180
181
  bind:ref
181
- {...attributes}
182
182
  {@attach triggerElement && open
183
183
  ? floating(triggerElement, positionConfig, {
184
184
  onComputed: withArrow ? arrowComputeCallback : undefined,
@@ -207,7 +207,8 @@
207
207
  position: fixed !important;
208
208
  top: 0;
209
209
  left: 0;
210
- z-index: 50;
210
+ z-index: 110;
211
+ padding: 0.5rem !important;
211
212
  & .fs-tooltip-arrow {
212
213
  position: absolute;
213
214
  width: 16px;
@@ -14,7 +14,7 @@ export type TooltipProps = {
14
14
  /** The DOM reference of the tooltip element.
15
15
  * @bindable
16
16
  */
17
- ref?: HTMLElement;
17
+ ref?: HTMLElement | null;
18
18
  /** The element the tooltip is anchored to. Falls back to the rendered children. */
19
19
  target?: HTMLElement;
20
20
  /** Controls the open state of the tooltip.
@@ -137,7 +137,7 @@ A selected item sets its label in semibold, which is wider than the same label a
137
137
 
138
138
  | Name | Type | Default | Description |
139
139
  | -------------------------- | ------------------------------------------------------------------------------ | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
140
- | `ref` _bindable_ | `HTMLDivElement` | | The DOM reference of the strip. |
140
+ | `ref` _bindable_ | `HTMLDivElement` &#124; `null` | | The DOM reference of the strip. |
141
141
  | `selectedValue` _bindable_ | `string` | | The value of the selected item. |
142
142
  | `onTabSelect` | `(event: Event, value: string) => void` | | Fired when an item is selected. |
143
143
  | `appearance` | [`TopNavAppearance`](https://fluentui-svelte.dev/docs/types/#topnavappearance) | `'transparent'` | How the strip is painted: `transparent` has no background of its own, `subtle` fills an item while it is engaged, and the two circular appearances trade the moving bar for a pill. |
@@ -7,7 +7,7 @@
7
7
 
8
8
  let {
9
9
  as = 'button' as T,
10
- ref = $bindable(),
10
+ ref = $bindable(null),
11
11
  value = `${COMPONENT_NAME}-${ID}`,
12
12
  icon,
13
13
  disabled,
@@ -54,6 +54,7 @@
54
54
  -->
55
55
  <svelte:element
56
56
  this={_as}
57
+ {...attributes}
57
58
  bind:this={ref as TopNavItemElementDOMType[T]}
58
59
  type={_as === 'button' ? 'button' : undefined}
59
60
  role="tab"
@@ -73,7 +74,6 @@
73
74
  () => context.config.selectTabOnFocus && context.methods.selectTab(e, value),
74
75
  onfocus
75
76
  ])}
76
- {...attributes}
77
77
  >
78
78
  {#if icon}
79
79
  <span class="fs-top-nav-item-icon">
@@ -4,7 +4,7 @@
4
4
  import type { TopNavContext, TopNavProps } from './types.js';
5
5
 
6
6
  let {
7
- ref = $bindable(),
7
+ ref = $bindable(null),
8
8
  selectedValue = $bindable(''),
9
9
  onTabSelect,
10
10
  appearance = 'transparent',
@@ -172,12 +172,12 @@
172
172
  ```
173
173
  -->
174
174
  <div
175
+ {...attributes}
175
176
  bind:this={ref}
176
177
  role="tablist"
177
178
  aria-orientation={vertical ? 'vertical' : undefined}
178
179
  class={['fs-top-nav', appearance, size, { vertical }, classes]}
179
180
  {...tabspotAttributes}
180
- {...attributes}
181
181
  >
182
182
  {@render children?.()}
183
183
  {#if hasIndicator && measured}
@@ -27,7 +27,7 @@ export type TopNavProps = {
27
27
  /** The DOM reference of the strip.
28
28
  * @bindable
29
29
  */
30
- ref?: HTMLDivElement;
30
+ ref?: HTMLDivElement | null;
31
31
  /** The value of the selected item.
32
32
  * @bindable
33
33
  */
@@ -71,7 +71,7 @@ export type TopNavItemProps<T extends TopNavItemGenerics = 'button'> = {
71
71
  * @type TopNavItemElementDOMType[T]
72
72
  * @bindable
73
73
  */
74
- ref?: TopNavItemElementDOMType[T];
74
+ ref?: TopNavItemElementDOMType[T] | null;
75
75
  /** The DOM element to render. An anchor takes the attributes of one, `href` among them, and is
76
76
  * what an item that navigates should be.
77
77
  * @type 'button' | 'a'
@@ -244,7 +244,7 @@ Use the bindable `openItems` and `checkedItems` props on the root `TreeView` to
244
244
 
245
245
  | Name | Type | Default | Description |
246
246
  | --------------------------------------------------- | -------------------------------------------- | ------------ | ------------------------------------------------------------------------------------ |
247
- | `ref` _bindable_ | `HTMLUListElement` | | The DOM reference of the tree element. |
247
+ | `ref` _bindable_ | `HTMLUListElement` &#124; `null` | | The DOM reference of the tree element. |
248
248
  | `size` | `'small'` &#124; `'medium'` &#124; `'large'` | `'medium'` | The size of every item in the tree. |
249
249
  | `navigationMode` | `'tree'` &#124; `'treegrid'` | `'tree'` | Whether the tree takes a single tab stop, or every row is reachable on its own. |
250
250
  | `onOpenChange` | `(e: Event, openItems: string[]) => void` | | Called whenever a branch opens or closes. |
@@ -268,7 +268,7 @@ Use the bindable `openItems` and `checkedItems` props on the root `TreeView` to
268
268
  | ------------------------- | ------------------------------------------------------------ | -------- | -------------------------------------------------------------------------------------- |
269
269
  | `id` | `string` | | The id of the item, used by the tree to track its state. Falls back to a generated id. |
270
270
  | `type` | `'item'` &#124; `'branch'` | `'item'` | Whether the item holds children, and can therefore be opened. |
271
- | `ref` | `HTMLLIElement` | | The DOM reference of the item element. |
271
+ | `ref` | `HTMLLIElement` &#124; `null` | | The DOM reference of the item element. |
272
272
  | `value` | `string` &#124; `number` | `id` | The value reported by the tree events. Falls back to the id of the item. |
273
273
  | `text` | `string` | | The label of the item, used by the type-ahead navigation. |
274
274
  | `open` | `boolean` | | Whether the branch is open. |
@@ -287,14 +287,14 @@ Use the bindable `openItems` and `checkedItems` props on the root `TreeView` to
287
287
  <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
288
288
  <!-- props:TreeViewItemLayoutProps -->
289
289
 
290
- | Name | Type | Default | Description |
291
- | -------------------------- | ---------------------------- | ------- | --------------------------------------------------------------------- |
292
- | `ref` | `HTMLDivElement` | | The DOM reference of the layout element. |
293
- | `expandIcon` | `Snippet` &#124; `Component` | | Custom icon for the control that opens a branch. |
294
- | `iconBefore` | `Snippet` &#124; `Component` | | Content rendered before the label. |
295
- | `iconAfter` | `Snippet` &#124; `Component` | | Content rendered after the label. |
296
- | `aside` | `Snippet` &#124; `Component` | | Content pinned to the end of the row. |
297
- | `actions` | `Snippet` &#124; `Component` | | Content pinned to the end of the row, revealed on hover and on focus. |
298
- | Element Attributes (`div`) | | | |
290
+ | Name | Type | Default | Description |
291
+ | -------------------------- | ------------------------------ | ------- | --------------------------------------------------------------------- |
292
+ | `ref` | `HTMLDivElement` &#124; `null` | | The DOM reference of the layout element. |
293
+ | `expandIcon` | `Snippet` &#124; `Component` | | Custom icon for the control that opens a branch. |
294
+ | `iconBefore` | `Snippet` &#124; `Component` | | Content rendered before the label. |
295
+ | `iconAfter` | `Snippet` &#124; `Component` | | Content rendered after the label. |
296
+ | `aside` | `Snippet` &#124; `Component` | | Content pinned to the end of the row. |
297
+ | `actions` | `Snippet` &#124; `Component` | | Content pinned to the end of the row, revealed on hover and on focus. |
298
+ | Element Attributes (`div`) | | | |
299
299
 
300
300
  <!-- /props:TreeViewItemLayoutProps -->
@@ -24,10 +24,10 @@
24
24
  <!-- Presentational row. The interactive element is the parent treeitem (`<li>`); this
25
25
  div is plain markup so it is not exposed as a separate control. -->
26
26
  <div
27
- class={['fs-tree-view-item-content', `size-${size}`, ITEM_CONTEXT.disabled && 'disabled']}
28
- style="--depth: {ITEM_CONTEXT.depth}"
29
- bind:this={ref}
30
27
  {...attributes}
28
+ class={['fs-tree-view-item-content', `size-${size}`, ITEM_CONTEXT.disabled && 'disabled', attributes?.class]}
29
+ style="{attributes?.style ?? ''}; --depth: {ITEM_CONTEXT.depth}"
30
+ bind:this={ref}
31
31
  >
32
32
  {#if expandIcon}
33
33
  <span class="fs-tree-view-item-expand-icon">
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { onMount, tick } from 'svelte';
3
+ import { invokeHandlers } from '../../internal/index.js';
3
4
  import { PREFIX } from '../../internal/constants.js';
4
5
  import {
5
6
  getTreeViewDepth,
@@ -35,6 +36,8 @@
35
36
  onCheckedChange,
36
37
  onOpenChange,
37
38
  children,
39
+ onclick,
40
+ onkeydown,
38
41
  ...attributes
39
42
  }: TreeViewItemProps = $props();
40
43
 
@@ -110,6 +113,10 @@
110
113
  });
111
114
  }
112
115
 
116
+ // Tabspot sets the tab stop of the tree on mount; until then the server HTML gives it to the first
117
+ // enabled item, as Tabspot will, so the tree can be reached with Tab.
118
+ const holdsTabStop = $derived(!itemState.disabled && (context.state.tabStop.id ??= id) === id);
119
+
113
120
  const isBranch = $derived(type === 'branch');
114
121
  const isVirtualRoot = $derived(config.virtualized && !itemContext);
115
122
 
@@ -162,10 +169,12 @@
162
169
  </script>
163
170
 
164
171
  <li
172
+ {...attributes}
165
173
  {id}
166
- class={['fs-tree-view-item', `fs-tree-item-size-${size}`, { open }]}
167
- style="--depth: {depth}"
174
+ class={['fs-tree-view-item', `fs-tree-item-size-${size}`, { open }, attributes?.class]}
175
+ style="{attributes?.style ?? ''}; --depth: {depth}"
168
176
  role="treeitem"
177
+ tabindex={holdsTabStop ? 0 : undefined}
169
178
  aria-expanded={type === 'branch' ? open : undefined}
170
179
  aria-checked={indeterminate ? 'mixed' : checked}
171
180
  aria-level={depth + 1}
@@ -173,10 +182,9 @@
173
182
  data-index={isVirtualRoot ? index : undefined}
174
183
  data-value={value}
175
184
  aria-disabled={itemState.disabled ? 'true' : undefined}
176
- onclick={handleClick}
177
- onkeydown={handleKeydown}
185
+ onclick={(event) => invokeHandlers(event, itemState.disabled, [handleClick, onclick])}
186
+ onkeydown={(event) => invokeHandlers(event, itemState.disabled, [handleKeydown, onkeydown])}
178
187
  bind:this={ref}
179
- {...attributes}
180
188
  >
181
189
  {@render children?.()}
182
190
  </li>
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { onMount, tick } from 'svelte';
3
+ import { invokeHandlers } from '../../internal/index.js';
3
4
  import { SvelteMap, SvelteSet } from 'svelte/reactivity';
4
5
  import { getTabspotAttributes, tabspotVirtual } from 'tabspot';
5
6
  import {
@@ -8,6 +9,7 @@
8
9
  setTreeViewContext,
9
10
  setTreeViewDepth,
10
11
  getTreeViewItemContext,
12
+ syncBranchStates,
11
13
  traversalSync,
12
14
  traversalSyncSingleSelection
13
15
  } from './tree-view.svelte.js';
@@ -15,6 +17,7 @@
15
17
 
16
18
  const CONTEXT = getTreeViewContext();
17
19
  const TREE_NODES = new SvelteMap<string, TreeViewNode>();
20
+ const TAB_STOP: { id: string | null } = { id: null };
18
21
  const DEPTH = getTreeViewDepth() || 0;
19
22
  const ITEM_CONTEXT = getTreeViewItemContext();
20
23
  const IS_SUB_TREE = $derived(!!CONTEXT);
@@ -26,12 +29,13 @@
26
29
  navigationMode = CONTEXT?.config.navigationMode ?? 'tree',
27
30
  checkedItems = $bindable(CONTEXT?.state.checkedItems ?? (virtualizer !== undefined ? new SvelteSet<string>() : [])),
28
31
  openItems = $bindable(CONTEXT?.state.openItems ?? (virtualizer !== undefined ? new SvelteSet<string>() : [])),
29
- ref = $bindable(),
32
+ ref = $bindable(null),
30
33
  onOpenChange,
31
34
  onCheckedChange,
32
35
  selectionMode = CONTEXT?.state.selectionMode ?? 'multiple',
33
36
  size = 'medium',
34
37
  children,
38
+ onkeydown,
35
39
  ...attributes
36
40
  }: TreeViewProps = $props();
37
41
 
@@ -65,6 +69,9 @@
65
69
  get TREE_NODES() {
66
70
  return CONTEXT?.state.TREE_NODES ?? TREE_NODES;
67
71
  },
72
+ get tabStop() {
73
+ return CONTEXT?.state.tabStop ?? TAB_STOP;
74
+ },
68
75
  get forceVirtualRender() {
69
76
  return CONTEXT?.state.forceVirtualRender ?? forceVirtualRender;
70
77
  },
@@ -195,6 +202,14 @@
195
202
  };
196
203
 
197
204
  // Add tabspot virtualizer for correct focus management
205
+ // Once every item is registered, the branches show what their checked descendants imply. A
206
+ // virtualized tree registers only the rows on screen, so it would judge a branch on a part of it.
207
+ onMount(async () => {
208
+ if (IS_SUB_TREE || virtualizer || selectionMode === 'single') return;
209
+ await tick();
210
+ syncBranchStates(TREE_NODES, checkedItems);
211
+ });
212
+
198
213
  onMount(() => {
199
214
  if (!IS_SUB_TREE || !ref || !virtualizer) return;
200
215
  return tabspotVirtual(ref, {
@@ -207,13 +222,13 @@
207
222
  <!-- Render only when necessary (virtualizer perf) -->
208
223
  {#if treeViewContext.state.forceVirtualRender || (treeViewContext.config.virtualized && (!IS_SUB_TREE || ITEM_CONTEXT?.open)) || !treeViewContext.config.virtualized}
209
224
  <ul
210
- class="fs-tree-view"
225
+ {...attributes}
226
+ class={['fs-tree-view', attributes?.class]}
211
227
  role={IS_SUB_TREE ? 'group' : 'tree'}
212
- aria-multiselectable={selectionMode !== 'single'}
213
- onkeydown={!IS_SUB_TREE ? handleTypeahead : undefined}
228
+ aria-multiselectable={IS_SUB_TREE ? undefined : selectionMode !== 'single'}
229
+ onkeydown={(event) => invokeHandlers(event, [], [!IS_SUB_TREE && handleTypeahead, onkeydown])}
214
230
  bind:this={ref}
215
231
  {...tabspotAttributes}
216
- {...attributes}
217
232
  >
218
233
  {@render children?.()}
219
234
  </ul>
@@ -1,4 +1,4 @@
1
1
  import type { TreeViewProps } from './types.js';
2
- declare const TreeView: import("svelte").Component<TreeViewProps, {}, "ref" | "openItems" | "checkedItems">;
2
+ declare const TreeView: import("svelte").Component<TreeViewProps, {}, "ref" | "checkedItems" | "openItems">;
3
3
  type TreeView = ReturnType<typeof TreeView>;
4
4
  export default TreeView;
@@ -1,4 +1,5 @@
1
1
  import { createFSContext } from '../../internal/index.js';
2
+ import { SvelteSet } from 'svelte/reactivity';
2
3
  export const [getTreeViewContext, setTreeViewContext] = createFSContext();
3
4
  export const [getTreeViewDepth, setTreeViewDepth] = createFSContext();
4
5
  export const [getTreeViewItemContext, setTreeViewItemContext] = createFSContext();
@@ -74,17 +75,44 @@ export function traversalSync(itemId, state, iterable, checked) {
74
75
  if (node.parentId) {
75
76
  bubbleCheck(node.id, state, checked, isIndeterminate);
76
77
  }
77
- const checkedItems = Array.from(state.values()).filter((n) => n.checked);
78
+ syncCheckedItems(state, iterable);
79
+ }
80
+ /** Writes the ids of the checked nodes into the set or array of the tree. */
81
+ function syncCheckedItems(state, iterable) {
82
+ writeItems(iterable, Array.from(state.values())
83
+ .filter((n) => n.checked)
84
+ .map(({ id }) => id));
85
+ }
86
+ /** Replaces the ids in the set or array of the tree. */
87
+ function writeItems(iterable, ids) {
78
88
  if (iterable instanceof Set) {
79
89
  iterable.clear();
80
- for (const { id } of checkedItems) {
90
+ for (const id of ids) {
81
91
  iterable.add(id);
82
92
  }
83
93
  }
84
94
  else if (Array.isArray(iterable)) {
85
95
  iterable.length = 0;
86
- iterable.push(...checkedItems.map(({ id }) => id));
96
+ iterable.push(...ids);
97
+ }
98
+ }
99
+ /**
100
+ * Gives each branch the state its checked descendants imply, as a click would: a tree can start
101
+ * with only some of the items of a branch checked. The set or array is written only if it changes,
102
+ * and keeps the ids of items that are not in the tree yet.
103
+ */
104
+ export function syncBranchStates(state, iterable) {
105
+ for (const node of Array.from(state.values())) {
106
+ if (node.checked && node.parentId)
107
+ bubbleCheck(node.id, state, true);
87
108
  }
109
+ const before = Array.from(iterable);
110
+ const kept = before.filter((id) => state.get(id)?.checked ?? true);
111
+ const added = Array.from(state.values())
112
+ .filter((n) => n.checked && !kept.includes(n.id))
113
+ .map(({ id }) => id);
114
+ if (added.length || kept.length !== before.length)
115
+ writeItems(iterable, [...kept, ...added]);
88
116
  }
89
117
  export function traversalSyncSingleSelection(itemId, state, iterable) {
90
118
  const node = state.get(itemId);
@@ -49,7 +49,7 @@ export type TreeViewProps = {
49
49
  /** The DOM reference of the tree element.
50
50
  * @bindable
51
51
  */
52
- ref?: HTMLUListElement;
52
+ ref?: HTMLUListElement | null;
53
53
  /** The size of every item in the tree.
54
54
  * @default 'medium'
55
55
  */
@@ -96,7 +96,7 @@ export type TreeViewItemProps = {
96
96
  */
97
97
  type?: TreeViewItemType;
98
98
  /** The DOM reference of the item element. */
99
- ref?: HTMLLIElement;
99
+ ref?: HTMLLIElement | null;
100
100
  /** The value reported by the tree events. Falls back to the id of the item.
101
101
  * @default id
102
102
  */
@@ -131,7 +131,7 @@ export type TreeViewItemProps = {
131
131
  /** @propsmith TreeViewItemLayoutProps */
132
132
  export type TreeViewItemLayoutProps = {
133
133
  /** The DOM reference of the layout element. */
134
- ref?: HTMLDivElement;
134
+ ref?: HTMLDivElement | null;
135
135
  /** Custom icon for the control that opens a branch.
136
136
  * @type Snippet | Component
137
137
  */
@@ -163,6 +163,10 @@ export type TreeViewContext = FSContext<{
163
163
  readonly openItems: NonNullable<TreeViewProps['openItems']>;
164
164
  readonly checkedItems: NonNullable<TreeViewProps['checkedItems']>;
165
165
  readonly TREE_NODES: SvelteMap<string, TreeViewNode>;
166
+ /** The item that holds the tab stop in the server HTML, before Tabspot runs. */
167
+ readonly tabStop: {
168
+ id: string | null;
169
+ };
166
170
  forceVirtualRender: boolean;
167
171
  }, {
168
172
  onOpenChange: TreeViewEvent<string[]>;