fluentui-svelte 0.1.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 (283) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +201 -0
  3. package/dist/components/auto-suggest-box/auto-suggest-box.d.ts +2 -0
  4. package/dist/components/auto-suggest-box/auto-suggest-box.js +2 -0
  5. package/dist/components/auto-suggest-box/auto-suggest-box.svelte +457 -0
  6. package/dist/components/auto-suggest-box/auto-suggest-box.svelte.d.ts +4 -0
  7. package/dist/components/auto-suggest-box/docs/llms.md +73 -0
  8. package/dist/components/auto-suggest-box/option.svelte +82 -0
  9. package/dist/components/auto-suggest-box/option.svelte.d.ts +4 -0
  10. package/dist/components/auto-suggest-box/types.d.ts +140 -0
  11. package/dist/components/auto-suggest-box/types.js +1 -0
  12. package/dist/components/avatar/avatar.svelte +269 -0
  13. package/dist/components/avatar/avatar.svelte.d.ts +20 -0
  14. package/dist/components/avatar/docs/llms.md +92 -0
  15. package/dist/components/avatar/type.d.ts +63 -0
  16. package/dist/components/avatar/type.js +1 -0
  17. package/dist/components/badge/badge-icon.svelte +103 -0
  18. package/dist/components/badge/badge-icon.svelte.d.ts +25 -0
  19. package/dist/components/badge/badge.svelte +163 -0
  20. package/dist/components/badge/badge.svelte.d.ts +20 -0
  21. package/dist/components/badge/docs/llms.md +133 -0
  22. package/dist/components/badge/types.d.ts +70 -0
  23. package/dist/components/badge/types.js +1 -0
  24. package/dist/components/badge/utils.svelte.d.ts +16 -0
  25. package/dist/components/badge/utils.svelte.js +35 -0
  26. package/dist/components/button/button.svelte +203 -0
  27. package/dist/components/button/button.svelte.d.ts +38 -0
  28. package/dist/components/button/docs/llms.md +102 -0
  29. package/dist/components/button/split-button.svelte +66 -0
  30. package/dist/components/button/split-button.svelte.d.ts +4 -0
  31. package/dist/components/button/types.d.ts +84 -0
  32. package/dist/components/button/types.js +1 -0
  33. package/dist/components/calendar-date-picker/calendar-date-picker.svelte +119 -0
  34. package/dist/components/calendar-date-picker/calendar-date-picker.svelte.d.ts +4 -0
  35. package/dist/components/calendar-date-picker/docs/llms.md +33 -0
  36. package/dist/components/calendar-date-picker/types.d.ts +36 -0
  37. package/dist/components/calendar-date-picker/types.js +1 -0
  38. package/dist/components/calendar-view/calendar-view-controls.svelte +115 -0
  39. package/dist/components/calendar-view/calendar-view-controls.svelte.d.ts +3 -0
  40. package/dist/components/calendar-view/calendar-view-days.svelte +210 -0
  41. package/dist/components/calendar-view/calendar-view-days.svelte.d.ts +3 -0
  42. package/dist/components/calendar-view/calendar-view-grid.d.ts +38 -0
  43. package/dist/components/calendar-view/calendar-view-grid.js +140 -0
  44. package/dist/components/calendar-view/calendar-view-header.svelte +66 -0
  45. package/dist/components/calendar-view/calendar-view-header.svelte.d.ts +18 -0
  46. package/dist/components/calendar-view/calendar-view-item.svelte +181 -0
  47. package/dist/components/calendar-view/calendar-view-item.svelte.d.ts +4 -0
  48. package/dist/components/calendar-view/calendar-view-months.svelte +165 -0
  49. package/dist/components/calendar-view/calendar-view-months.svelte.d.ts +3 -0
  50. package/dist/components/calendar-view/calendar-view-years.svelte +161 -0
  51. package/dist/components/calendar-view/calendar-view-years.svelte.d.ts +3 -0
  52. package/dist/components/calendar-view/calendar-view.svelte +451 -0
  53. package/dist/components/calendar-view/calendar-view.svelte.d.ts +9 -0
  54. package/dist/components/calendar-view/calendar-view.svelte.js +196 -0
  55. package/dist/components/calendar-view/docs/llms.md +121 -0
  56. package/dist/components/calendar-view/index.d.ts +1 -0
  57. package/dist/components/calendar-view/index.js +1 -0
  58. package/dist/components/calendar-view/types.d.ts +174 -0
  59. package/dist/components/calendar-view/types.js +1 -0
  60. package/dist/components/checkbox/checkbox.svelte +171 -0
  61. package/dist/components/checkbox/checkbox.svelte.d.ts +40 -0
  62. package/dist/components/checkbox/docs/llms.md +78 -0
  63. package/dist/components/checkbox/types.d.ts +50 -0
  64. package/dist/components/checkbox/types.js +1 -0
  65. package/dist/components/date-picker/date-picker.svelte +381 -0
  66. package/dist/components/date-picker/date-picker.svelte.d.ts +4 -0
  67. package/dist/components/date-picker/docs/llms.md +52 -0
  68. package/dist/components/date-picker/index.d.ts +1 -0
  69. package/dist/components/date-picker/index.js +1 -0
  70. package/dist/components/date-picker/types.d.ts +74 -0
  71. package/dist/components/date-picker/types.js +1 -0
  72. package/dist/components/dialog/dialog-actions.svelte +37 -0
  73. package/dist/components/dialog/dialog-actions.svelte.d.ts +4 -0
  74. package/dist/components/dialog/dialog-content.svelte +17 -0
  75. package/dist/components/dialog/dialog-content.svelte.d.ts +4 -0
  76. package/dist/components/dialog/dialog-surface.svelte +95 -0
  77. package/dist/components/dialog/dialog-surface.svelte.d.ts +4 -0
  78. package/dist/components/dialog/dialog-title.svelte +33 -0
  79. package/dist/components/dialog/dialog-title.svelte.d.ts +25 -0
  80. package/dist/components/dialog/dialog-trigger.svelte +23 -0
  81. package/dist/components/dialog/dialog-trigger.svelte.d.ts +4 -0
  82. package/dist/components/dialog/dialog.svelte +64 -0
  83. package/dist/components/dialog/dialog.svelte.d.ts +7 -0
  84. package/dist/components/dialog/dialog.svelte.js +2 -0
  85. package/dist/components/dialog/docs/llms.md +131 -0
  86. package/dist/components/dialog/types.d.ts +92 -0
  87. package/dist/components/dialog/types.js +1 -0
  88. package/dist/components/divider/divider.svelte +120 -0
  89. package/dist/components/divider/divider.svelte.d.ts +39 -0
  90. package/dist/components/divider/docs/llms.md +83 -0
  91. package/dist/components/divider/types.d.ts +32 -0
  92. package/dist/components/divider/types.js +1 -0
  93. package/dist/components/dropdown/docs/llms.md +70 -0
  94. package/dist/components/dropdown/dropdown-context.d.ts +2 -0
  95. package/dist/components/dropdown/dropdown-context.js +2 -0
  96. package/dist/components/dropdown/dropdown-option.svelte +31 -0
  97. package/dist/components/dropdown/dropdown-option.svelte.d.ts +4 -0
  98. package/dist/components/dropdown/dropdown.svelte +309 -0
  99. package/dist/components/dropdown/dropdown.svelte.d.ts +4 -0
  100. package/dist/components/dropdown/types.d.ts +82 -0
  101. package/dist/components/dropdown/types.js +1 -0
  102. package/dist/components/dropdown-select/docs/llms.md +72 -0
  103. package/dist/components/dropdown-select/dropdown-select-option.svelte +87 -0
  104. package/dist/components/dropdown-select/dropdown-select-option.svelte.d.ts +4 -0
  105. package/dist/components/dropdown-select/dropdown-select.svelte +165 -0
  106. package/dist/components/dropdown-select/dropdown-select.svelte.d.ts +4 -0
  107. package/dist/components/dropdown-select/dropdown-select.svelte.js +48 -0
  108. package/dist/components/dropdown-select/index.d.ts +2 -0
  109. package/dist/components/dropdown-select/index.js +2 -0
  110. package/dist/components/dropdown-select/types.d.ts +46 -0
  111. package/dist/components/dropdown-select/types.js +1 -0
  112. package/dist/components/expander/docs/llms.md +88 -0
  113. package/dist/components/expander/expander.svelte +249 -0
  114. package/dist/components/expander/expander.svelte.d.ts +21 -0
  115. package/dist/components/expander/types.d.ts +47 -0
  116. package/dist/components/expander/types.js +1 -0
  117. package/dist/components/flyout/docs/llms.md +31 -0
  118. package/dist/components/flyout/flyout.svelte +148 -0
  119. package/dist/components/flyout/flyout.svelte.d.ts +19 -0
  120. package/dist/components/flyout/types.d.ts +36 -0
  121. package/dist/components/flyout/types.js +1 -0
  122. package/dist/components/hyperlink/docs/llms.md +33 -0
  123. package/dist/components/hyperlink/hyperlink.svelte +66 -0
  124. package/dist/components/hyperlink/hyperlink.svelte.d.ts +16 -0
  125. package/dist/components/hyperlink/types.d.ts +14 -0
  126. package/dist/components/hyperlink/types.js +1 -0
  127. package/dist/components/info-bar/docs/llms.md +81 -0
  128. package/dist/components/info-bar/info-bar.svelte +140 -0
  129. package/dist/components/info-bar/info-bar.svelte.d.ts +19 -0
  130. package/dist/components/info-bar/types.d.ts +27 -0
  131. package/dist/components/info-bar/types.js +1 -0
  132. package/dist/components/label/docs/llms.md +67 -0
  133. package/dist/components/label/label.svelte +95 -0
  134. package/dist/components/label/label.svelte.d.ts +4 -0
  135. package/dist/components/label/types.d.ts +32 -0
  136. package/dist/components/label/types.js +1 -0
  137. package/dist/components/list-view/docs/llms.md +110 -0
  138. package/dist/components/list-view/list-view-item.svelte +168 -0
  139. package/dist/components/list-view/list-view-item.svelte.d.ts +25 -0
  140. package/dist/components/list-view/list-view.svelte +137 -0
  141. package/dist/components/list-view/list-view.svelte.d.ts +25 -0
  142. package/dist/components/list-view/types.d.ts +95 -0
  143. package/dist/components/list-view/types.js +1 -0
  144. package/dist/components/list-view/utils.d.ts +6 -0
  145. package/dist/components/list-view/utils.js +12 -0
  146. package/dist/components/menu/context-menu-trigger.svelte +84 -0
  147. package/dist/components/menu/context-menu-trigger.svelte.d.ts +9 -0
  148. package/dist/components/menu/docs/llms.md +169 -0
  149. package/dist/components/menu/menu-divider.svelte +9 -0
  150. package/dist/components/menu/menu-divider.svelte.d.ts +26 -0
  151. package/dist/components/menu/menu-group.svelte +31 -0
  152. package/dist/components/menu/menu-group.svelte.d.ts +4 -0
  153. package/dist/components/menu/menu-item-checkbox.svelte +143 -0
  154. package/dist/components/menu/menu-item-checkbox.svelte.d.ts +15 -0
  155. package/dist/components/menu/menu-item-radio.svelte +147 -0
  156. package/dist/components/menu/menu-item-radio.svelte.d.ts +15 -0
  157. package/dist/components/menu/menu-item-switch.svelte +194 -0
  158. package/dist/components/menu/menu-item-switch.svelte.d.ts +15 -0
  159. package/dist/components/menu/menu-item.svelte +124 -0
  160. package/dist/components/menu/menu-item.svelte.d.ts +18 -0
  161. package/dist/components/menu/menu-list.svelte +38 -0
  162. package/dist/components/menu/menu-list.svelte.d.ts +5 -0
  163. package/dist/components/menu/menu-popover.svelte +125 -0
  164. package/dist/components/menu/menu-popover.svelte.d.ts +12 -0
  165. package/dist/components/menu/menu-trigger.svelte +121 -0
  166. package/dist/components/menu/menu-trigger.svelte.d.ts +4 -0
  167. package/dist/components/menu/menu.svelte +124 -0
  168. package/dist/components/menu/menu.svelte.d.ts +4 -0
  169. package/dist/components/menu/menu.svelte.js +77 -0
  170. package/dist/components/menu/types.d.ts +127 -0
  171. package/dist/components/menu/types.js +1 -0
  172. package/dist/components/number-box/docs/llms.md +37 -0
  173. package/dist/components/number-box/number-box.svelte +115 -0
  174. package/dist/components/number-box/number-box.svelte.d.ts +15 -0
  175. package/dist/components/number-box/types.d.ts +16 -0
  176. package/dist/components/number-box/types.js +1 -0
  177. package/dist/components/persona/docs/llms.md +107 -0
  178. package/dist/components/persona/persona.svelte +79 -0
  179. package/dist/components/persona/persona.svelte.d.ts +4 -0
  180. package/dist/components/persona/types.d.ts +42 -0
  181. package/dist/components/persona/types.js +1 -0
  182. package/dist/components/progress-bar/docs/llms.md +67 -0
  183. package/dist/components/progress-bar/progress-bar.svelte +167 -0
  184. package/dist/components/progress-bar/progress-bar.svelte.d.ts +15 -0
  185. package/dist/components/progress-bar/types.d.ts +39 -0
  186. package/dist/components/progress-bar/types.js +1 -0
  187. package/dist/components/progress-ring/docs/llms.md +76 -0
  188. package/dist/components/progress-ring/progress-ring.svelte +145 -0
  189. package/dist/components/progress-ring/progress-ring.svelte.d.ts +15 -0
  190. package/dist/components/progress-ring/types.d.ts +42 -0
  191. package/dist/components/progress-ring/types.js +1 -0
  192. package/dist/components/radio-button/docs/llms.md +64 -0
  193. package/dist/components/radio-button/radio-button.svelte +129 -0
  194. package/dist/components/radio-button/radio-button.svelte.d.ts +19 -0
  195. package/dist/components/radio-button/types.d.ts +24 -0
  196. package/dist/components/radio-button/types.js +1 -0
  197. package/dist/components/skeleton/docs/llms.md +67 -0
  198. package/dist/components/skeleton/skeleton.svelte +106 -0
  199. package/dist/components/skeleton/skeleton.svelte.d.ts +39 -0
  200. package/dist/components/skeleton/types.d.ts +24 -0
  201. package/dist/components/skeleton/types.js +1 -0
  202. package/dist/components/slider/docs/llms.md +75 -0
  203. package/dist/components/slider/slider.svelte +486 -0
  204. package/dist/components/slider/slider.svelte.d.ts +19 -0
  205. package/dist/components/slider/types.d.ts +102 -0
  206. package/dist/components/slider/types.js +1 -0
  207. package/dist/components/text-box/docs/llms.md +86 -0
  208. package/dist/components/text-box/text-box-button.svelte +65 -0
  209. package/dist/components/text-box/text-box-button.svelte.d.ts +9 -0
  210. package/dist/components/text-box/text-box.svelte +299 -0
  211. package/dist/components/text-box/text-box.svelte.d.ts +16 -0
  212. package/dist/components/text-box/types.d.ts +60 -0
  213. package/dist/components/text-box/types.js +1 -0
  214. package/dist/components/textarea/docs/llms.md +55 -0
  215. package/dist/components/textarea/textarea.svelte +151 -0
  216. package/dist/components/textarea/textarea.svelte.d.ts +17 -0
  217. package/dist/components/textarea/types.d.ts +33 -0
  218. package/dist/components/textarea/types.js +1 -0
  219. package/dist/components/time-picker/docs/llms.md +47 -0
  220. package/dist/components/time-picker/index.d.ts +1 -0
  221. package/dist/components/time-picker/index.js +1 -0
  222. package/dist/components/time-picker/time-picker.svelte +336 -0
  223. package/dist/components/time-picker/time-picker.svelte.d.ts +4 -0
  224. package/dist/components/time-picker/types.d.ts +54 -0
  225. package/dist/components/time-picker/types.js +1 -0
  226. package/dist/components/toggle-switch/docs/llms.md +39 -0
  227. package/dist/components/toggle-switch/toggle-switch.svelte +151 -0
  228. package/dist/components/toggle-switch/toggle-switch.svelte.d.ts +17 -0
  229. package/dist/components/toggle-switch/types.d.ts +20 -0
  230. package/dist/components/toggle-switch/types.js +1 -0
  231. package/dist/components/tooltip/docs/llms.md +74 -0
  232. package/dist/components/tooltip/tooltip.svelte +246 -0
  233. package/dist/components/tooltip/tooltip.svelte.d.ts +18 -0
  234. package/dist/components/tooltip/types.d.ts +67 -0
  235. package/dist/components/tooltip/types.js +1 -0
  236. package/dist/components/tree-view/docs/llms.md +117 -0
  237. package/dist/components/tree-view/tree-view-item-content.svelte +158 -0
  238. package/dist/components/tree-view/tree-view-item-content.svelte.d.ts +4 -0
  239. package/dist/components/tree-view/tree-view-item.svelte +197 -0
  240. package/dist/components/tree-view/tree-view-item.svelte.d.ts +4 -0
  241. package/dist/components/tree-view/tree-view.svelte +220 -0
  242. package/dist/components/tree-view/tree-view.svelte.d.ts +4 -0
  243. package/dist/components/tree-view/tree-view.svelte.js +111 -0
  244. package/dist/components/tree-view/types.d.ts +185 -0
  245. package/dist/components/tree-view/types.js +1 -0
  246. package/dist/css/class-darkmode.css +186 -0
  247. package/dist/css/media-darkmode.css +189 -0
  248. package/dist/css/reset.css +53 -0
  249. package/dist/css/theme.css +276 -0
  250. package/dist/css/typography.css +67 -0
  251. package/dist/css/utils.d.ts +1 -0
  252. package/dist/css/utils.js +153 -0
  253. package/dist/index.d.ts +63 -0
  254. package/dist/index.js +129 -0
  255. package/dist/internal/components/dynamic-carousel/dynamic-carousel.svelte +449 -0
  256. package/dist/internal/components/dynamic-carousel/dynamic-carousel.svelte.d.ts +22 -0
  257. package/dist/internal/components/render-soc/render-soc.svelte +29 -0
  258. package/dist/internal/components/render-soc/render-soc.svelte.d.ts +30 -0
  259. package/dist/internal/constants.d.ts +26 -0
  260. package/dist/internal/constants.js +4036 -0
  261. package/dist/internal/context.d.ts +14 -0
  262. package/dist/internal/context.js +13 -0
  263. package/dist/internal/dom-utils.svelte.d.ts +6 -0
  264. package/dist/internal/dom-utils.svelte.js +46 -0
  265. package/dist/internal/floating-ui/floating.svelte.d.ts +15 -0
  266. package/dist/internal/floating-ui/floating.svelte.js +26 -0
  267. package/dist/internal/floating-ui/utils.d.ts +3 -0
  268. package/dist/internal/floating-ui/utils.js +30 -0
  269. package/dist/internal/index.d.ts +9 -0
  270. package/dist/internal/index.js +9 -0
  271. package/dist/internal/polyfills/expander.svelte.d.ts +21 -0
  272. package/dist/internal/polyfills/expander.svelte.js +96 -0
  273. package/dist/internal/transitions.d.ts +32 -0
  274. package/dist/internal/transitions.js +37 -0
  275. package/dist/internal/utils.d.ts +22 -0
  276. package/dist/internal/utils.js +63 -0
  277. package/dist/providers/fluentui-svelte/fluentui-svelte.d.ts +19 -0
  278. package/dist/providers/fluentui-svelte/fluentui-svelte.js +11 -0
  279. package/dist/providers/fluentui-svelte/fluentui-svelte.svelte +68 -0
  280. package/dist/providers/fluentui-svelte/fluentui-svelte.svelte.d.ts +9 -0
  281. package/dist/types/index.d.ts +117 -0
  282. package/dist/types/index.js +1 -0
  283. package/package.json +142 -0
