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,73 @@
1
+ # AutoSuggestBox
2
+
3
+ The AutoSuggestBox component provides an input field with dynamic suggestions as users type. It enhances user experience by offering relevant suggestions, improving efficiency in form inputs and searches.
4
+
5
+ ## Usage
6
+
7
+ ```svelte
8
+ <script>
9
+ import { AutoSuggestBox, AutoSuggestBoxOption } from 'fluentui-svelte';
10
+ </script>
11
+
12
+ <AutoSuggestBox placeholder="Type a fruit...">
13
+ <AutoSuggestBoxOption index={0} value="Apple">Apple</AutoSuggestBoxOption>
14
+ <AutoSuggestBoxOption index={1} value="Banana">Banana</AutoSuggestBoxOption>
15
+ <AutoSuggestBoxOption index={2} value="Cherry">Cherry</AutoSuggestBoxOption>
16
+ </AutoSuggestBox>
17
+ ```
18
+
19
+ ## Examples
20
+
21
+ ### Virtualized Suggestions
22
+
23
+ Long lists can be windowed. Pass a `virtualizer` describing the _whole_ list — `size` is the
24
+ total number of suggestions, not the number rendered — and the box drives your list component
25
+ when the cursor walks past what is on screen. Options keep their real `index`, which is what
26
+ ties a rendered row back to the data.
27
+
28
+ ```svelte
29
+ <script>
30
+ import SvelteVirtualList from '@humanspeak/svelte-virtual-list';
31
+
32
+ let items = $state(fruits);
33
+ let listRef;
34
+ </script>
35
+
36
+ <AutoSuggestBox
37
+ placeholder="Type a fruit..."
38
+ virtualizer={{
39
+ size: items.length,
40
+ scrollToTop: () => listRef.scroll({ index: 0, align: 'top', smoothScroll: false }),
41
+ scrollToBottom: () => listRef.scroll({ index: items.length - 1, align: 'bottom', smoothScroll: false }),
42
+ scrollToIndex: (index) => listRef.scroll({ index, align: 'auto', smoothScroll: false })
43
+ }}
44
+ textChanged={(e, val) => (items = fruits.filter((item) => item.name.toLowerCase().includes(val.toLowerCase())))}
45
+ >
46
+ <SvelteVirtualList {items} bind:this={listRef} defaultEstimatedItemHeight={30}>
47
+ {#snippet renderItem(item, index)}
48
+ <AutoSuggestBoxOption {index} id={item.id} value={item.name} text={item.name}>
49
+ {item.name}
50
+ </AutoSuggestBoxOption>
51
+ {/snippet}
52
+ </SvelteVirtualList>
53
+ </AutoSuggestBox>
54
+ ```
55
+
56
+ Filtering is yours to do in `textChanged`: a windowed list renders from your data, so the
57
+ built-in filter that a plain option list applies is skipped.
58
+
59
+ ## Component Props
60
+
61
+ | Name | Type | Description |
62
+ | ------------------ | --------------------------------------------------------- | ---------------------------------------------------------------------- |
63
+ | `placeholder` | `string` | Placeholder text shown in the input. |
64
+ | `value` | `string` | The current value of the input field. |
65
+ | `open` | `boolean` | Whether the suggestion flyout is open. Default: `false`. |
66
+ | `multiselect` | `boolean` | Allow selecting multiple suggestions. |
67
+ | `selectOnFocus` | `boolean` | Select a suggestion as it is focused during keyboard navigation. |
68
+ | `notFoundText` | `string` | Text shown when no suggestions match. Default: `No results found`. |
69
+ | `maxItemsInView` | `number` | Number of suggestions visible before the flyout scrolls. Default: `6`. |
70
+ | `ref` | `HTMLElement` | The DOM reference of the auto-suggest box element. |
71
+ | `suggestionChosen` | `(e: Event, selection: string) => void` | Event triggered when a suggestion is chosen. |
72
+ | `querySubmitted` | `(e: MouseEvent \| KeyboardEvent, query: string) => void` | Event triggered when a query is submitted. |
73
+ | `virtualizer` | `{ size, scrollToIndex?, scrollToTop?, scrollToBottom? }` | Bridge to a windowed list. `size` is the total suggestion count. |
@@ -0,0 +1,82 @@
1
+ <script lang="ts">
2
+ import { PREFIX } from '../../internal/constants.js';
3
+ import ListViewItem from '../list-view/list-view-item.svelte';
4
+ import { getAutoSuggestBoxContext } from './auto-suggest-box.js';
5
+ import type { AutoSuggestOptionProps } from './types.js';
6
+
7
+ const FALLBACK_ID = $props.id();
8
+ const ID = `${PREFIX}-${FALLBACK_ID}`;
9
+
10
+ let {
11
+ disabled,
12
+ ref = $bindable(),
13
+ id = ID,
14
+ value = id!,
15
+ text,
16
+ index,
17
+ children,
18
+ ...attributes
19
+ }: AutoSuggestOptionProps = $props();
20
+
21
+ const context = getAutoSuggestBoxContext();
22
+
23
+ if (!context) throw new Error('AutoSuggestOption must be used within an AutoSuggestBox');
24
+
25
+ const { config, state: _state, methods } = context;
26
+ const { selectOnFocus, virtualized } = config;
27
+ const { setOption, deleteOption, toggleSelection } = methods;
28
+
29
+ let isVisible = $derived(
30
+ value.toLowerCase().includes((_state.lastTypedValue || '').toLowerCase()) ||
31
+ text?.toLowerCase().includes((_state.lastTypedValue || '').toLowerCase())
32
+ );
33
+
34
+ function handleClick(e: MouseEvent) {
35
+ if (disabled) return;
36
+
37
+ toggleSelection?.(e, id);
38
+
39
+ if (!config.multiselect) _state.open = false;
40
+ }
41
+
42
+ // An option counts only while it is on screen: that is what makes the empty
43
+ // list detectable when a query filters everything out, and it keeps keyboard
44
+ // navigation off options nobody can see. The effect also covers the virtualizer
45
+ // remounting the same component instance with new data.
46
+ $effect(() => {
47
+ if (!isVisible && !virtualized) return;
48
+
49
+ // Capture current values to avoid them being stale in the callback
50
+ const _id = id;
51
+
52
+ setOption?.({ id, index, value, text, disabled });
53
+
54
+ return () => deleteOption?.(_id);
55
+ });
56
+ </script>
57
+
58
+ {#if isVisible || virtualized}
59
+ <ListViewItem
60
+ {id}
61
+ role="option"
62
+ {value}
63
+ tabindex={-1}
64
+ data-index={index}
65
+ class={['fs-autosuggest-option', selectOnFocus && 'no-outline']}
66
+ onclick={handleClick}
67
+ bind:ref
68
+ {disabled}
69
+ {...attributes}
70
+ >
71
+ {@render children?.()}
72
+ </ListViewItem>
73
+ {/if}
74
+
75
+ <style>
76
+ /* Tabspot marks the option under the cursor with `data-active`, which
77
+ ListViewItem already outlines. With selectOnFocus the text box mirrors that
78
+ option instead, so the outline would be noise. */
79
+ :global(.fs-autosuggest-option.no-outline) {
80
+ outline: 0 !important;
81
+ }
82
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { AutoSuggestOptionProps } from './types.ts';
2
+ declare const Option: import("svelte").Component<AutoSuggestOptionProps, {}, "ref">;
3
+ type Option = ReturnType<typeof Option>;
4
+ export default Option;
@@ -0,0 +1,140 @@
1
+ import type { FSContext } from '../../internal/index.js';
2
+ import type { TextBoxProps } from '../text-box/types.ts';
3
+ import type { ListViewItemProps } from '../list-view/types.ts';
4
+ import type { FlyoutProps } from '../flyout/types.ts';
5
+ import type { HTMLAttributes } from 'svelte/elements';
6
+ /** @propsmith AutoSuggestBoxProps */
7
+ export type AutoSuggestBoxProps = {
8
+ /** The DOM reference of the wrapper element.
9
+ * @bindable
10
+ */
11
+ ref?: HTMLElement;
12
+ /** The DOM reference of the text box element.
13
+ * @bindable
14
+ */
15
+ inputRef?: HTMLInputElement;
16
+ /** The current text of the box.
17
+ * @default ''
18
+ * @bindable
19
+ */
20
+ value?: string;
21
+ /** Controls the open state of the suggestion list.
22
+ * @default false
23
+ * @bindable
24
+ */
25
+ open?: boolean;
26
+ /** Lets more than one suggestion be chosen, and keeps the list open after each one. */
27
+ multiselect?: boolean;
28
+ /** Mirrors the suggestion under the cursor into the text box as it is walked over.
29
+ * Not supported together with `multiselect`.
30
+ */
31
+ selectOnFocus?: boolean;
32
+ /** Lists every chosen suggestion in the text box, comma separated. Multiselect only. */
33
+ showTextualMultiselect?: boolean;
34
+ /** The message shown in place of the list when nothing matches.
35
+ * @default 'No results found'
36
+ */
37
+ notFoundText?: string;
38
+ /** The suggestions currently chosen.
39
+ * @default []
40
+ * @bindable
41
+ */
42
+ selectedOptions?: {
43
+ id: string;
44
+ value: string;
45
+ }[];
46
+ /** Called when a suggestion is chosen: by clicking it, by pressing Enter on it, or by
47
+ * walking onto it while `selectOnFocus` is set.
48
+ */
49
+ suggestionChosen?: (e: Event, selection: string) => void;
50
+ /** Called when Enter is pressed with no suggestion under the cursor, or when the search
51
+ * button is clicked. This is where a fresh set of suggestions is fetched.
52
+ */
53
+ querySubmitted?: (e: MouseEvent | KeyboardEvent, query: string) => void;
54
+ /** Bridge to a windowed list, for suggestion sets too long to render whole.
55
+ * @type AutoSuggestVirtualizer
56
+ */
57
+ virtualizer?: AutoSuggestVirtualizer;
58
+ /** How many suggestions are visible before the list scrolls.
59
+ * @default 6
60
+ */
61
+ maxItemsInView?: number;
62
+ /** The DOM reference of the underlying text box input.
63
+ * @bindable
64
+ */
65
+ textBoxRef?: HTMLInputElement;
66
+ /** The props to spread on the text box.
67
+ * @type TextBoxProps
68
+ */
69
+ textBoxProps?: Omit<TextBoxProps, 'type' | 'ref' | 'placeholder' | 'hideActionButtons' | 'textChanged'>;
70
+ /** The DOM reference of the flyout holding the suggestion list.
71
+ * @bindable
72
+ */
73
+ flyoutRef?: HTMLElement;
74
+ /** The props to spread on the flyout.
75
+ * @type FlyoutProps
76
+ */
77
+ flyoutProps?: Omit<FlyoutProps, 'children' | 'ref'>;
78
+ /** The DOM reference of the suggestion list.
79
+ * @bindable
80
+ */
81
+ listViewRef?: HTMLUListElement;
82
+ /** The props to spread on the suggestion list.
83
+ * @type ListViewItemProps
84
+ */
85
+ listViewProps?: Omit<ListViewItemProps, 'as' | 'role' | 'ref' | 'navigationMode' | 'selectedItems'>;
86
+ } & Pick<TextBoxProps, 'type' | 'placeholder' | 'hideActionButtons' | 'textChanged'> & HTMLAttributes<HTMLDivElement>;
87
+ /**
88
+ * Bridge to a windowed list. `size` is the total number of suggestions, not the
89
+ * number currently rendered — it is how the box knows where the list really ends
90
+ * and which index to scroll to when the cursor walks past the rendered window.
91
+ */
92
+ export type AutoSuggestVirtualizer = {
93
+ size: number;
94
+ scrollToIndex?: (index: number) => void | Promise<void>;
95
+ scrollToTop?: () => void | Promise<void>;
96
+ scrollToBottom?: () => void | Promise<void>;
97
+ };
98
+ export type AutoSuggestBoxContext = FSContext<{
99
+ readonly selectOnFocus?: boolean;
100
+ readonly virtualized?: AutoSuggestVirtualizer;
101
+ multiselect?: boolean;
102
+ }, {
103
+ readonly searchValue?: string;
104
+ readonly textBoxRef?: HTMLInputElement;
105
+ readonly lastTypedValue?: string;
106
+ open?: boolean;
107
+ activeOption?: OptionType | null;
108
+ }, null, {
109
+ setOption: (item: OptionType) => void;
110
+ deleteOption: (id: string) => void;
111
+ toggleSelection: (e: Event, id: string) => void;
112
+ }>;
113
+ export type OptionType = {
114
+ id: string;
115
+ index: number;
116
+ value: string;
117
+ text?: string;
118
+ disabled?: boolean;
119
+ };
120
+ /** @propsmith AutoSuggestOptionProps */
121
+ export type AutoSuggestOptionProps = {
122
+ /** The value reported to the box when the suggestion is chosen. Falls back to the id. */
123
+ value?: string;
124
+ /** The text shown in the box once the suggestion is chosen. Falls back to `value`. */
125
+ text?: string;
126
+ /** The id of the option element, referenced by the box through `aria-activedescendant`.
127
+ * Falls back to a generated id.
128
+ */
129
+ id?: string;
130
+ /** The DOM reference of the option element.
131
+ * @bindable
132
+ */
133
+ ref?: HTMLLIElement;
134
+ /** Takes the suggestion out of reach: it is shown, but the cursor steps over it. */
135
+ disabled?: boolean;
136
+ /** Where the suggestion sits in the whole set. A windowed list needs the real index,
137
+ * not the position within the rendered slice.
138
+ */
139
+ index: number;
140
+ } & Omit<ListViewItemProps<'li'>, 'as' | 'value'>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,269 @@
1
+ <script lang="ts">
2
+ import { BadgeIcon } from '../../index.js';
3
+ import { pickColorByWord } from '../../css/utils.js';
4
+ import { getInitials, pxToRem, RenderSoC } from '../../internal/index.js';
5
+ import type { AvatarProps } from './type.js';
6
+
7
+ let {
8
+ size = 48,
9
+ name = 'Avatar',
10
+ image,
11
+ initials = name && getInitials(name),
12
+ shape = 'circular',
13
+ icon: Icon,
14
+ active,
15
+ color = 'attention',
16
+ style,
17
+ activeAppearance = 'ring',
18
+ ref = $bindable(),
19
+ idForColor,
20
+ badge,
21
+ ...attributes
22
+ }: AvatarProps = $props();
23
+
24
+ const avatarStyle = $derived(
25
+ `--av-size: ${pxToRem(size)}; ${color === 'colorful' ? '--av-color: ' + pickColorByWord(idForColor ?? name) + ';' : ''}`
26
+ );
27
+
28
+ const badgeSize = $derived((size / 2).toFixed(0) + 'px');
29
+
30
+ let hideBg = $state(false);
31
+ </script>
32
+
33
+ <!--
34
+ @component
35
+
36
+ This is a implementation of Fluen UI Avatar component.
37
+
38
+ An Avatar is a graphical representation of a user, team, or entity.
39
+
40
+ Avatar can display an image, icon, or initials, and supports various sizes and shapes.
41
+
42
+ - Usage:
43
+ ```tsx
44
+ <script>
45
+ import { Avatar } from 'fluentui-svelte';
46
+ </script>
47
+
48
+ <Avatar name="John Doe" size={48} />
49
+ ```
50
+ -->
51
+ <div
52
+ role="img"
53
+ aria-label={name}
54
+ bind:this={ref}
55
+ style="{avatarStyle} {style}"
56
+ class={[
57
+ 'fs-avatar',
58
+ color,
59
+ activeAppearance,
60
+ active,
61
+ shape,
62
+ hideBg && 'hide-bg',
63
+ (badge?.status || badge?.icon) && 'mask'
64
+ ]}
65
+ {...attributes}
66
+ >
67
+ <span class="content">
68
+ {#if image}
69
+ <img
70
+ class="fs-avatar-image {shape}"
71
+ src={image.src}
72
+ width={size}
73
+ height={size}
74
+ alt={name}
75
+ onload={() => (hideBg = true)}
76
+ />
77
+ {/if}
78
+ {#if Icon}
79
+ <RenderSoC SoC={Icon} args={[{ width: badgeSize, height: badgeSize }]} width={badgeSize} height={badgeSize} />
80
+ {:else}
81
+ {initials}
82
+ {/if}
83
+ </span>
84
+ {#if badge}
85
+ <BadgeIcon
86
+ size={Number((size / 3.25).toFixed(0))}
87
+ icon={badge?.icon || undefined}
88
+ status={badge?.status}
89
+ outOfOffice={badge?.outOfOffice}
90
+ />
91
+ {/if}
92
+ </div>
93
+
94
+ <style>
95
+ .fs-avatar {
96
+ display: inline-flex;
97
+ align-items: center;
98
+ justify-content: center;
99
+ position: relative;
100
+ width: var(--av-size);
101
+ height: var(--av-size);
102
+ font-size: calc(var(--av-size) / 2.4);
103
+ line-height: 1.4em;
104
+ font-weight: 500;
105
+ z-index: 0;
106
+ & :global(.fs-avatar-image) {
107
+ position: absolute;
108
+ inset: 0;
109
+ z-index: 1;
110
+ }
111
+ & > :global(.fs-badge-icon),
112
+ & > :global(.fs-badge),
113
+ & > :global(svg) {
114
+ position: absolute;
115
+ bottom: 0;
116
+ right: 0;
117
+ z-index: 1;
118
+ }
119
+ & .content {
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: center;
123
+ font-size: inherit;
124
+ width: 100%;
125
+ height: 100%;
126
+ z-index: 1;
127
+ color: var(--fs-text-on-accent-primary);
128
+ }
129
+ &::before {
130
+ content: '';
131
+ position: absolute;
132
+ top: 0;
133
+ left: 0;
134
+ width: 100%;
135
+ height: 100%;
136
+ border-radius: inherit;
137
+ }
138
+ &.ring::after,
139
+ &.ring-shadow::after {
140
+ font-size: calc(var(--av-size) / 4);
141
+ content: '';
142
+ position: absolute;
143
+ top: 50%;
144
+ left: 50%;
145
+ width: calc(100% + 1em);
146
+ height: calc(100% + 1em);
147
+ transform: translate(-50%, -50%);
148
+ border: max(1px, 0.3em) solid transparent;
149
+ opacity: 0;
150
+ transition: opacity 0.1s;
151
+ z-index: 0;
152
+ }
153
+ &.circular,
154
+ & :global(.circular),
155
+ &.circular::after {
156
+ border-radius: 9999rem;
157
+ }
158
+ &.rounded {
159
+ border-radius: var(--fs-control-border-radius);
160
+ }
161
+ &.rounded::after {
162
+ border-radius: calc(var(--fs-control-border-radius) + 0.325rem);
163
+ }
164
+ &.shadow,
165
+ &.ring-shadow {
166
+ filter: drop-shadow(var(--fs-shadow-flyout));
167
+ }
168
+ &.information {
169
+ color: var(--fs-system-neutral-text);
170
+ &::before {
171
+ background: var(--fs-system-neutral);
172
+ }
173
+ &:after {
174
+ border-color: var(--fs-system-neutral);
175
+ }
176
+ }
177
+ &.attention {
178
+ color: var(--fs-system-attention-text);
179
+ &::before {
180
+ background: var(--fs-system-attention);
181
+ }
182
+ &:after {
183
+ border-color: var(--fs-system-attention);
184
+ }
185
+ }
186
+ &.warning {
187
+ color: var(--fs-system-caution-text);
188
+ &::before {
189
+ background: var(--fs-system-caution);
190
+ }
191
+ &:after {
192
+ border-color: var(--fs-system-caution);
193
+ }
194
+ }
195
+ &.success {
196
+ color: var(--fs-system-success-text);
197
+ &::before {
198
+ background: var(--fs-system-success);
199
+ }
200
+ &:after {
201
+ border-color: var(--fs-system-success);
202
+ }
203
+ }
204
+ &.critical {
205
+ color: var(--fs-system-critical-text);
206
+ &::before {
207
+ background: var(--fs-system-critical);
208
+ }
209
+ &:after {
210
+ border-color: var(--fs-system-critical);
211
+ }
212
+ }
213
+ &.colorful {
214
+ & .content {
215
+ color: color-mix(in srgb, var(--av-color), contrast-color(var(--av-color)) 60%);
216
+ }
217
+ &::before {
218
+ background: var(--av-color);
219
+ }
220
+ &:after {
221
+ border-color: var(--av-color);
222
+ }
223
+ }
224
+ &.active {
225
+ &.ring::after,
226
+ &.ring-shadow::after {
227
+ opacity: 1;
228
+ }
229
+ }
230
+ &.inactive {
231
+ transform: scale(0.875);
232
+ }
233
+ &.mask {
234
+ /* Crop center */
235
+ --pos: calc(var(--av-size) / 6.1);
236
+ /* Transparent cutout radius */
237
+ --cut: calc(var(--av-size) * 0.228);
238
+ /* Border gradient width (fake anti-aliasing) */
239
+ --feather: max(1%, calc(var(--av-size) * 0.01));
240
+ & .content,
241
+ &::before,
242
+ & :global(.fs-avatar-image) {
243
+ --fs-mask: radial-gradient(
244
+ circle at right var(--pos) bottom var(--pos),
245
+ rgba(0, 0, 0, 0) var(--cut),
246
+ rgb(255, 255, 255) calc(var(--cut) + var(--feather))
247
+ );
248
+ -webkit-mask-image: var(--fs-mask);
249
+ mask-image: var(--fs-mask);
250
+ }
251
+ &::after {
252
+ --after-pos: calc(var(--pos) + (var(--av-size) / 4) / 2);
253
+ --after-cut: calc(var(--av-size) * 0.236);
254
+ --fs-mask: radial-gradient(
255
+ circle at right var(--after-pos) bottom var(--after-pos),
256
+ rgba(0, 0, 0, 0) var(--after-cut),
257
+ rgb(255, 255, 255) calc(var(--after-cut) + var(--feather))
258
+ );
259
+ -webkit-mask-image: var(--fs-mask);
260
+ mask-image: var(--fs-mask);
261
+ }
262
+ }
263
+ &.hide-bg {
264
+ &::before {
265
+ background: transparent;
266
+ }
267
+ }
268
+ }
269
+ </style>
@@ -0,0 +1,20 @@
1
+ import type { AvatarProps } from './type.ts';
2
+ /**
3
+ * This is a implementation of Fluen UI Avatar component.
4
+ *
5
+ * An Avatar is a graphical representation of a user, team, or entity.
6
+ *
7
+ * Avatar can display an image, icon, or initials, and supports various sizes and shapes.
8
+ *
9
+ * - Usage:
10
+ * ```tsx
11
+ * <script>
12
+ * import { Avatar } from 'fluentui-svelte';
13
+ * </script>
14
+ *
15
+ * <Avatar name="John Doe" size={48} />
16
+ * ```
17
+ */
18
+ declare const Avatar: import("svelte").Component<AvatarProps, {}, "ref">;
19
+ type Avatar = ReturnType<typeof Avatar>;
20
+ export default Avatar;
@@ -0,0 +1,92 @@
1
+ # Avatar
2
+
3
+ An Avatar is a graphical representation of a user, team, or entity.
4
+
5
+ Avatar can display an image, icon, or initials, and supports different sizes, shapes, and status indicators.
6
+
7
+ ## Usage
8
+
9
+ ```svelte
10
+ <script>
11
+ import { Avatar } from 'fluentui-svelte';
12
+ </script>
13
+
14
+ <Avatar size={40} name="FluentUI Svelte" />
15
+ ```
16
+
17
+ ## Component API
18
+
19
+ A brief explanation of the props that really need explaining. You can see the rest of the props in the Component Props table below.
20
+
21
+ ## Examples
22
+
23
+ ### Image
24
+
25
+ An avatar can display an image. It is recommended to also include a name in addition to the image: the initials from the name are displayed while the image is loading, and the name makes the Avatar accessible to screen readers.
26
+
27
+ ```svelte
28
+ <Avatar
29
+ active="active"
30
+ size={56}
31
+ name="FluentUI Svelte"
32
+ image={{ src: 'https://placehold.co/120x120/jpeg' }}
33
+ badge={{ status: 'do-not-disturb' }}
34
+ />
35
+ ```
36
+
37
+ ### Icon
38
+
39
+ An avatar can display an icon. The icon will only be shown when there is no image or initials available.
40
+
41
+ ```svelte
42
+ <script>
43
+ import { ClockRegular } from 'fluentui-icons-svelte';
44
+ </script>
45
+
46
+ <Avatar active="active" size={56} name="FluentUI Svelte" icon={ClockRegular} color="information" />
47
+ ```
48
+
49
+ ### Badge
50
+
51
+ An avatar can have a badge to indicate presence status. See the PresenceBadge component for more info.
52
+
53
+ ```svelte
54
+ <Avatar active="active" size={56} name="FluentUI Svelte" badge={{ status: 'available' }} />
55
+ ```
56
+
57
+ ### Shape
58
+
59
+ An avatar can have a square, circular, or rounded shape.
60
+
61
+ ```svelte
62
+ <Avatar active="active" size={56} name="FluentUI Svelte" badge={{ status: 'available' }} />
63
+ <Avatar active="active" size={56} name="FluentUI Svelte" badge={{ status: 'available' }} shape="rounded" />
64
+ <Avatar active="active" size={56} name="FluentUI Svelte" badge={{ status: 'available' }} shape="square" />
65
+ ```
66
+
67
+ ### Color: colorful
68
+
69
+ An avatar can have its color automatically picked based on the name prop, or idForColor can be used if a name is not available.
70
+
71
+ ```svelte
72
+ <Avatar active="active" size={56} name="FluentUI Svelte" color="colorful" />
73
+ <Avatar active="active" size={56} name="FluentUI Svelte" color="colorful" />
74
+ <Avatar active="active" size={56} name="FluentUI Svelte" color="colorful" />
75
+ ```
76
+
77
+ ## Component Props
78
+
79
+ | Name | Type | Description |
80
+ | ------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
81
+ | `name` | `string` | The name of the person or entity represented by this Avatar. Used to determine initials and for accessibility tools. |
82
+ | `image` | `{ src: string }` | The Avatar image. It can only be a single image URL. |
83
+ | `ref` | `HTMLDivElement` | The DOM reference of the avatar element. |
84
+ | `size` | `number` | Size of the avatar in pixels. |
85
+ | `shape` | `string` | The shape of the avatar. Possible values: 'circular', 'rounded', 'square'. |
86
+ | `color` | `string` | The color used when displaying either an icon or initials. Supports system colors. Possible values: 'information', 'attention', 'warning', 'success', 'critical', 'colorful'. |
87
+ | `active` | `string` | Optional activity indicator. Possible values: 'active', 'inactive'. Active decorates the avatar according to activeAppearance. Inactive reduces size and makes it partially transparent. |
88
+ | `activeAppearance` | `string` | The appearance used when active is set to active. Possible values: 'ring', 'shadow', 'ring-shadow'. |
89
+ | `initials` | `string` | Custom initials. By default, initials are derived from the name prop using the getInitials function. They are displayed when there is no image. |
90
+ | `idForColor` | `string` | A string used instead of the name to determine the color when color is set to colorful. Useful when a name is unavailable but another unique identifier exists. |
91
+ | `icon` | `Snippet` \| `Component` | The icon to display when the avatar does not have an image or initials. |
92
+ | `badge` | `object` | The badge to display as a status indicator. It can include a custom icon. |