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,4 +1,5 @@
1
1
  import type { HTMLAttributes, HTMLButtonAttributes, HTMLInputAttributes } from 'svelte/elements';
2
+ import type { NativeFieldAttributes } from '../../internal/index.js';
2
3
  /** @propsmith TimePickerProps */
3
4
  export type TimePickerProps = {
4
5
  /** Selected time as 24h `HH:mm` or `HH:mm:ss` (matches `<input type="time">`).
@@ -27,28 +28,37 @@ export type TimePickerProps = {
27
28
  * @default false
28
29
  */
29
30
  hideSeconds?: boolean;
30
- /** The DOM reference of the trigger button.
31
+ /** The DOM reference of the native time input that holds the value. The other attributes of the picker are applied to it.
31
32
  * @bindable
32
33
  */
33
- element?: HTMLButtonElement;
34
- /** The DOM reference of the element wrapping the trigger and its input.
34
+ ref?: HTMLInputElement | null;
35
+ /** The DOM reference of the button that opens the picker.
35
36
  * @bindable
36
37
  */
37
- wrapperRef?: HTMLDivElement;
38
- /** The attributes to spread on the wrapper element.
39
- * @type HTMLAttributes
38
+ buttonRef?: HTMLButtonElement | null;
39
+ /** The attributes to spread on the button that opens the picker.
40
+ * @type HTMLButtonAttributes
40
41
  */
41
- wrapperAttributes?: HTMLAttributes<HTMLDivElement>;
42
- /** The DOM reference of the underlying input element.
42
+ buttonAttributes?: HTMLButtonAttributes;
43
+ /** The DOM reference of the element wrapping the button and the native input.
43
44
  * @bindable
44
45
  */
45
- inputElement?: HTMLInputElement;
46
- /** HTML attributes for the underlying input element. Give it a `name` to submit the
47
- * value with a form.
46
+ wrapperRef?: HTMLDivElement | null;
47
+ /** The attributes to spread on the wrapper element.
48
+ * @type HTMLAttributes
48
49
  */
49
- inputProps?: HTMLInputAttributes;
50
+ wrapperAttributes?: HTMLAttributes<HTMLDivElement>;
50
51
  /** The accessible name of the popup, which is announced as a dialog.
51
52
  * @default 'Choose a time'
52
53
  */
53
54
  popupLabel?: string;
54
- } & HTMLButtonAttributes;
55
+ /** The names of the hour, minute, second and AM/PM columns: shown on the trigger while there is no time, and given to the lists of the popup.
56
+ * @default { hour: 'Hour', minute: 'Minute', second: 'Second', meridiem: 'AM/PM' }
57
+ */
58
+ columnLabels?: {
59
+ hour?: string;
60
+ minute?: string;
61
+ second?: string;
62
+ meridiem?: string;
63
+ };
64
+ } & NativeFieldAttributes<HTMLInputAttributes>;
@@ -0,0 +1,382 @@
1
+ # TitleBar
2
+
3
+ A title bar is the top bar of an app shell, laid out like the one of a Windows 11 app: the identity of the app and its navigation at the start, a search that grows and shrinks at the center, and the person picture and window controls at the end. It paints no background of its own, since it sits on the component that renders the window.
4
+
5
+ To create a title bar, you will need to use the following components:
6
+
7
+ - `TitleBar`: The root component. It lays the three areas out, keeps the search between its width limits and collapses it when asked.
8
+ - `TitleBarLeftControls`: The controls at the start of the bar: a back button, a global navigation button, and the icon, the name and the release tag of the app.
9
+ - `TitleBarRightControls`: The controls at the end of the bar: custom menus, the person picture, and the minimize, maximize and close buttons of the window.
10
+
11
+ ## Usage
12
+
13
+ Compose the bar from its three areas through the `leftControls`, `search` and `rightControls` snippets. Every area is optional. `TitleBarLeftControls` and `TitleBarRightControls` follow the settings of the bar when they are rendered inside a `TitleBar`, and also work on their own. The window buttons only report the press, since minimizing, maximizing and closing the window is up to the host of your app.
14
+
15
+ ```svelte
16
+ <script>
17
+ import { TitleBar, TitleBarLeftControls, TitleBarRightControls } from 'fluentui-svelte';
18
+ import { AppsRegular } from 'fluentui-icons-svelte';
19
+ import { getCurrentWindow } from '@tauri-apps/api/window';
20
+
21
+ const appWindow = getCurrentWindow();
22
+ let maximized = $state(false);
23
+ appWindow.isMaximized().then((value) => (maximized = value));
24
+ </script>
25
+
26
+ <TitleBar>
27
+ {#snippet leftControls()}
28
+ <TitleBarLeftControls back globalNav appIcon={AppsRegular} appName="FluentUI App" releaseTag="PREVIEW" />
29
+ {/snippet}
30
+ {#snippet rightControls()}
31
+ <TitleBarRightControls
32
+ {maximized}
33
+ personPic={{ name: 'Ada Lovelace' }}
34
+ onMinimize={() => appWindow.minimize()}
35
+ onWindowToggle={async () => {
36
+ await appWindow.toggleMaximize();
37
+ maximized = await appWindow.isMaximized();
38
+ }}
39
+ onClose={() => appWindow.close()}
40
+ />
41
+ {/snippet}
42
+ </TitleBar>
43
+ ```
44
+
45
+ ## Examples
46
+
47
+ ### Left Controls
48
+
49
+ `back` and `globalNav` show a button each and report the press through `onBack` and `onGlobalNav`. Inside an AppWindow with a SideNav, the global navigation button expands and collapses it, follows its state and takes the place of its hamburger (call `preventDefault()` in `onGlobalNav` to opt out of the toggle). Elsewhere, set `globalNavExpanded` while the navigation is open, or pass a snippet to `globalNav` to draw the button yourself.
50
+
51
+ ```svelte
52
+ <TitleBar>
53
+ {#snippet leftControls()}
54
+ <TitleBarLeftControls
55
+ back
56
+ globalNav
57
+ globalNavExpanded={navExpanded}
58
+ onBack={() => history.back()}
59
+ onGlobalNav={() => (navExpanded = !navExpanded)}
60
+ appIcon={AppsRegular}
61
+ appName="FluentUI App"
62
+ />
63
+ {/snippet}
64
+ </TitleBar>
65
+ ```
66
+
67
+ ### App Icon
68
+
69
+ `appIcon` takes the URL of an image, a Fluent icon component, or a snippet that draws a custom SVG. With `appName` it is decorative and the name of the app identifies it. Without `appName` it has `role="img"` and `appIconLabel` names it.
70
+
71
+ ```svelte
72
+ <TitleBar>
73
+ {#snippet leftControls()}
74
+ <TitleBarLeftControls appIcon="/logo.png" appName="Image URL" />
75
+ {/snippet}
76
+ </TitleBar>
77
+
78
+ <TitleBar>
79
+ {#snippet leftControls()}
80
+ <TitleBarLeftControls appIcon={AppsRegular} appName="Fluent icon" />
81
+ {/snippet}
82
+ </TitleBar>
83
+
84
+ <TitleBar>
85
+ {#snippet leftControls()}
86
+ <TitleBarLeftControls appName="Custom SVG">
87
+ {#snippet appIcon(props)}
88
+ <svg {...props} viewBox="0 0 16 16"><circle cx="8" cy="8" r="7" fill="currentColor" /></svg>
89
+ {/snippet}
90
+ </TitleBarLeftControls>
91
+ {/snippet}
92
+ </TitleBar>
93
+ ```
94
+
95
+ ### Release Tag
96
+
97
+ `releaseTag` marks the release status of the app, such as PREVIEW or BETA, in a badge next to its name. It takes a string or a snippet.
98
+
99
+ ```svelte
100
+ <TitleBar>
101
+ {#snippet leftControls()}
102
+ <TitleBarLeftControls appIcon={AppsRegular} appName="FluentUI App" releaseTag="PREVIEW" />
103
+ {/snippet}
104
+ </TitleBar>
105
+
106
+ <TitleBar>
107
+ {#snippet leftControls()}
108
+ <TitleBarLeftControls appIcon={AppsRegular} appName="FluentUI App" releaseTag="BETA" />
109
+ {/snippet}
110
+ </TitleBar>
111
+ ```
112
+
113
+ ### Search
114
+
115
+ The `search` snippet sits at the center of the bar and takes up the width the bar gives it, growing and shrinking with the window. A bar with a search is `tall` by default, which leaves the search room to breathe.
116
+
117
+ ```svelte
118
+ <TitleBar searchMinWidth={120}>
119
+ {#snippet leftControls()}
120
+ <TitleBarLeftControls appIcon={AppsRegular} appName="FluentUI App" />
121
+ {/snippet}
122
+ {#snippet search()}
123
+ <AutoSuggestBox placeholder="Search" aria-label="Search">
124
+ <AutoSuggestBoxOption index={0} value="Documents">Documents</AutoSuggestBoxOption>
125
+ <AutoSuggestBoxOption index={1} value="Pictures">Pictures</AutoSuggestBoxOption>
126
+ </AutoSuggestBox>
127
+ {/snippet}
128
+ {#snippet rightControls()}
129
+ <TitleBarRightControls />
130
+ {/snippet}
131
+ </TitleBar>
132
+ ```
133
+
134
+ ### Search Width
135
+
136
+ `searchMinWidth` and `searchMaxWidth` set how far the search shrinks and grows. Numbers are pixel values converted to rem using the current root font size, with a 16px fallback during SSR. For example, 200 becomes 10rem at a 20px root and still renders as 200px. A string is any CSS length.
137
+
138
+ ```svelte
139
+ <TitleBar searchMinWidth={100} searchMaxWidth={180}>...</TitleBar>
140
+ <TitleBar searchMinWidth="30%" searchMaxWidth="60%">...</TitleBar>
141
+ ```
142
+
143
+ ### Collapsed Search
144
+
145
+ `searchCollapsed` manually folds the search into a button; resizing does not collapse it automatically. Pressing the button expands the search and moves the focus into the first available control. Bind it to follow the state. Leave enough room for the expanded search and the side controls, or lower `searchMinWidth`. Long app names are truncated, but navigation and window buttons still need room.
146
+
147
+ ```svelte
148
+ <script>
149
+ let collapsed = $state(false);
150
+ </script>
151
+
152
+ <TitleBar searchMinWidth={120} bind:searchCollapsed={collapsed}>
153
+ {#snippet search()}
154
+ <AutoSuggestBox placeholder="Search" aria-label="Search" />
155
+ {/snippet}
156
+ ...
157
+ </TitleBar>
158
+ ```
159
+
160
+ ### Window Controls
161
+
162
+ `hideMinimize`, `hideWindowToggle` and `hideClose` each take a window button out of the bar. `onMinimize`, `onWindowToggle` and `onClose` report the press.
163
+
164
+ ```svelte
165
+ <TitleBar>
166
+ {#snippet rightControls()}
167
+ <TitleBarRightControls />
168
+ {/snippet}
169
+ </TitleBar>
170
+
171
+ <TitleBar>
172
+ {#snippet rightControls()}
173
+ <TitleBarRightControls hideMinimize />
174
+ {/snippet}
175
+ </TitleBar>
176
+
177
+ <TitleBar>
178
+ {#snippet rightControls()}
179
+ <TitleBarRightControls hideWindowToggle />
180
+ {/snippet}
181
+ </TitleBar>
182
+
183
+ <TitleBar>
184
+ {#snippet rightControls()}
185
+ <TitleBarRightControls hideClose />
186
+ {/snippet}
187
+ </TitleBar>
188
+
189
+ <TitleBar>
190
+ {#snippet rightControls()}
191
+ <TitleBarRightControls hideMinimize hideWindowToggle />
192
+ {/snippet}
193
+ </TitleBar>
194
+ ```
195
+
196
+ ### Maximized
197
+
198
+ While `maximized` is set, the maximize button becomes a restore button, with the icon and the label that go with it.
199
+
200
+ ```svelte
201
+ <script>
202
+ let maximized = $state(false);
203
+ appWindow.isMaximized().then((value) => (maximized = value));
204
+ </script>
205
+
206
+ <TitleBar>
207
+ {#snippet rightControls()}
208
+ <TitleBarRightControls {maximized} onWindowToggle={() => (maximized = !maximized)} />
209
+ {/snippet}
210
+ </TitleBar>
211
+ ```
212
+
213
+ ### Person Picture
214
+
215
+ `personPic` takes the props of an `Avatar`, such as its `image`, drawn at 24 pixels unless you set a size. Add `onPersonPicClick` to turn the picture into a button, such as the one that opens an account.
216
+
217
+ ```svelte
218
+ <TitleBar>
219
+ {#snippet rightControls()}
220
+ <TitleBarRightControls personPic={{ name: 'Ada Lovelace', image: { src: 'https://placehold.co/120x120/jpeg' } }} />
221
+ {/snippet}
222
+ </TitleBar>
223
+
224
+ <TitleBar>
225
+ {#snippet rightControls()}
226
+ <TitleBarRightControls
227
+ personPic={{ name: 'Grace Hopper', image: { src: 'https://placehold.co/120x120/jpeg' }, size: 28 }}
228
+ onPersonPicClick={() => openAccount()}
229
+ />
230
+ {/snippet}
231
+ </TitleBar>
232
+ ```
233
+
234
+ ### Custom Menu
235
+
236
+ The `customMenu` snippet places your own actions before the person picture, such as a settings menu.
237
+
238
+ ```svelte
239
+ <TitleBar>
240
+ {#snippet rightControls()}
241
+ <TitleBarRightControls personPic={{ name: 'Ada Lovelace', image: { src: 'https://placehold.co/120x120/jpeg' } }}>
242
+ {#snippet customMenu()}
243
+ <Menu>
244
+ <MenuTrigger>
245
+ {#snippet children({ state, menuTriggerProps })}
246
+ <Button bind:ref={state.ref} {...menuTriggerProps} appearance="subtle" aria-label="Settings">
247
+ <SettingsRegular width="1rem" height="1rem" />
248
+ </Button>
249
+ {/snippet}
250
+ </MenuTrigger>
251
+ <MenuPopover>
252
+ <MenuList>
253
+ <MenuItem>Preferences</MenuItem>
254
+ <MenuItem>Keyboard shortcuts</MenuItem>
255
+ </MenuList>
256
+ </MenuPopover>
257
+ </Menu>
258
+ {/snippet}
259
+ </TitleBarRightControls>
260
+ {/snippet}
261
+ </TitleBar>
262
+ ```
263
+
264
+ ### Labels
265
+
266
+ The accessible names of the buttons default to English. Pass `backLabel`, `globalNavLabel`, `searchLabel`, `minimizeLabel`, `maximizeLabel`, `restoreLabel` and `closeLabel` to translate them.
267
+
268
+ ```svelte
269
+ <TitleBar>
270
+ {#snippet leftControls()}
271
+ <TitleBarLeftControls back globalNav backLabel="Atrás" globalNavLabel="Menú de navegación" />
272
+ {/snippet}
273
+ {#snippet rightControls()}
274
+ <TitleBarRightControls
275
+ minimizeLabel="Minimizar"
276
+ maximizeLabel="Maximizar"
277
+ restoreLabel="Restaurar"
278
+ closeLabel="Cerrar"
279
+ />
280
+ {/snippet}
281
+ </TitleBar>
282
+ ```
283
+
284
+ ### Tab Order
285
+
286
+ The buttons of the bar are in the tab order by default. Set `tabbable={false}` only when a desktop host provides an alternative keyboard route to these actions. The content you place in the snippets keeps its own tab order.
287
+
288
+ ```svelte
289
+ <TitleBar tabbable>
290
+ {#snippet leftControls()}
291
+ <TitleBarLeftControls back globalNav appName="FluentUI App" />
292
+ {/snippet}
293
+ {#snippet rightControls()}
294
+ <TitleBarRightControls />
295
+ {/snippet}
296
+ </TitleBar>
297
+ ```
298
+
299
+ ### Drag Region
300
+
301
+ `dragRegionProps` is spread on the bar, its start and end areas, and the app identity, so a host that moves the window can tell where to grab the bar. Use `data-tauri-drag-region` for Tauri, or a pointer handler for any other host.
302
+
303
+ ```svelte
304
+ <TitleBar dragRegionProps={{ 'data-tauri-drag-region': true }}>...</TitleBar>
305
+
306
+ <TitleBar dragRegionProps={{ onpointerdown: (e) => e.target === e.currentTarget && appWindow.startDragging() }}>
307
+ ...
308
+ </TitleBar>
309
+ ```
310
+
311
+ ## Component Props (TitleBar)
312
+
313
+ <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
314
+ <!-- props:TitleBarProps -->
315
+
316
+ | Name | Type | Default | Description |
317
+ | ------------------------------------------------ | --------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
318
+ | `ref` _bindable_ | `HTMLElement` &#124; `null` | | The DOM reference of the title bar element. |
319
+ | `leftControls` | `Snippet` | | The controls at the start of the bar: back, navigation, and the identity of the app. Render a `TitleBarLeftControls` here. |
320
+ | `search` | `Snippet` | | The search at the center of the bar, which grows and shrinks with the window between `searchMinWidth` and `searchMaxWidth`. |
321
+ | `rightControls` | `Snippet` | | The controls at the end of the bar: custom menus, the person picture, and the window buttons. Render a `TitleBarRightControls` here. |
322
+ | `tall` | `boolean` | | Uses the tall bar, which leaves a search room to breathe. It is on by default when `search` is provided. |
323
+ | `searchMinWidth` | `number` &#124; `string` | `200` | The narrowest the search gets while the window shrinks. A number is in pixels, converted to rem using the current root font size, with a 16px fallback during SSR. A string is any CSS length. |
324
+ | `searchMaxWidth` | `number` &#124; `string` | `480` | The widest the search gets while the window grows. A number is in pixels, converted to rem using the current root font size, with a 16px fallback during SSR. A string is any CSS length. |
325
+ | `searchCollapsed` _bindable_ | `boolean` | `false` | Manually collapses the search into a button; it does not collapse automatically on resize. Pressing the button expands the search again and moves the focus into the first available control. The host must leave enough room for the expanded search and the side controls. |
326
+ | `searchLabel` | `string` | `'Search'` | The accessible name of the button that stands in for a collapsed search. |
327
+ | `tabbable` | `boolean` | `true` | Lets the Tab key reach the buttons of the bar. Set to false only when the desktop host provides an alternative keyboard route to these actions. The content you render in the snippets is not affected. |
328
+ | `dragRegionProps` | `HTMLAttributes` | | The attributes that make the bar draggable for the host that moves the window, such as `data-tauri-drag-region` for Tauri. They are spread on the bar, its start and end areas, and the app identity. |
329
+ | `HTMLAttributes<HTMLElement>` without `children` | | | |
330
+
331
+ <!-- /props:TitleBarProps -->
332
+
333
+ ## Component Props (TitleBarLeftControls)
334
+
335
+ <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
336
+ <!-- props:TitleBarLeftControlsProps -->
337
+
338
+ | Name | Type | Default | Description |
339
+ | --------------------------------------------------- | -------------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
340
+ | `ref` _bindable_ | `HTMLDivElement` &#124; `null` | | The DOM reference of the controls element. |
341
+ | `back` | `boolean` | `false` | Shows the back button. |
342
+ | `backDisabled` | `boolean` | `false` | Disables the back button, for when there is nowhere to go back to. |
343
+ | `onBack` | `MouseEventHandler<HTMLButtonElement>` | | Called when the back button is pressed. |
344
+ | `backLabel` | `string` | `'Back'` | The accessible name of the back button. |
345
+ | `globalNav` | `boolean` &#124; `Snippet` | `false` | Shows the global navigation button, or replaces it with the snippet you provide. |
346
+ | `globalNavExpanded` | `boolean` | `false` | Whether the navigation the global navigation button controls is expanded. Inside an AppWindow with a SideNav, it follows the SideNav and the button expands and collapses it. |
347
+ | `onGlobalNav` | `MouseEventHandler<HTMLButtonElement>` | | Called when the global navigation button is pressed. Call `preventDefault()` to keep it from toggling the SideNav of the window. |
348
+ | `globalNavLabel` | `string` | `'Navigation menu'` | The accessible name of the global navigation button. |
349
+ | `appIcon` | `string` &#124; `Snippet` &#124; `Component` | | The icon of the app: the URL of an image, an icon component, or a snippet that draws a custom SVG. |
350
+ | `appIconLabel` | `string` | `'Application'` | The accessible name of the app icon when appName is absent. Set it to the app's name for an icon-only identity. |
351
+ | `appName` | `string` | | The name of the app. |
352
+ | `releaseTag` | `string` &#124; `Snippet` | | The release status of the app, such as `PREVIEW` or `BETA`. |
353
+ | `children` | `Snippet` | | More content after the release tag, such as a subtitle. |
354
+ | `HTMLAttributes<HTMLDivElement>` without `children` | | | |
355
+
356
+ <!-- /props:TitleBarLeftControlsProps -->
357
+
358
+ ## Component Props (TitleBarRightControls)
359
+
360
+ <!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
361
+ <!-- props:TitleBarRightControlsProps -->
362
+
363
+ | Name | Type | Default | Description |
364
+ | --------------------------------------------------- | -------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
365
+ | `ref` _bindable_ | `HTMLDivElement` &#124; `null` | | The DOM reference of the controls element. |
366
+ | `hideMinimize` | `boolean` | `false` | Hides the minimize button. |
367
+ | `hideWindowToggle` | `boolean` | `false` | Hides the maximize and restore button. |
368
+ | `hideClose` | `boolean` | `false` | Hides the close button. |
369
+ | `maximized` | `boolean` | `false` | Whether the window is maximized, which turns the maximize button into a restore button. Inherits AppWindow's maximized state when omitted, or false when standalone. |
370
+ | `onMinimize` | `MouseEventHandler<HTMLButtonElement>` | | Called when the minimize button is pressed. |
371
+ | `onWindowToggle` | `MouseEventHandler<HTMLButtonElement>` | | Called when the maximize or restore button is pressed. |
372
+ | `onClose` | `MouseEventHandler<HTMLButtonElement>` | | Called when the close button is pressed. |
373
+ | `minimizeLabel` | `string` | `'Minimize'` | The accessible name of the minimize button. |
374
+ | `maximizeLabel` | `string` | `'Maximize'` | The accessible name of the maximize button. |
375
+ | `restoreLabel` | `string` | `'Restore'` | The accessible name of the restore button. |
376
+ | `closeLabel` | `string` | `'Close'` | The accessible name of the close button. |
377
+ | `personPic` | `AvatarProps` | | The props of the `Avatar` that shows the person. Its size is 24 unless you set one. |
378
+ | `onPersonPicClick` | `MouseEventHandler<HTMLButtonElement>` | | Called when the person picture is pressed, which turns it into a button. |
379
+ | `customMenu` | `Snippet` | | The custom menus or actions placed before the person picture. |
380
+ | `HTMLAttributes<HTMLDivElement>` without `children` | | | |
381
+
382
+ <!-- /props:TitleBarRightControlsProps -->
@@ -0,0 +1,215 @@
1
+ <script lang="ts">
2
+ import { Badge, Button } from '../../index.js';
3
+ import { RenderSoC } from '../../internal/index.js';
4
+ import ArrowLeftRegular from 'fluentui-icons-svelte/ArrowLeftRegular.svelte';
5
+ import NavigationRegular from 'fluentui-icons-svelte/NavigationRegular.svelte';
6
+ import { onDestroy } from 'svelte';
7
+ import { getAppWindowContext } from '../app-window/app-window.js';
8
+ import { getTitleBarContext } from './title-bar.js';
9
+ import type { TitleBarLeftControlsProps } from './types.js';
10
+
11
+ let {
12
+ ref = $bindable(null),
13
+ back = false,
14
+ backDisabled = false,
15
+ onBack,
16
+ backLabel = 'Back',
17
+ globalNav = false,
18
+ globalNavExpanded,
19
+ onGlobalNav,
20
+ globalNavLabel = 'Navigation menu',
21
+ appIcon,
22
+ appIconLabel = 'Application',
23
+ appName,
24
+ releaseTag,
25
+ children,
26
+ class: classes,
27
+ ...attributes
28
+ }: TitleBarLeftControlsProps = $props();
29
+
30
+ const context = getTitleBarContext();
31
+
32
+ // Outside a TitleBar the controls are always reachable.
33
+ const tabindex = $derived(context && !context.config.tabbable ? -1 : undefined);
34
+
35
+ let globalNavRef = $state<HTMLButtonElement | null>(null);
36
+
37
+ // The button controls the SideNav of its window, when it has one.
38
+ const appWindow = getAppWindowContext();
39
+ const sideNav = $derived(appWindow?.state.sideNav);
40
+ const expanded = $derived(globalNavExpanded ?? (sideNav ? !sideNav.collapsed : false));
41
+ const unregister = appWindow?.methods.registerGlobalNav({
42
+ get ref() {
43
+ return globalNavRef;
44
+ },
45
+ get enabled() {
46
+ return !!globalNav;
47
+ }
48
+ });
49
+ onDestroy(() => unregister?.());
50
+
51
+ function handleGlobalNav(event: MouseEvent & { currentTarget: HTMLButtonElement }) {
52
+ onGlobalNav?.(event);
53
+ if (!event.defaultPrevented) sideNav?.setCollapsed(event, !sideNav.collapsed);
54
+ }
55
+
56
+ const hasIdentity = $derived(!!(appIcon || appName || releaseTag || children));
57
+ </script>
58
+
59
+ <!--
60
+ @component
61
+ The controls at the start of a `TitleBar`: a back button, a global navigation button, and the identity of the app,
62
+ which is its icon, its name and its release tag. Inside a `TitleBar` it follows its `tabbable` setting and its drag region; it also works on its own.
63
+
64
+ - Usage:
65
+ ```tsx
66
+ <script>
67
+ import { TitleBar, TitleBarLeftControls } from 'fluentui-svelte';
68
+ import { AppsRegular } from 'fluentui-icons-svelte';
69
+ </script>
70
+
71
+ <TitleBar>
72
+ {#snippet leftControls()}
73
+ <TitleBarLeftControls back globalNav appIcon={AppsRegular} appName="FluentUI App" releaseTag="PREVIEW" />
74
+ {/snippet}
75
+ </TitleBar>
76
+ ```
77
+ -->
78
+ <div
79
+ bind:this={ref}
80
+ class={['fs-title-bar-left-controls', classes]}
81
+ {...context?.config.dragRegionProps}
82
+ {...attributes}
83
+ >
84
+ {#if back}
85
+ <Button
86
+ class="fs-title-bar-button"
87
+ appearance="subtle"
88
+ aria-label={backLabel}
89
+ title={backLabel}
90
+ {tabindex}
91
+ disabled={backDisabled}
92
+ onclick={onBack}
93
+ >
94
+ <ArrowLeftRegular aria-hidden="true" />
95
+ </Button>
96
+ {/if}
97
+ {#if typeof globalNav === 'function'}
98
+ {@render globalNav()}
99
+ {:else if globalNav}
100
+ <Button
101
+ bind:ref={globalNavRef}
102
+ class="fs-title-bar-button"
103
+ appearance="subtle"
104
+ aria-label={globalNavLabel}
105
+ title={globalNavLabel}
106
+ {tabindex}
107
+ aria-expanded={expanded}
108
+ onclick={handleGlobalNav}
109
+ >
110
+ <NavigationRegular aria-hidden="true" />
111
+ </Button>
112
+ {/if}
113
+ {#if hasIdentity}
114
+ <div class="fs-title-bar-identity" {...context?.config.dragRegionProps}>
115
+ {#if appIcon}
116
+ <span
117
+ class="fs-title-bar-app-icon"
118
+ role={appName ? undefined : 'img'}
119
+ aria-label={appName ? undefined : appIconLabel}
120
+ aria-hidden={appName ? true : undefined}
121
+ >
122
+ {#if typeof appIcon === 'string'}
123
+ <img src={appIcon} alt="" />
124
+ {:else}
125
+ <RenderSoC SoC={appIcon} />
126
+ {/if}
127
+ </span>
128
+ {/if}
129
+ {#if appName}
130
+ <span class="fs-title-bar-app-name">{appName}</span>
131
+ {/if}
132
+ {#if releaseTag}
133
+ <Badge class="fs-title-bar-release-tag" appearance="outline" shape="rounded" size={14}>
134
+ {#if typeof releaseTag === 'string'}
135
+ {releaseTag}
136
+ {:else}
137
+ {@render releaseTag()}
138
+ {/if}
139
+ </Badge>
140
+ {/if}
141
+ {@render children?.()}
142
+ </div>
143
+ {/if}
144
+ </div>
145
+
146
+ <style>
147
+ .fs-title-bar-left-controls {
148
+ display: flex;
149
+ align-items: center;
150
+ gap: 0.25rem;
151
+ block-size: 100%;
152
+ min-inline-size: 0;
153
+ /* The same space above as at the start of the bar, which the window controls on the right do not have. */
154
+ padding-block-start: 0.25rem;
155
+ /* The buttons are the size of the ones of a SideNav: the same padding around an icon, and the same line of text under it. */
156
+ & :global(.fs-title-bar-button) {
157
+ flex: none;
158
+ padding: 0.275rem 0.5rem 0.4rem;
159
+ font-size: var(--fs-body2-font-size);
160
+ /* The line of a SideNav, not the caption one of the bar. */
161
+ line-height: 1.4;
162
+ min-block-size: calc(1lh + 0.675rem);
163
+ background: var(--fs-subtle-fill-transparent);
164
+ }
165
+ & :global(.fs-title-bar-button svg) {
166
+ inline-size: 1rem;
167
+ block-size: 1rem;
168
+ }
169
+ }
170
+ .fs-title-bar-identity {
171
+ display: flex;
172
+ min-inline-size: 0;
173
+ align-items: center;
174
+ gap: 0.5rem;
175
+ /* Breathing room after the buttons, and from the edge of the bar when there are none. */
176
+ padding-inline: 0.25rem;
177
+ /* The wrapper alone carries the drag region, so what sits in it lets the pointer through to it. */
178
+ & .fs-title-bar-app-icon,
179
+ & .fs-title-bar-app-name,
180
+ & :global(.fs-title-bar-release-tag) {
181
+ pointer-events: none;
182
+ }
183
+ }
184
+ .fs-title-bar-app-icon {
185
+ display: inline-flex;
186
+ flex: none;
187
+ & :global(svg),
188
+ & img {
189
+ inline-size: 1rem;
190
+ block-size: 1rem;
191
+ object-fit: contain;
192
+ }
193
+ }
194
+ .fs-title-bar-app-name {
195
+ flex: 0 1 auto;
196
+ min-inline-size: 0;
197
+ max-inline-size: 16rem;
198
+ overflow: hidden;
199
+ white-space: nowrap;
200
+ text-overflow: ellipsis;
201
+ color: var(--fs-text-primary);
202
+ }
203
+ /* Repeats the classes of the badge, since its own color rules are more specific than a single one. */
204
+ .fs-title-bar-identity :global(.fs-badge.fs-title-bar-release-tag.outline) {
205
+ flex: none;
206
+ padding-block: 0;
207
+ padding-inline: 0.1875rem;
208
+ font-size: 0.5625rem;
209
+ line-height: 1;
210
+ font-weight: 400;
211
+ color: var(--fs-text-secondary);
212
+ background: var(--fs-control-alt-fill-quaternary);
213
+ border-color: var(--fs-card-stroke-default);
214
+ }
215
+ </style>