@@ -0,0 +1,147 @@
1
+ <script lang="ts">
2
+ import { watch } from 'runed';
3
+ import CheckmarkFilled from 'fluentui-icons-svelte/CheckmarkFilled.svelte';
4
+ import { Button } from '../../index.js';
5
+ import { PREFIX } from '../../internal/constants.js';
6
+ import { invokeHandlers, RenderSoC } from '../../internal/index.js';
7
+ import { getMenuContext, COMPONENT_NAME as MENU_COMPONENT_NAME } from './menu.svelte.js';
8
+ import type { MenuItemActionableProps } from './types.js';
9
+
10
+ const FALLBACK_ID = $props.id();
11
+ const COMPONENT_NAME = 'menu-item-radio';
12
+ const ID = `${PREFIX}${COMPONENT_NAME}-${FALLBACK_ID}`;
13
+
14
+ let {
15
+ ref = $bindable(),
16
+ icon: Icon,
17
+ secondaryContent,
18
+ children,
19
+ checked = $bindable(),
20
+ disabled,
21
+ class: classes,
22
+ id = ID,
23
+ name = id as string,
24
+ value = id as string,
25
+ onclick,
26
+ subText,
27
+ ...attributes
28
+ }: MenuItemActionableProps = $props();
29
+
30
+ const context = getMenuContext();
31
+
32
+ if (!context) throw new Error(`No MenuContext found for ${MENU_COMPONENT_NAME}.`);
33
+
34
+ const { hasIcons, persistOnItemActivation } = context.config;
35
+
36
+ const { toggleRadio, toggle } = context.methods;
37
+
38
+ const { state: _state } = context;
39
+
40
+ watch(
41
+ () => _state.checkedValues?.[name]?.includes(value),
42
+ () => {
43
+ checked = _state.checkedValues?.[name]?.includes(value) || false;
44
+ }
45
+ );
46
+ </script>
47
+
48
+ <!--
49
+ @component
50
+
51
+ - Usage:
52
+ ```tsx
53
+ <Menu hasIcons>
54
+ <MenuGroup name="Inputs">
55
+ <MenuItemRadio secondaryContent="Item 1" hint="Ctrl + 1" {Icon}>Item 1</MenuItemRadio>
56
+ <MenuItemRadio secondaryContent="Item 2" hint="Ctrl + 2">Item 2</MenuItemRadio>
57
+ </MenuGroup>
58
+ </Menu>
59
+ ```
60
+ -->
61
+ <Button
62
+ {disabled}
63
+ appearance="subtle"
64
+ onclick={(e: MouseEvent) =>
65
+ invokeHandlers(e, !!disabled, [onclick, () => toggleRadio(e, value, name), !!persistOnItemActivation && toggle])}
66
+ onkeydown={(e: KeyboardEvent) =>
67
+ invokeHandlers(
68
+ e,
69
+ [e.key !== 'Enter', !!disabled],
70
+ [onkeydown, () => toggleRadio(e, value, name), !!persistOnItemActivation && toggle]
71
+ )}
72
+ aria-checked={checked}
73
+ role="menuitemradio"
74
+ style={`--margin-left: ${hasIcons && !Icon ? 1.5 : 0}rem;}`}
75
+ aria-label={secondaryContent ? `${secondaryContent}, Use ${secondaryContent}` : undefined}
76
+ class="fs-menu-item-radio {hasIcons ? 'align' : ''} {checked ? 'checked' : ''} {classes}"
77
+ bind:ref
78
+ {...attributes}
79
+ >
80
+ <span class="label" aria-label="{secondaryContent}, Use {secondaryContent}">
81
+ <CheckmarkFilled class="indicator" />
82
+ {#if Icon}
83
+ <RenderSoC SoC={Icon} class="menu-item-icon" args={[{ class: 'menu-item-icon' }]} />
84
+ {/if}
85
+ {#if subText}
86
+ <span class="sub-text">
87
+ {@render children?.()}
88
+ <small>{subText}</small>
89
+ </span>
90
+ {:else}
91
+ {@render children?.()}
92
+ {/if}
93
+ </span>
94
+ {#if secondaryContent}
95
+ <span class="secondary-content" aria-hidden="true">{secondaryContent}</span>
96
+ {/if}
97
+ </Button>
98
+
99
+ <style>
100
+ :global(.fs-menu-item-radio.fs-button) {
101
+ width: 100%;
102
+ padding: 0.375rem 0.45rem;
103
+ border-radius: var(--fs-control-inner-border-radius);
104
+ justify-content: space-between;
105
+ font-size: var(--fs-body2-font-size);
106
+ line-height: var(--fs-caption-line-height);
107
+ & :global(svg) {
108
+ width: 1.25rem;
109
+ fill: currentColor;
110
+ & > :global(path) {
111
+ fill: currentColor;
112
+ }
113
+ }
114
+ & .label {
115
+ display: flex;
116
+ align-items: center;
117
+ gap: 0.25rem;
118
+ font-size: inherit;
119
+ }
120
+ & .secondary-content {
121
+ font-size: var(--fs-caption-font-size);
122
+ color: var(--fs-text-secondary);
123
+ margin-left: 0.6rem;
124
+ }
125
+ &:global(.align .label:not(:has(.menu-item-icon))) {
126
+ margin-left: var(--margin-left) !important;
127
+ }
128
+ & .sub-text {
129
+ display: flex;
130
+ flex-direction: column;
131
+ align-items: flex-start;
132
+ text-align: left;
133
+ font-size: inherit;
134
+ & small {
135
+ font-size: var(--fs-caption2-font-size);
136
+ color: var(--fs-text-secondary);
137
+ }
138
+ }
139
+ & :global(svg.indicator) {
140
+ width: 20px;
141
+ opacity: 0;
142
+ }
143
+ &.checked :global(svg.indicator) {
144
+ opacity: 1;
145
+ }
146
+ }
147
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { MenuItemActionableProps } from './types.ts';
2
+ /**
3
+ * - Usage:
4
+ * ```tsx
5
+ * <Menu hasIcons>
6
+ * <MenuGroup name="Inputs">
7
+ * <MenuItemRadio secondaryContent="Item 1" hint="Ctrl + 1" {Icon}>Item 1</MenuItemRadio>
8
+ * <MenuItemRadio secondaryContent="Item 2" hint="Ctrl + 2">Item 2</MenuItemRadio>
9
+ * </MenuGroup>
10
+ * </Menu>
11
+ * ```
12
+ */
13
+ declare const MenuItemRadio: import("svelte").Component<MenuItemActionableProps, {}, "ref" | "checked">;
14
+ type MenuItemRadio = ReturnType<typeof MenuItemRadio>;
15
+ export default MenuItemRadio;
@@ -0,0 +1,194 @@
1
+ <script lang="ts">
2
+ import { watch } from 'runed';
3
+ import { PREFIX } from '../../internal/constants.js';
4
+ import { Button } from '../../index.js';
5
+ import { invokeHandlers, RenderSoC } from '../../internal/index.js';
6
+ import { getMenuContext, COMPONENT_NAME as MENU_COMPONENT_NAME } from './menu.svelte.js';
7
+ import type { MenuItemActionableProps } from './types.js';
8
+
9
+ const FALLBACK_ID = $props.id();
10
+ const COMPONENT_NAME = 'menu-item-switch';
11
+ const ID = `${PREFIX}${COMPONENT_NAME}-${FALLBACK_ID}`;
12
+
13
+ let {
14
+ ref = $bindable(),
15
+ icon: Icon,
16
+ secondaryContent,
17
+ children,
18
+ checked = $bindable(),
19
+ disabled,
20
+ id = ID,
21
+ class: classes,
22
+ name = id as string,
23
+ value = id as string,
24
+ subText,
25
+ onclick,
26
+ ...attributes
27
+ }: MenuItemActionableProps = $props();
28
+
29
+ const context = getMenuContext();
30
+
31
+ if (!context) throw new Error(`No MenuContext found for ${MENU_COMPONENT_NAME}.`);
32
+
33
+ const { hasIcons, hasCheckmarks } = context.config;
34
+
35
+ const { toggleCheckbox } = context.methods;
36
+
37
+ const { state: _state } = context;
38
+
39
+ const marginLeft = $derived(1.5 * (+!!(hasIcons && !Icon) + +!!hasCheckmarks));
40
+
41
+ watch(
42
+ () => _state.checkedValues?.[name]?.includes(value),
43
+ () => {
44
+ checked = _state.checkedValues?.[name]?.includes(value) || false;
45
+ }
46
+ );
47
+ </script>
48
+
49
+ <!--
50
+ @component
51
+
52
+ - Usage:
53
+ ```tsx
54
+ <Menu hasIcons>
55
+ <MenuGroup name="Inputs">
56
+ <MenuItemSwitch secondaryContent="Item 1" hint="Ctrl + 1" {Icon}>Item 1</MenuItemSwitch>
57
+ <MenuItemSwitch secondaryContent="Item 2" hint="Ctrl + 2">Item 2</MenuItemSwitch>
58
+ </MenuGroup>
59
+ </Menu>
60
+ ```
61
+ -->
62
+ <Button
63
+ {disabled}
64
+ {id}
65
+ appearance="subtle"
66
+ onclick={(e: MouseEvent) => invokeHandlers(e, disabled, [onclick, () => toggleCheckbox(e, value, name)])}
67
+ onkeydown={(e: KeyboardEvent) =>
68
+ invokeHandlers(e, [e.key !== 'Enter', !!disabled], [onkeydown, () => toggleCheckbox(e, value, name)])}
69
+ aria-checked={checked}
70
+ role="menuitemcheckbox"
71
+ style={`--margin-left: ${marginLeft}rem;}`}
72
+ aria-label={secondaryContent ? `${secondaryContent}, Use ${secondaryContent}` : undefined}
73
+ class="fs-menu-item-switch {hasIcons || hasCheckmarks ? 'align' : ''} {checked ? 'checked' : ''} {classes}"
74
+ bind:ref
75
+ {...attributes}
76
+ >
77
+ <span class="label" aria-label="{secondaryContent}, Use {secondaryContent}">
78
+ {#if Icon}
79
+ <RenderSoC SoC={Icon} class="menu-item-icon" args={[{ class: 'menu-item-icon' }]} />
80
+ {/if}
81
+ {#if subText}
82
+ <span class="sub-text">
83
+ {@render children?.()}
84
+ <small>{subText}</small>
85
+ </span>
86
+ {:else}
87
+ {@render children?.()}
88
+ {/if}
89
+ <span class={['item-switch', { on: checked, disabled }]} aria-hidden="true"></span>
90
+ </span>
91
+ {#if secondaryContent}
92
+ <span class="secondary-content" aria-hidden="true">{secondaryContent}</span>
93
+ {/if}
94
+ </Button>
95
+
96
+ <style>
97
+ :global(.fs-menu-item-switch.fs-button) {
98
+ width: 100%;
99
+ padding: 0.375rem 0.45rem;
100
+ border-radius: var(--fs-control-inner-border-radius);
101
+ justify-content: space-between;
102
+ font-size: var(--fs-body2-font-size);
103
+ line-height: var(--fs-caption-line-height);
104
+ & :global(svg) {
105
+ width: 1.25rem;
106
+ fill: currentColor;
107
+ & > :global(path) {
108
+ fill: currentColor;
109
+ }
110
+ }
111
+ & .label {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 0.5rem;
115
+ font-size: inherit;
116
+ justify-content: space-between;
117
+ flex: 1;
118
+ /* Mirrors the ToggleSwitch track and thumb, driven by `.checked` on the item. */
119
+ & .item-switch {
120
+ margin-left: 1rem;
121
+ pointer-events: none;
122
+ position: relative;
123
+ display: inline-flex;
124
+ align-items: center;
125
+ box-sizing: border-box;
126
+ width: 2.5rem;
127
+ min-width: 2.5rem;
128
+ height: 1.25rem;
129
+ padding: 0.063rem;
130
+ border: 0.063rem solid var(--fs-control-strong-stroke-default);
131
+ border-radius: 1.125rem;
132
+ background-color: var(--fs-control-alt-fill-secondary);
133
+ &::after {
134
+ content: '';
135
+ position: absolute;
136
+ left: 0.22rem;
137
+ width: 0.75rem;
138
+ height: 0.75rem;
139
+ border-radius: 0.75rem;
140
+ background-color: var(--fs-text-secondary);
141
+ transition: transform var(--fs-fast-duration) var(--fs-point-to-point);
142
+ }
143
+ &.on {
144
+ background-color: var(--fs-accent-fill-default);
145
+ border-color: var(--fs-accent-fill-default);
146
+ &::after {
147
+ transform: translateX(1.25rem);
148
+ background-color: var(--fs-text-on-accent-primary);
149
+ }
150
+ }
151
+ &.disabled {
152
+ background-color: var(--fs-control-alt-fill-disabled);
153
+ border-color: var(--fs-control-strong-stroke-disabled);
154
+ &::after {
155
+ background-color: var(--fs-text-disabled);
156
+ }
157
+ &.on {
158
+ background-color: var(--fs-accent-fill-disabled);
159
+ border-color: var(--fs-accent-fill-disabled);
160
+ &::after {
161
+ background-color: var(--fs-text-on-accent-disabled);
162
+ }
163
+ }
164
+ }
165
+ }
166
+ }
167
+ & .secondary-content {
168
+ font-size: var(--fs-caption-font-size);
169
+ color: var(--fs-text-secondary);
170
+ margin-left: 0.6rem;
171
+ }
172
+ &:global(.align .label:not(:has(.menu-item-icon))) {
173
+ margin-left: var(--margin-left) !important;
174
+ }
175
+ & .sub-text {
176
+ display: flex;
177
+ flex-direction: column;
178
+ align-items: flex-start;
179
+ text-align: left;
180
+ font-size: inherit;
181
+ & small {
182
+ font-size: var(--fs-caption2-font-size);
183
+ color: var(--fs-text-secondary);
184
+ }
185
+ }
186
+ & :global(svg.indicator) {
187
+ width: 20px;
188
+ opacity: 0;
189
+ }
190
+ &.checked :global(svg.indicator) {
191
+ opacity: 1;
192
+ }
193
+ }
194
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { MenuItemActionableProps } from './types.ts';
2
+ /**
3
+ * - Usage:
4
+ * ```tsx
5
+ * <Menu hasIcons>
6
+ * <MenuGroup name="Inputs">
7
+ * <MenuItemSwitch secondaryContent="Item 1" hint="Ctrl + 1" {Icon}>Item 1</MenuItemSwitch>
8
+ * <MenuItemSwitch secondaryContent="Item 2" hint="Ctrl + 2">Item 2</MenuItemSwitch>
9
+ * </MenuGroup>
10
+ * </Menu>
11
+ * ```
12
+ */
13
+ declare const MenuItemSwitch: import("svelte").Component<MenuItemActionableProps, {}, "ref" | "checked">;
14
+ type MenuItemSwitch = ReturnType<typeof MenuItemSwitch>;
15
+ export default MenuItemSwitch;
@@ -0,0 +1,124 @@
1
+ <script lang="ts">
2
+ import { Button } from '../../index.js';
3
+ import { getMenuContext, COMPONENT_NAME as MENU_COMPONENT_NAME } from './menu.svelte.js';
4
+ import { PREFIX } from '../../internal/constants.js';
5
+ import { invokeHandlers, RenderSoC } from '../../internal/index.js';
6
+ import type { MenuItemProps } from './types.js';
7
+ import type { ComponentProps } from 'svelte';
8
+
9
+ const FALLBACK_ID = $props.id();
10
+ const COMPONENT_NAME = 'menu-item';
11
+ const ID = `${PREFIX}${COMPONENT_NAME}-${FALLBACK_ID}`;
12
+
13
+ let {
14
+ ref = $bindable(),
15
+ icon: Icon,
16
+ secondaryContent,
17
+ children,
18
+ href,
19
+ id = ID,
20
+ disabled,
21
+ class: classes,
22
+ onclick,
23
+ onkeydown,
24
+ subText,
25
+ ...attributes
26
+ }: MenuItemProps & ComponentProps<typeof Button> = $props();
27
+
28
+ const context = getMenuContext();
29
+
30
+ if (!context) throw new Error(`No MenuContext found for ${MENU_COMPONENT_NAME}.`);
31
+
32
+ const { hasIcons, hasCheckmarks, persistOnItemActivation } = context.config;
33
+
34
+ const { toggle } = context.methods;
35
+
36
+ const marginLeft = $derived(1.5 * (+!!(hasIcons && !Icon) + +!!hasCheckmarks));
37
+ </script>
38
+
39
+ <!--
40
+ @component
41
+
42
+ - Usage:
43
+ ```tsx
44
+ <Menu hasIcons>
45
+ <MenuGroup name="Inputs">
46
+ <MenuItem secondaryContent="Item 1" hint="Ctrl + 1" {Icon}>Item 1</MenuItem>
47
+ <MenuItem secondaryContent="Item 2" hint="Ctrl + 2">Item 2</MenuItem>
48
+ </MenuGroup>
49
+ </Menu>
50
+ ```
51
+ -->
52
+ <Button
53
+ {href}
54
+ {disabled}
55
+ {id}
56
+ role="menuitem"
57
+ appearance="subtle"
58
+ onclick={(e: MouseEvent) => invokeHandlers(e, [persistOnItemActivation, disabled], [onclick, toggle])}
59
+ onkeydown={(e: KeyboardEvent) =>
60
+ invokeHandlers(e, [e.key !== 'Enter', persistOnItemActivation, disabled], [onkeydown, toggle])}
61
+ as={href ? 'a' : 'button'}
62
+ style={`--margin-left: ${marginLeft}rem;`}
63
+ class="fs-menu-item {hasIcons || hasCheckmarks ? 'align' : ''} {classes}"
64
+ bind:ref
65
+ {...attributes}
66
+ >
67
+ <span class="label" aria-label={secondaryContent ? `${secondaryContent}, Use ${secondaryContent}` : undefined}>
68
+ {#if Icon}
69
+ <RenderSoC SoC={Icon} args={[{ class: 'menu-item-icon' }]} class="menu-item-icon" />
70
+ {/if}
71
+ {#if subText}
72
+ <span class="sub-text">
73
+ {@render children?.()}
74
+ <small>{subText}</small>
75
+ </span>
76
+ {:else}
77
+ {@render children?.()}
78
+ {/if}
79
+ </span>
80
+ {#if secondaryContent}
81
+ <span class="secondary-content" aria-hidden="true">{secondaryContent}</span>
82
+ {/if}
83
+ </Button>
84
+
85
+ <style>
86
+ :global(.fs-menu-item.fs-button) {
87
+ width: 100%;
88
+ padding: 0.375rem 0.45rem;
89
+ border-radius: var(--fs-control-inner-border-radius);
90
+ justify-content: space-between;
91
+ font-size: var(--fs-body2-font-size);
92
+ line-height: var(--fs-caption-line-height);
93
+
94
+ & .label {
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 0.25rem;
98
+ font-size: inherit;
99
+ line-height: inherit;
100
+ }
101
+ & .secondary-content {
102
+ font-size: var(--fs-caption-font-size);
103
+ color: var(--fs-text-secondary);
104
+ margin-left: 0.6rem;
105
+ }
106
+ &:global(.align) {
107
+ & .label:not(:has(.menu-item-icon)),
108
+ & .label:not(:has(.fs-menu-item-checkmark, .fs-menu-item-radio, .fs-menu-item-switch)) {
109
+ margin-left: var(--margin-left) !important;
110
+ }
111
+ }
112
+ & .sub-text {
113
+ display: flex;
114
+ flex-direction: column;
115
+ align-items: flex-start;
116
+ text-align: left;
117
+ font-size: inherit;
118
+ & small {
119
+ font-size: var(--fs-caption2-font-size);
120
+ color: var(--fs-text-secondary);
121
+ }
122
+ }
123
+ }
124
+ </style>
@@ -0,0 +1,18 @@
1
+ import { Button } from '../../index.js';
2
+ import type { MenuItemProps } from './types.ts';
3
+ import type { ComponentProps } from 'svelte';
4
+ type $$ComponentProps = MenuItemProps & ComponentProps<typeof Button>;
5
+ /**
6
+ * - Usage:
7
+ * ```tsx
8
+ * <Menu hasIcons>
9
+ * <MenuGroup name="Inputs">
10
+ * <MenuItem secondaryContent="Item 1" hint="Ctrl + 1" {Icon}>Item 1</MenuItem>
11
+ * <MenuItem secondaryContent="Item 2" hint="Ctrl + 2">Item 2</MenuItem>
12
+ * </MenuGroup>
13
+ * </Menu>
14
+ * ```
15
+ */
16
+ declare const MenuItem: import("svelte").Component<$$ComponentProps, {}, "ref">;
17
+ type MenuItem = ReturnType<typeof MenuItem>;
18
+ export default MenuItem;
@@ -0,0 +1,38 @@
1
+ <script lang="ts">
2
+ import { getTabspotAttributes } from 'tabspot';
3
+ import { getMenuContext } from './menu.svelte.js';
4
+
5
+ let { children } = $props();
6
+
7
+ const context = getMenuContext();
8
+
9
+ let isSubMenu = $derived(context?.config.isSubMenu);
10
+ </script>
11
+
12
+ <div
13
+ class="fs-menu-list"
14
+ role="menu"
15
+ {...getTabspotAttributes({
16
+ mover: { axis: 'vertical' },
17
+ grouper: isSubMenu
18
+ ? {
19
+ enterDirection: 'right',
20
+ exitDirection: 'left'
21
+ }
22
+ : undefined
23
+ })}
24
+ >
25
+ {@render children()}
26
+ </div>
27
+
28
+ <style>
29
+ .fs-menu-list {
30
+ display: flex;
31
+ flex-direction: column;
32
+ padding: 0;
33
+ margin: 0;
34
+ list-style: none;
35
+ padding: 0.25rem;
36
+ flex-grow: 1;
37
+ }
38
+ </style>
@@ -0,0 +1,5 @@
1
+ declare const MenuList: import("svelte").Component<{
2
+ children: any;
3
+ }, {}, "">;
4
+ type MenuList = ReturnType<typeof MenuList>;
5
+ export default MenuList;
@@ -0,0 +1,125 @@
1
+ <script lang="ts">
2
+ import { circOut } from 'svelte/easing';
3
+ import { Flyout } from '../../index.js';
4
+ import { COMPONENT_NAME, getIntroTransition, getMenuContext } from './menu.svelte.js';
5
+ import { flip, hide, offset, shift } from '@floating-ui/dom';
6
+ import { useDebounce } from 'runed';
7
+ import { floating, flyToOffset, getCSSDuration, reactiveBoundingRect } from '../../internal/index.js';
8
+ import { getReducedMotion } from '../../providers/fluentui-svelte/fluentui-svelte.js';
9
+ import type { Snippet } from 'svelte';
10
+ import type { ComputePositionConfig } from '@floating-ui/dom';
11
+
12
+ let {
13
+ ref: _ref,
14
+ open: _open = $bindable(),
15
+ placement,
16
+ positionConfig: floatingPosition = {
17
+ placement,
18
+ middleware: [offset(-2), flip({ crossAxis: true, padding: 0 }), shift({ crossAxis: true, padding: 0 }), hide()],
19
+ strategy: 'fixed'
20
+ },
21
+ children
22
+ }: {
23
+ ref?: HTMLElement;
24
+ open?: boolean;
25
+ placement?: ComputePositionConfig['placement'];
26
+ positionConfig?: Partial<ComputePositionConfig>;
27
+ children: Snippet;
28
+ } = $props();
29
+
30
+ const context = getMenuContext();
31
+
32
+ if (!context) throw new Error(`No MenuContext found for ${COMPONENT_NAME}.`);
33
+
34
+ const reducedMotion = getReducedMotion();
35
+
36
+ const { positionConfig, id, isSubMenu, openOnHover, openingDelay } = context.config;
37
+
38
+ const { close } = context.methods;
39
+
40
+ let opened = $derived(_open ?? context.state.open);
41
+
42
+ let ref = $derived(_ref ?? context.state.ref);
43
+
44
+ let { state: _state } = context;
45
+
46
+ // The `placement` prop wins over the one coming from the config
47
+ let config = $derived.by(() => {
48
+ const base = positionConfig ?? floatingPosition;
49
+
50
+ return { ...base, placement: placement ?? base.placement ?? (isSubMenu ? 'right-start' : 'bottom-start') };
51
+ });
52
+
53
+ let boundingElement = reactiveBoundingRect();
54
+
55
+ let duration = $state(333);
56
+
57
+ let element: HTMLElement | null = $state(null);
58
+
59
+ const debounced = useDebounce((e: MouseEvent) => {
60
+ // Where the mouse is moving to
61
+ const to = e.relatedTarget as HTMLElement | null;
62
+ const isPopover = to?.id === `fs-menu-popover-${id}` || to?.closest(`#fs-menu-popover-${id}`);
63
+ const isTrigger =
64
+ to?.id === `fs-${isSubMenu ? 'submenu' : 'menu'}-trigger-${id}` ||
65
+ to?.closest(`#fs-${isSubMenu ? 'submenu' : 'menu'}-trigger-${id}`);
66
+
67
+ if (to && !isPopover && !isTrigger && !_state.locked) close(e);
68
+ }, openingDelay || 0);
69
+
70
+ $effect.pre(() => {
71
+ duration = getCSSDuration('--fs-normal-duration') || 333;
72
+
73
+ if (isSubMenu) floatingPosition.placement ??= 'right-start';
74
+
75
+ if (ref && ref instanceof HTMLElement) boundingElement.ref = ref;
76
+
77
+ // Make sure to update the position of boundingElement before the popover is shown
78
+ if (opened) boundingElement.update();
79
+ });
80
+ </script>
81
+
82
+ {#if opened && ref}
83
+ {@const isRefAnElement = ref instanceof HTMLElement}
84
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
85
+ <div
86
+ bind:this={element}
87
+ class="fs-menu-popover"
88
+ onmouseleave={openOnHover ? (e: MouseEvent) => debounced(e) : undefined}
89
+ {@attach ref ? floating(ref, config) : undefined}
90
+ style={`--position=${isSubMenu ? 'absolute' : 'fixed'} --min-width=${isRefAnElement && !isSubMenu ? `${boundingElement.rect.width}px` : 'max-content'}`}
91
+ in:flyToOffset={isRefAnElement
92
+ ? {
93
+ ...getIntroTransition({ config, anchor: boundingElement.rect, element, ref, isSubMenu }),
94
+ duration: duration,
95
+ easing: circOut,
96
+ reducedMotion: reducedMotion()
97
+ }
98
+ : undefined}
99
+ >
100
+ <Flyout class="fs-menu-popover" id="fs-menu-popover-{id}" role="menu">
101
+ {@render children()}
102
+ </Flyout>
103
+ </div>
104
+ {/if}
105
+
106
+ <style>
107
+ .fs-menu-popover {
108
+ position: var(--position, fixed);
109
+ top: 0;
110
+ left: 0;
111
+ width: max-content;
112
+ min-width: var(--min-width);
113
+ z-index: 110;
114
+ & :global(.fs-flyout),
115
+ & :global(.fs-flyout::before) {
116
+ border-radius: var(--fs-control-border-radius);
117
+ }
118
+ & :global(.fs-flyout) {
119
+ padding: 0;
120
+ & :global(> .wrapper) {
121
+ width: 100% !important;
122
+ }
123
+ }
124
+ }
125
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { ComputePositionConfig } from '@floating-ui/dom';
3
+ type $$ComponentProps = {
4
+ ref?: HTMLElement;
5
+ open?: boolean;
6
+ placement?: ComputePositionConfig['placement'];
7
+ positionConfig?: Partial<ComputePositionConfig>;
8
+ children: Snippet;
9
+ };
10
+ declare const MenuPopover: import("svelte").Component<$$ComponentProps, {}, "open">;
11
+ type MenuPopover = ReturnType<typeof MenuPopover>;
12
+ export default MenuPopover;