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
@@ -0,0 +1,355 @@
1
+ <script lang="ts">
2
+ import { onDestroy } from 'svelte';
3
+ import { onClickOutside } from 'runed';
4
+ import NavigationRegular from 'fluentui-icons-svelte/NavigationRegular.svelte';
5
+ import Button from '../button/button.svelte';
6
+ import { getAppWindowContext } from '../app-window/app-window.js';
7
+ import { invokeHandlers, RenderSoC, toLength } from '../../internal/index.js';
8
+ import { PREFIX } from '../../internal/constants.js';
9
+ import SideNavList from './side-nav-list.svelte';
10
+ import { setSideNavContext } from './side-nav.js';
11
+ import type { SideNavContent, SideNavContext, SideNavProps } from './types.js';
12
+
13
+ const FALLBACK_ID = $props.id();
14
+ const COMPONENT_NAME = 'side-nav';
15
+ const BODY_ID = `${PREFIX}-${COMPONENT_NAME}-${FALLBACK_ID}`;
16
+
17
+ let {
18
+ ref = $bindable(null),
19
+ label = 'Main navigation',
20
+ collapsed = $bindable(false),
21
+ position = 'left',
22
+ showToggle,
23
+ floating = false,
24
+ width = 200,
25
+ expandLabel = 'Expand navigation',
26
+ collapseLabel = 'Collapse navigation',
27
+ closeOnSelect = true,
28
+ onCollapsedChange,
29
+ selectedItems = $bindable([]),
30
+ listViewProps,
31
+ header,
32
+ topContent,
33
+ footerContent,
34
+ footer,
35
+ children,
36
+ onkeydown,
37
+ onfocusout,
38
+ class: classes,
39
+ ...attributes
40
+ }: SideNavProps = $props();
41
+
42
+ let toggleRef = $state<HTMLButtonElement | null>(null);
43
+
44
+ /** Docked, a collapsed navigation is a rail of icons. Floating, it is only the toggle. */
45
+ const compact = $derived(collapsed && !floating);
46
+ const toggleLabel = $derived(collapsed ? expandLabel : collapseLabel);
47
+
48
+ function setCollapsed(event: Event, value: boolean) {
49
+ if (collapsed === value) return;
50
+ collapsed = value;
51
+ onCollapsedChange?.(event, value);
52
+ }
53
+
54
+ const context: SideNavContext = {
55
+ config: {
56
+ get floating() {
57
+ return floating;
58
+ },
59
+ get listViewProps() {
60
+ return listViewProps;
61
+ }
62
+ },
63
+ state: {
64
+ get collapsed() {
65
+ return collapsed;
66
+ },
67
+ get compact() {
68
+ return compact;
69
+ },
70
+ get selectedItems() {
71
+ return selectedItems;
72
+ },
73
+ set selectedItems(value) {
74
+ selectedItems = value;
75
+ }
76
+ },
77
+ events: null,
78
+ methods: {
79
+ setCollapsed,
80
+ activate: (event) => {
81
+ if (floating && closeOnSelect && !event.defaultPrevented) setCollapsed(event, true);
82
+ }
83
+ }
84
+ };
85
+ setSideNavContext(context);
86
+
87
+ const appWindow = getAppWindowContext();
88
+ // The global navigation button of the title bar controls the navigation, and takes the place of its own toggle.
89
+ const globalNav = $derived(appWindow?.state.globalNav);
90
+ const toggleVisible = $derived(showToggle ?? !globalNav?.enabled);
91
+ // Without a toggle, the navigation itself is where the focus lands when a floating one closes: it takes focus, but is not a tab stop.
92
+ const focusTarget = $derived(toggleVisible ? {} : { tabindex: -1 });
93
+
94
+ const unregister = appWindow?.methods.registerSideNav({
95
+ get ref() {
96
+ return ref;
97
+ },
98
+ get collapsed() {
99
+ return collapsed;
100
+ },
101
+ get floating() {
102
+ return floating;
103
+ },
104
+ get position() {
105
+ return position;
106
+ },
107
+ setCollapsed
108
+ });
109
+ onDestroy(() => unregister?.());
110
+
111
+ // The body of a floating navigation hides when it closes, so the focus moves to the button that opens it first.
112
+ $effect.pre(() => {
113
+ if (floating && collapsed && ref?.contains(ref.ownerDocument.activeElement))
114
+ (toggleRef ?? globalNav?.ref ?? ref)?.focus();
115
+ });
116
+
117
+ /** The button of the title bar that opens and closes the navigation is not outside it: its own click toggles it. */
118
+ const isGlobalNav = (target: EventTarget | null) => target instanceof Node && !!globalNav?.ref?.contains(target);
119
+
120
+ // A floating navigation is not modal: it closes with an outside press, with Escape and when the focus leaves it.
121
+ onClickOutside(
122
+ () => ref,
123
+ (event) => {
124
+ if (floating && !collapsed && !isGlobalNav(event.target)) setCollapsed(event, true);
125
+ }
126
+ );
127
+
128
+ function handleKeydown(event: KeyboardEvent) {
129
+ // Escape belongs to a nested disclosure or menu first: they cancel it when they handle it.
130
+ if (event.defaultPrevented || !floating || collapsed || event.key !== 'Escape') return;
131
+ event.preventDefault();
132
+ event.stopPropagation();
133
+ setCollapsed(event, true);
134
+ }
135
+
136
+ function handleFocusout(event: FocusEvent) {
137
+ const next = event.relatedTarget;
138
+ if (floating && !collapsed && next instanceof Node && !ref?.contains(next) && !isGlobalNav(next))
139
+ setCollapsed(event, true);
140
+ }
141
+ </script>
142
+
143
+ {#snippet region(value?: SideNavContent)}
144
+ {#if value && !(compact && typeof value === 'string')}
145
+ <div class="fs-side-nav-content">
146
+ {#if typeof value === 'string'}
147
+ {value}
148
+ {:else}
149
+ <RenderSoC SoC={value} args={{ collapsed, floating }} />
150
+ {/if}
151
+ </div>
152
+ {/if}
153
+ {/snippet}
154
+
155
+ <!--
156
+ @component
157
+ Collapsible app navigation. Place it directly inside AppWindow next to AppSurface.
158
+ AppWindow handles docked layout and the floating overlay below its title bar.
159
+ Use SideNavItem for links and SideNavBranch for nested navigation.
160
+
161
+ - Usage:
162
+ ```tsx
163
+ <script>
164
+ import { AppSurface, AppWindow, SideNav, SideNavItem } from 'fluentui-svelte';
165
+ import { HomeRegular } from 'fluentui-icons-svelte';
166
+ </script>
167
+
168
+ <AppWindow width={480} height={320}>
169
+ <SideNav header="My app">
170
+ <SideNavItem href="/" label="Home" icon={HomeRegular} />
171
+ </SideNav>
172
+ <AppSurface>The content of the app.</AppSurface>
173
+ </AppWindow>
174
+ ```
175
+ -->
176
+ <nav
177
+ aria-label={label}
178
+ {...focusTarget}
179
+ {...attributes}
180
+ bind:this={ref}
181
+ class={[
182
+ 'fs-side-nav',
183
+ { collapsed, floating, compact, 'no-toggle': !toggleVisible, 'position-right': position === 'right' },
184
+ classes
185
+ ]}
186
+ style:--fs-side-nav-width={toLength(width)}
187
+ onkeydown={(e) => invokeHandlers(e, [], [onkeydown, handleKeydown])}
188
+ onfocusout={(e) => invokeHandlers(e, [], [onfocusout, handleFocusout])}
189
+ >
190
+ {#if toggleVisible || (header && !collapsed)}
191
+ <div class={['fs-side-nav-header', { 'no-toggle': !toggleVisible }]}>
192
+ {#if toggleVisible}
193
+ <Button
194
+ bind:ref={toggleRef}
195
+ type="button"
196
+ appearance="subtle"
197
+ class="fs-side-nav-toggle"
198
+ aria-label={toggleLabel}
199
+ title={toggleLabel}
200
+ aria-controls={BODY_ID}
201
+ aria-expanded={!collapsed}
202
+ onclick={(event) => setCollapsed(event, !collapsed)}
203
+ >
204
+ <NavigationRegular aria-hidden="true" />
205
+ </Button>
206
+ {/if}
207
+ {#if header && !collapsed}
208
+ <span class="fs-side-nav-heading">{header}</span>
209
+ {/if}
210
+ </div>
211
+ {/if}
212
+ <div id={BODY_ID} class="fs-side-nav-body" hidden={floating && collapsed}>
213
+ {@render region(topContent)}
214
+
215
+ <div class="fs-side-nav-items">
216
+ <SideNavList>
217
+ {@render children?.()}
218
+ </SideNavList>
219
+ </div>
220
+
221
+ {#if footerContent || footer}
222
+ <div class="fs-side-nav-footer">
223
+ {@render region(footerContent)}
224
+
225
+ {#if footer}
226
+ <SideNavList>
227
+ {@render footer()}
228
+ </SideNavList>
229
+ {/if}
230
+ </div>
231
+ {/if}
232
+ </div>
233
+ </nav>
234
+
235
+ <style>
236
+ .fs-side-nav {
237
+ box-sizing: border-box;
238
+ position: relative;
239
+ display: flex;
240
+ flex-direction: column;
241
+ flex: none;
242
+ inline-size: var(--fs-side-nav-width);
243
+ max-inline-size: 100%;
244
+ min-block-size: 0;
245
+ color: var(--fs-text-primary);
246
+ font-family: var(--fs-font-family-base);
247
+ font-size: var(--fs-body-font-size);
248
+ /* The line of its items and toggle, which the buttons of a TitleBar share. */
249
+ line-height: 1.4;
250
+ padding-top: 0.25rem;
251
+ /* Without its own toggle the list sits right under the title bar, which already has its button. */
252
+ &.no-toggle:not(.floating) {
253
+ padding-top: 0;
254
+ }
255
+ &.collapsed {
256
+ /* The rail is one item wide: its icon (1rem) and the padding of the item (0.5rem) and of the list (0.25rem). */
257
+ inline-size: 2.5rem;
258
+ & .fs-side-nav-content {
259
+ padding-bottom: 0;
260
+ }
261
+ }
262
+ &.floating {
263
+ position: absolute;
264
+ inset-block: 0;
265
+ inset-inline-start: 0;
266
+ z-index: 3;
267
+ &.position-right {
268
+ inset-inline: auto 0;
269
+ }
270
+ &:not(.collapsed) {
271
+ background: var(--fs-acrylic-background-default);
272
+ border: 1px solid var(--fs-control-surface-stroke-flyout);
273
+ border-radius: var(--fs-control-overlay-border-radius);
274
+ box-shadow: var(--fs-shadow-flyout);
275
+ }
276
+ &.collapsed {
277
+ /* Only the toggle is left, and the content below it stays reachable. */
278
+ pointer-events: none;
279
+ }
280
+ }
281
+ /* The icons keep their place in the rail and out of it, aligned with the toggle. */
282
+ & :global(.fs-list-view-item),
283
+ & :global(.fs-list-view-item-branch-trigger) {
284
+ padding-inline: 0.5rem;
285
+ margin: 0.2rem 0;
286
+ }
287
+ &.compact {
288
+ & :global(.fs-list-view-item-branch-region),
289
+ & :global(.branch-chevron) {
290
+ display: none;
291
+ }
292
+ /* The label still names the branch for assistive technology. */
293
+ & :global(.fs-list-view-branch-label) {
294
+ position: absolute;
295
+ inline-size: 1px;
296
+ block-size: 1px;
297
+ clip-path: inset(50%);
298
+ overflow: hidden;
299
+ }
300
+ & .fs-side-nav-content {
301
+ padding-inline: 0.25rem;
302
+ }
303
+ }
304
+ }
305
+ .fs-side-nav-header {
306
+ display: flex;
307
+ align-items: center;
308
+ flex: none;
309
+ gap: 0.5rem;
310
+ padding-inline: 0.25rem;
311
+ box-sizing: border-box;
312
+ &.no-toggle {
313
+ padding-inline: 0.75rem;
314
+ }
315
+ /* The toggle is the size of an item: the same padding around an icon, and the same line of text under it. */
316
+ & :global(.fs-side-nav-toggle) {
317
+ flex: none;
318
+ padding: 0.275rem 0.5rem 0.4rem;
319
+ font-size: var(--fs-body2-font-size);
320
+ line-height: inherit;
321
+ min-block-size: calc(1lh + 0.675rem);
322
+ pointer-events: auto;
323
+ & :global(svg) {
324
+ inline-size: 1rem;
325
+ block-size: 1rem;
326
+ }
327
+ }
328
+ }
329
+ .fs-side-nav-heading {
330
+ min-inline-size: 0;
331
+ font-weight: 600;
332
+ }
333
+ .fs-side-nav-body {
334
+ display: flex;
335
+ flex-direction: column;
336
+ flex: 1;
337
+ min-block-size: 0;
338
+ &[hidden] {
339
+ display: none;
340
+ }
341
+ }
342
+ .fs-side-nav-content {
343
+ padding: 0.125rem 0.25rem 0.125rem 0.75rem;
344
+ }
345
+ .fs-side-nav-items {
346
+ flex: 1;
347
+ min-block-size: 0;
348
+ overflow: auto;
349
+ padding-inline: 0.25rem;
350
+ }
351
+ .fs-side-nav-footer {
352
+ flex: none;
353
+ padding: 0.125rem 0.25rem;
354
+ }
355
+ </style>
@@ -0,0 +1,24 @@
1
+ import type { SideNavProps } from './types.ts';
2
+ /**
3
+ * Collapsible app navigation. Place it directly inside AppWindow next to AppSurface.
4
+ * AppWindow handles docked layout and the floating overlay below its title bar.
5
+ * Use SideNavItem for links and SideNavBranch for nested navigation.
6
+ *
7
+ * - Usage:
8
+ * ```tsx
9
+ * <script>
10
+ * import { AppSurface, AppWindow, SideNav, SideNavItem } from 'fluentui-svelte';
11
+ * import { HomeRegular } from 'fluentui-icons-svelte';
12
+ * </script>
13
+ *
14
+ * <AppWindow width={480} height={320}>
15
+ * <SideNav header="My app">
16
+ * <SideNavItem href="/" label="Home" icon={HomeRegular} />
17
+ * </SideNav>
18
+ * <AppSurface>The content of the app.</AppSurface>
19
+ * </AppWindow>
20
+ * ```
21
+ */
22
+ declare const SideNav: import("svelte").Component<SideNavProps, {}, "ref" | "selectedItems" | "collapsed">;
23
+ type SideNav = ReturnType<typeof SideNav>;
24
+ export default SideNav;
@@ -0,0 +1,149 @@
1
+ import type { Component, Snippet } from 'svelte';
2
+ import type { HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
3
+ import type { FSContext } from '../../internal/index.js';
4
+ import type { PolymorphicProps } from '../../types/index.js';
5
+ import type { ListViewItemBranchProps, ListViewItemDOM, ListViewItemProps, ListViewProps } from '../list-view/types.ts';
6
+ export type SideNavRenderState = {
7
+ collapsed: boolean;
8
+ floating: boolean;
9
+ };
10
+ export type SideNavContent = string | Snippet<[SideNavRenderState]> | Component<SideNavRenderState>;
11
+ export type SideNavListViewProps = Omit<ListViewProps<'ul'>, 'children' | 'ref' | 'selectedItems'>;
12
+ /** @propsmith SideNavProps */
13
+ export type SideNavProps = {
14
+ /** The DOM reference of the navigation landmark.
15
+ * @bindable
16
+ */
17
+ ref?: HTMLElement | null;
18
+ /** The accessible name of the navigation landmark.
19
+ * @default 'Main navigation'
20
+ */
21
+ label?: string;
22
+ /** Shows an icon rail when docked, or only the toggle when floating.
23
+ * @default false
24
+ * @bindable
25
+ */
26
+ collapsed?: boolean;
27
+ /** The side of the window the navigation is on. It mirrors in right-to-left layouts, and AppSurface rounds the corners that face it.
28
+ * @default 'left'
29
+ */
30
+ position?: 'left' | 'right';
31
+ /** Whether the navigation shows its own hamburger toggle. By default it hides it when the title bar of its window has a global navigation button, which then controls the navigation. Set it to true to keep both, or to false to control the navigation yourself.
32
+ * @default Automatic
33
+ */
34
+ showToggle?: boolean;
35
+ /** Overlays the content of a positioned parent instead of taking layout space. The overlay is non-modal.
36
+ * @default false
37
+ */
38
+ floating?: boolean;
39
+ /** The expanded width. Numbers are pixels converted to rem; strings are CSS lengths.
40
+ * @default 200
41
+ */
42
+ width?: number | string;
43
+ /** The accessible label of the toggle while collapsed.
44
+ * @default 'Expand navigation'
45
+ */
46
+ expandLabel?: string;
47
+ /** The accessible label of the toggle while expanded.
48
+ * @default 'Collapse navigation'
49
+ */
50
+ collapseLabel?: string;
51
+ /** Closes a floating panel after activating a SideNavItem.
52
+ * @default true
53
+ */
54
+ closeOnSelect?: boolean;
55
+ /** Called when the user expands or collapses the navigation. */
56
+ onCollapsedChange?: (event: Event, collapsed: boolean) => void;
57
+ /** The selection shared by every list in the navigation. Selection is off by default.
58
+ * @bindable
59
+ */
60
+ selectedItems?: string[];
61
+ /** Overrides the defaults of every list in the navigation, the main one, the footer and the ones inside a SideNavBranch: native list semantics, no selection and one tab stop per item.
62
+ * @type SideNavListViewProps
63
+ */
64
+ listViewProps?: SideNavListViewProps;
65
+ /** The text heading beside the hamburger button. Hidden in the compact rail. */
66
+ header?: string;
67
+ /** Custom content between the hamburger section and the list. Text, snippets and components are supported. Renderers receive collapsed and floating; strings are hidden in the compact rail.
68
+ * @type string | Snippet | Component
69
+ */
70
+ topContent?: SideNavContent;
71
+ /** Custom content after the scrolling list and before the pinned footer. Text, snippets and components are supported. Renderers receive collapsed and floating; strings are hidden in the compact rail.
72
+ * @type string | Snippet | Component
73
+ */
74
+ footerContent?: SideNavContent;
75
+ /** Footer list items pinned to the bottom, outside the main list's scroll area. */
76
+ footer?: Snippet;
77
+ /** Main navigation items. Use SideNavItem and SideNavBranch. */
78
+ children?: Snippet;
79
+ } & Omit<HTMLAttributes<HTMLElement>, 'children'>;
80
+ /** @propsmith SideNavItemProps */
81
+ export type SideNavItemProps<T extends 'li' | 'a' | 'button' | 'div' = 'a'> = {
82
+ /** The HTML tag. Links are the default; use button for actions and li or div for custom controls.
83
+ * @type 'li' | 'a' | 'button' | 'div'
84
+ * @default 'a'
85
+ */
86
+ as?: T;
87
+ /** The DOM reference of the item.
88
+ * @type HTMLLIElement | HTMLAnchorElement | HTMLButtonElement | HTMLDivElement
89
+ * @bindable
90
+ */
91
+ ref?: ListViewItemDOM[T] | null;
92
+ /** The accessible label, also used as visible content when children are absent. */
93
+ label: string;
94
+ /** The decorative icon shown in both expanded and collapsed modes.
95
+ * @type Snippet | Component
96
+ */
97
+ icon?: Snippet | Component;
98
+ /** Optional item markup, following ListViewItem. The label is rendered when children are absent. */
99
+ children?: Snippet;
100
+ } & Pick<ListViewItemProps, 'shape' | 'value' | 'active' | 'role' | 'disabled' | 'checkmark' | 'onAction' | 'onfocus'> & PolymorphicProps<T, 'children' | 'ref' | 'onfocus'>;
101
+ /** @propsmith SideNavBranchProps */
102
+ export type SideNavBranchProps = {
103
+ /** The accessible label of the disclosure button. In the compact rail, its initial stands in when there is no icon. */
104
+ label: string;
105
+ /** The decorative icon before the label.
106
+ * @type Snippet | Component
107
+ */
108
+ icon?: Snippet | Component;
109
+ /** Whether the nested items are visible. Branches only expand or collapse and are never selectable. The compact rail reports a branch as collapsed, and opens the navigation when one is pressed.
110
+ * @default false
111
+ * @bindable
112
+ */
113
+ expanded?: boolean;
114
+ /** Called when a user expands or collapses the branch. */
115
+ onExpandedChange?: (e: Event, expanded: boolean) => void;
116
+ /** Disables the disclosure button.
117
+ * @default false
118
+ */
119
+ disabled?: boolean;
120
+ /** The DOM reference of the native disclosure button. Additional HTML attributes, including class and id, also target this button.
121
+ * @type HTMLButtonElement
122
+ * @bindable
123
+ */
124
+ ref?: HTMLButtonElement | null;
125
+ /** The DOM reference of the wrapper element, the list item that holds the button and the nested list.
126
+ * @type HTMLLIElement | HTMLDivElement
127
+ * @bindable
128
+ */
129
+ wrapperRef?: HTMLLIElement | HTMLDivElement | null;
130
+ /** The attributes to spread on the wrapper element.
131
+ * @type HTMLAttributes
132
+ */
133
+ wrapperAttributes?: HTMLAttributes<HTMLLIElement | HTMLDivElement>;
134
+ /** The disclosure button shape. Inherited from the list by default. */
135
+ shape?: ListViewItemBranchProps['shape'];
136
+ /** The nested SideNavItem and SideNavBranch content. */
137
+ children?: Snippet;
138
+ } & Omit<HTMLButtonAttributes, 'children' | 'role' | 'type' | 'value' | 'aria-expanded' | 'aria-controls'>;
139
+ export type SideNavContext = FSContext<{
140
+ readonly floating: boolean;
141
+ readonly listViewProps: SideNavListViewProps | undefined;
142
+ }, {
143
+ readonly collapsed: boolean;
144
+ readonly compact: boolean;
145
+ selectedItems: string[];
146
+ }, null, {
147
+ setCollapsed: (event: Event, collapsed: boolean) => void;
148
+ activate: (event: Event) => void;
149
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -66,7 +66,7 @@ The `as` prop lets you choose the HTML tag used to render the skeleton. Possible
66
66
  | `animation` | `'wave'` &#124; `'pulse'` | `'wave'` | The animation played while the content is loading. |
67
67
  | `shape` | `'circular'` &#124; `'rounded'` &#124; `'square'` | `'rounded'` | The skeleton can have a circular, rounded or square shape. |
68
68
  | `justify` | `boolean` | | The skeleton is justified to the full width of the container. |
69
- | `ref` _bindable_ | `HTMLElement` | | The DOM reference of the skeleton element. |
69
+ | `ref` _bindable_ | `HTMLElement` &#124; `null` | | The DOM reference of the skeleton element. |
70
70
  | HTML Attributes | | | |
71
71
 
72
72
  <!-- /props:SkeletonProps -->
@@ -8,7 +8,7 @@
8
8
  shape = 'rounded',
9
9
  justify,
10
10
  class: classes,
11
- ref = $bindable(),
11
+ ref = $bindable(null),
12
12
  ...attributes
13
13
  }: SkeletonProps<Tag> = $props();
14
14
 
@@ -36,10 +36,10 @@
36
36
  -->
37
37
  <svelte:element
38
38
  this={as}
39
+ {...attributes}
39
40
  bind:this={ref}
40
41
  aria-hidden="true"
41
42
  class={['fs-skeleton', animation, shape, classes, { justify }]}
42
- {...attributes}
43
43
  ></svelte:element>
44
44
 
45
45
  <style>
@@ -20,5 +20,5 @@ export type SkeletonProps<Tag extends SkeletonTags = 'div'> = {
20
20
  /** The DOM reference of the skeleton element.
21
21
  * @bindable
22
22
  */
23
- ref?: HTMLElement;
23
+ ref?: HTMLElement | null;
24
24
  } & PolymorphicProps<Tag>;
@@ -50,38 +50,41 @@ Set the `disabled` prop to prevent interaction with the slider.
50
50
  <Slider value={30} disabled />
51
51
  ```
52
52
 
53
+ The root is the control element. HTML attributes, class and ref apply to that element. There is no separate wrapper API.
54
+
53
55
  ## Component Props
54
56
 
55
57
  <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
56
58
  <!-- props:SliderProps -->
57
59
 
58
- | Name | Type | Default | Description |
59
- | -------------------------- | --------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------- |
60
- | `value` _bindable_ | `number` | `0` | The current value of the slider. |
61
- | `min` | `number` | `0` | The minimum value of the slider. |
62
- | `max` | `number` | `100` | The maximum value of the slider. |
63
- | `step` | `number` | `1` | How much the value moves on every step. |
64
- | `ticks` | `number[]` | `[]` | The values the tick marks are drawn at. |
65
- | `tickPlacement` | `'around'` &#124; `'before'` &#124; `'after'` | `'around'` | Where the tick marks sit relative to the rail. |
66
- | `prefix` | `string` | `''` | Text prepended to the value in the tooltip. |
67
- | `suffix` | `string` | `''` | Text appended to the value in the tooltip. |
68
- | `track` | `boolean` | `true` | Whether to fill the rail up to the current value. |
69
- | `orientation` | `'horizontal'` &#124; `'vertical'` | `'horizontal'` | The direction the slider runs in. |
70
- | `reverse` | `boolean` | `false` | Runs the slider from the maximum to the minimum instead. |
71
- | `disabled` | `boolean` | `false` | Disables the user interaction. |
72
- | `sync` | `boolean` | | Snaps the thumb to the pointer as soon as it is pressed, instead of stepping towards it. |
73
- | `tooltip` | `boolean` | `true` | Whether to show the value in a tooltip while dragging. |
74
- | `tooltipPlacement` | `Placement` | `'top'` | Where the tooltip is placed relative to the thumb. |
75
- | `tooltipContent` | `string` &#124; `Snippet` &#124; `Component` | | Custom content for the tooltip, replacing the plain value. |
76
- | `onChange` | `(value: number) => void` | | Called whenever the value changes. |
77
- | `class` | `string` | | The class to apply to the slider. |
78
- | `ref` _bindable_ | `HTMLElement` | | The DOM reference of the slider element. |
79
- | `inputRef` _bindable_ | `HTMLInputElement` | | The DOM reference of the underlying input element. |
80
- | `thumbRef` _bindable_ | `HTMLElement` | | The DOM reference of the thumb element. |
81
- | `tooltipRef` _bindable_ | `HTMLElement` | | The DOM reference of the tooltip element. |
82
- | `railRef` _bindable_ | `HTMLElement` | | The DOM reference of the rail element. |
83
- | `trackRef` _bindable_ | `HTMLElement` | | The DOM reference of the track element. |
84
- | `tickBarRef` _bindable_ | `HTMLElement` | | The DOM reference of the tick bar element. |
85
- | Element Attributes (`div`) | | | |
60
+ | Name | Type | Default | Description |
61
+ | -------------------------------------------- | --------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
62
+ | `value` _bindable_ | `number` | `0` | The current value of the slider. |
63
+ | `defaultValue` | `number` | `min` | The value a form reset returns the slider to. A range input without one would fall back to an empty value. |
64
+ | `min` | `number` | `0` | The minimum value of the slider. |
65
+ | `max` | `number` | `100` | The maximum value of the slider. |
66
+ | `step` | `number` | `1` | How much the value moves on every step. |
67
+ | `ticks` | `number[]` | `[]` | The values the tick marks are drawn at. |
68
+ | `tickPlacement` | `'around'` &#124; `'before'` &#124; `'after'` | `'around'` | Where the tick marks sit relative to the rail. |
69
+ | `prefix` | `string` | `''` | Text prepended to the value in the tooltip. |
70
+ | `suffix` | `string` | `''` | Text appended to the value in the tooltip. |
71
+ | `track` | `boolean` | `true` | Whether to fill the rail up to the current value. |
72
+ | `orientation` | `'horizontal'` &#124; `'vertical'` | `'horizontal'` | The direction the slider runs in. |
73
+ | `reverse` | `boolean` | `false` | Runs the slider from the maximum to the minimum instead. |
74
+ | `disabled` | `boolean` | `false` | Disables the user interaction. |
75
+ | `sync` | `boolean` | | Snaps the thumb to the pointer as soon as it is pressed, instead of stepping towards it. Without it, a value between two steps is drawn as it is, while the native input, and so the form, holds the nearest step. |
76
+ | `tooltip` | `boolean` | `true` | Whether to show the value in a tooltip while dragging. |
77
+ | `tooltipPlacement` | `Placement` | `'top'` | Where the tooltip is placed relative to the thumb. |
78
+ | `tooltipContent` | `string` &#124; `Snippet` &#124; `Component` | | Custom content for the tooltip, replacing the plain value. |
79
+ | `onChange` | `(value: number) => void` | | Called whenever the value changes. |
80
+ | `ref` _bindable_ | `HTMLInputElement` &#124; `null` | | The DOM reference of the native range input that holds the value and takes the keyboard focus. The other attributes of the slider are applied to it. |
81
+ | `wrapperRef` _bindable_ | `HTMLDivElement` &#124; `null` | | The DOM reference of the element that draws the slider. |
82
+ | `wrapperAttributes` | `HTMLAttributes` | | The attributes to spread on the element that draws the slider. |
83
+ | `thumbRef` _bindable_ | `HTMLElement` &#124; `null` | | The DOM reference of the thumb element. |
84
+ | `tooltipRef` _bindable_ | `HTMLElement` &#124; `null` | | The DOM reference of the tooltip element. |
85
+ | `railRef` _bindable_ | `HTMLElement` &#124; `null` | | The DOM reference of the rail element. |
86
+ | `trackRef` _bindable_ | `HTMLElement` &#124; `null` | | The DOM reference of the track element. |
87
+ | `tickBarRef` _bindable_ | `HTMLElement` &#124; `null` | | The DOM reference of the tick bar element. |
88
+ | `HiddenInputAttributes<HTMLInputAttributes>` | | | |
86
89
 
87
90
  <!-- /props:SliderProps -->