svelte-fluentui 1.0.0-rc01

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 (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +191 -0
  3. package/dist/actions/use-actions.d.ts +1 -0
  4. package/dist/actions/use-actions.js +6 -0
  5. package/dist/components/Accordion.svelte +68 -0
  6. package/dist/components/Accordion.svelte.d.ts +11 -0
  7. package/dist/components/AccordionItem.svelte +52 -0
  8. package/dist/components/AccordionItem.svelte.d.ts +17 -0
  9. package/dist/components/Anchor.svelte +53 -0
  10. package/dist/components/Anchor.svelte.d.ts +25 -0
  11. package/dist/components/Badge.svelte +14 -0
  12. package/dist/components/Badge.svelte.d.ts +15 -0
  13. package/dist/components/Breadcrumb.svelte +8 -0
  14. package/dist/components/Breadcrumb.svelte.d.ts +8 -0
  15. package/dist/components/BreadcrumbItem.svelte +17 -0
  16. package/dist/components/BreadcrumbItem.svelte.d.ts +10 -0
  17. package/dist/components/Button.svelte +31 -0
  18. package/dist/components/Button.svelte.d.ts +24 -0
  19. package/dist/components/Calendar.svelte +442 -0
  20. package/dist/components/Calendar.svelte.d.ts +27 -0
  21. package/dist/components/Card.svelte +14 -0
  22. package/dist/components/Card.svelte.d.ts +14 -0
  23. package/dist/components/Checkbox.svelte +38 -0
  24. package/dist/components/Checkbox.svelte.d.ts +17 -0
  25. package/dist/components/Combobox.svelte +91 -0
  26. package/dist/components/Combobox.svelte.d.ts +21 -0
  27. package/dist/components/ContentRegion.svelte +7 -0
  28. package/dist/components/ContentRegion.svelte.d.ts +7 -0
  29. package/dist/components/DataGrid.svelte +26 -0
  30. package/dist/components/DataGrid.svelte.d.ts +16 -0
  31. package/dist/components/DataGridCell.svelte +33 -0
  32. package/dist/components/DataGridCell.svelte.d.ts +20 -0
  33. package/dist/components/DataGridRow.svelte +33 -0
  34. package/dist/components/DataGridRow.svelte.d.ts +16 -0
  35. package/dist/components/Dialog.svelte +86 -0
  36. package/dist/components/Dialog.svelte.d.ts +27 -0
  37. package/dist/components/Divider.svelte +9 -0
  38. package/dist/components/Divider.svelte.d.ts +4 -0
  39. package/dist/components/Listbox.svelte +34 -0
  40. package/dist/components/Listbox.svelte.d.ts +13 -0
  41. package/dist/components/Menu.svelte +9 -0
  42. package/dist/components/Menu.svelte.d.ts +4 -0
  43. package/dist/components/MenuItem.svelte +9 -0
  44. package/dist/components/MenuItem.svelte.d.ts +4 -0
  45. package/dist/components/NumberField.svelte +57 -0
  46. package/dist/components/NumberField.svelte.d.ts +29 -0
  47. package/dist/components/Option.svelte +28 -0
  48. package/dist/components/Option.svelte.d.ts +13 -0
  49. package/dist/components/Paginator.svelte +85 -0
  50. package/dist/components/Paginator.svelte.d.ts +21 -0
  51. package/dist/components/PositioningRegion.svelte +7 -0
  52. package/dist/components/PositioningRegion.svelte.d.ts +8 -0
  53. package/dist/components/Progress.svelte +9 -0
  54. package/dist/components/Progress.svelte.d.ts +4 -0
  55. package/dist/components/README.md +75 -0
  56. package/dist/components/Radio.svelte +23 -0
  57. package/dist/components/Radio.svelte.d.ts +11 -0
  58. package/dist/components/RadioGroup.svelte +26 -0
  59. package/dist/components/RadioGroup.svelte.d.ts +13 -0
  60. package/dist/components/Search.svelte +51 -0
  61. package/dist/components/Search.svelte.d.ts +30 -0
  62. package/dist/components/Select.svelte +41 -0
  63. package/dist/components/Select.svelte.d.ts +23 -0
  64. package/dist/components/Slider.svelte +9 -0
  65. package/dist/components/Slider.svelte.d.ts +4 -0
  66. package/dist/components/Switch.svelte +45 -0
  67. package/dist/components/Switch.svelte.d.ts +22 -0
  68. package/dist/components/Tab.svelte +52 -0
  69. package/dist/components/Tab.svelte.d.ts +23 -0
  70. package/dist/components/TabPanel.svelte +10 -0
  71. package/dist/components/TabPanel.svelte.d.ts +13 -0
  72. package/dist/components/Tabs.svelte +35 -0
  73. package/dist/components/Tabs.svelte.d.ts +21 -0
  74. package/dist/components/TextField.svelte +57 -0
  75. package/dist/components/TextField.svelte.d.ts +27 -0
  76. package/dist/components/Textarea.svelte +53 -0
  77. package/dist/components/Textarea.svelte.d.ts +32 -0
  78. package/dist/components/Toast.svelte +90 -0
  79. package/dist/components/Toast.svelte.d.ts +18 -0
  80. package/dist/components/Toolbar.svelte +16 -0
  81. package/dist/components/Toolbar.svelte.d.ts +12 -0
  82. package/dist/components/Tooltip.svelte +28 -0
  83. package/dist/components/Tooltip.svelte.d.ts +18 -0
  84. package/dist/components/Tree.svelte +9 -0
  85. package/dist/components/Tree.svelte.d.ts +4 -0
  86. package/dist/components/TreeItem.svelte +9 -0
  87. package/dist/components/TreeItem.svelte.d.ts +4 -0
  88. package/dist/components/icons/ChevronDoubleRight.svelte +1 -0
  89. package/dist/components/icons/ChevronDoubleRight.svelte.d.ts +26 -0
  90. package/dist/components/icons/ExpandIcon.svelte +9 -0
  91. package/dist/components/icons/ExpandIcon.svelte.d.ts +26 -0
  92. package/dist/components/icons/HamburgerIcon.svelte +8 -0
  93. package/dist/components/icons/HamburgerIcon.svelte.d.ts +26 -0
  94. package/dist/components/icons/ResourcesIcon.svelte +17 -0
  95. package/dist/components/icons/ResourcesIcon.svelte.d.ts +6 -0
  96. package/dist/components/icons/index.d.ts +4 -0
  97. package/dist/components/icons/index.js +4 -0
  98. package/dist/components/index.d.ts +45 -0
  99. package/dist/components/index.js +45 -0
  100. package/dist/components/layout/BodyContent.svelte +20 -0
  101. package/dist/components/layout/BodyContent.svelte.d.ts +7 -0
  102. package/dist/components/layout/Footer.svelte +13 -0
  103. package/dist/components/layout/Footer.svelte.d.ts +8 -0
  104. package/dist/components/layout/Header.svelte +13 -0
  105. package/dist/components/layout/Header.svelte.d.ts +8 -0
  106. package/dist/components/layout/Layout.svelte +10 -0
  107. package/dist/components/layout/Layout.svelte.d.ts +8 -0
  108. package/dist/components/layout/Spacer.svelte +18 -0
  109. package/dist/components/layout/Spacer.svelte.d.ts +6 -0
  110. package/dist/components/layout/Stack.svelte +19 -0
  111. package/dist/components/layout/Stack.svelte.d.ts +18 -0
  112. package/dist/components/layout/index.d.ts +6 -0
  113. package/dist/components/layout/index.js +6 -0
  114. package/dist/components/nav/AppBar.svelte +15 -0
  115. package/dist/components/nav/AppBar.svelte.d.ts +10 -0
  116. package/dist/components/nav/AppBarItem.svelte +34 -0
  117. package/dist/components/nav/AppBarItem.svelte.d.ts +14 -0
  118. package/dist/components/nav/NavExpander.svelte +18 -0
  119. package/dist/components/nav/NavExpander.svelte.d.ts +7 -0
  120. package/dist/components/nav/NavGroup.svelte +244 -0
  121. package/dist/components/nav/NavGroup.svelte.d.ts +12 -0
  122. package/dist/components/nav/NavIcon.svelte +7 -0
  123. package/dist/components/nav/NavIcon.svelte.d.ts +7 -0
  124. package/dist/components/nav/NavItem.svelte +17 -0
  125. package/dist/components/nav/NavItem.svelte.d.ts +11 -0
  126. package/dist/components/nav/NavLink.svelte +31 -0
  127. package/dist/components/nav/NavLink.svelte.d.ts +13 -0
  128. package/dist/components/nav/NavLinkItem.svelte +23 -0
  129. package/dist/components/nav/NavLinkItem.svelte.d.ts +17 -0
  130. package/dist/components/nav/NavMenu.svelte +19 -0
  131. package/dist/components/nav/NavMenu.svelte.d.ts +11 -0
  132. package/dist/components/nav/index.d.ts +8 -0
  133. package/dist/components/nav/index.js +8 -0
  134. package/dist/constants/date.d.ts +1 -0
  135. package/dist/constants/date.js +1 -0
  136. package/dist/data/selected-options.svelte.d.ts +8 -0
  137. package/dist/data/selected-options.svelte.js +51 -0
  138. package/dist/fluent-ui/calendar/calendar-day.d.ts +17 -0
  139. package/dist/fluent-ui/calendar/calendar-day.js +56 -0
  140. package/dist/fluent-ui/calendar/calendar-month.d.ts +12 -0
  141. package/dist/fluent-ui/calendar/calendar-month.js +56 -0
  142. package/dist/fluent-ui/calendar/calendar-titles.d.ts +15 -0
  143. package/dist/fluent-ui/calendar/calendar-titles.js +99 -0
  144. package/dist/fluent-ui/calendar/calendar-year.d.ts +12 -0
  145. package/dist/fluent-ui/calendar/calendar-year.js +46 -0
  146. package/dist/fluent-ui/calendar/day-format.d.ts +4 -0
  147. package/dist/fluent-ui/calendar/day-format.js +3 -0
  148. package/dist/fluent-ui/calendar/fluent-calendar-extended.d.ts +44 -0
  149. package/dist/fluent-ui/calendar/fluent-calendar-extended.js +170 -0
  150. package/dist/fluent-ui/calendar/fluent-calendar.d.ts +18 -0
  151. package/dist/fluent-ui/calendar/fluent-calendar.js +1 -0
  152. package/dist/fluent-ui/calendar/range-of-dates.d.ts +8 -0
  153. package/dist/fluent-ui/calendar/range-of-dates.js +34 -0
  154. package/dist/fluent-ui/constants/app-bar.d.ts +4 -0
  155. package/dist/fluent-ui/constants/app-bar.js +5 -0
  156. package/dist/fluent-ui/constants/button.d.ts +7 -0
  157. package/dist/fluent-ui/constants/button.js +8 -0
  158. package/dist/fluent-ui/constants/calendar-vertical-position.d.ts +5 -0
  159. package/dist/fluent-ui/constants/calendar-vertical-position.js +6 -0
  160. package/dist/fluent-ui/constants/stack.d.ts +20 -0
  161. package/dist/fluent-ui/constants/stack.js +23 -0
  162. package/dist/fluent-ui/setup.d.ts +1 -0
  163. package/dist/fluent-ui/setup.js +7 -0
  164. package/dist/fluent-ui/util/range-of.d.ts +21 -0
  165. package/dist/fluent-ui/util/range-of.js +84 -0
  166. package/dist/helpers/array.d.ts +2 -0
  167. package/dist/helpers/array.js +6 -0
  168. package/dist/helpers/html.d.ts +2 -0
  169. package/dist/helpers/html.js +10 -0
  170. package/dist/index.d.ts +1 -0
  171. package/dist/index.js +1 -0
  172. package/dist/main.scss +1 -0
  173. package/dist/types/combobox.d.ts +7 -0
  174. package/dist/types/combobox.js +1 -0
  175. package/dist/types/index.d.ts +10 -0
  176. package/dist/types/index.js +1 -0
  177. package/package.json +83 -0
@@ -0,0 +1,442 @@
1
+ <script lang="ts">import Calendar from "./Calendar.svelte";
2
+ import { CalendarDay } from "../fluent-ui/calendar/calendar-day.js";
3
+ import { CalendarMonth } from "../fluent-ui/calendar/calendar-month.js";
4
+ import { CalendarYear } from "../fluent-ui/calendar/calendar-year.js";
5
+ import { CalendarExtended } from "../fluent-ui/calendar/fluent-calendar-extended.js";
6
+ import { CalendarTitles } from "../fluent-ui/calendar/calendar-titles.js";
7
+ import { RangeOfDates } from "../fluent-ui/calendar/range-of-dates.js";
8
+ import { CalendarVerticalPosition } from "../fluent-ui/constants/calendar-vertical-position.js";
9
+ import { tick } from "svelte";
10
+ import { getLargest, getSmallest } from "../helpers/array.js";
11
+ let { value = new Date(), selectedDates = [], pickerMonth = $bindable(new Date()), view = "days", culture = new Intl.Locale(window.navigator.language), disabledCheckAllDaysOfMonthYear = undefined, animatePeriodChanges = undefined, disabledSelectable = undefined, readonly = undefined, selectMode = "single", checkIfSelectedValueHasChanged = undefined, dayFormat = undefined, disabledDateFunc = undefined, selectDatesHover = undefined, onDatesSelected = undefined, onDateSelected = undefined, day: daySnippet = undefined, ...restProps } = $props();
12
+ let _rangeSelector = $state(new RangeOfDates());
13
+ let _rangeSelectorMouseOver = $state(new RangeOfDates());
14
+ let _pickerView = $state(null);
15
+ let _selectedDatesMouseOver = $state([]);
16
+ let _animationRunning = $state(CalendarVerticalPosition.Unset);
17
+ const canBeAnimated = $derived(animatePeriodChanges ?? (view !== "days" && view !== "years"));
18
+ const calendarExtended = $derived((value, new CalendarExtended(culture, pickerMonth)));
19
+ const calendar = $derived({
20
+ view,
21
+ calendarExtended,
22
+ culture: culture,
23
+ dayFormat,
24
+ disabledCheckAllDaysOfMonthYear: false,
25
+ disabledSelectable: false,
26
+ readOnly: readonly ?? false,
27
+ selectMode,
28
+ value: value,
29
+ selectedDates: selectedDates,
30
+ allDaysAreDisabled,
31
+ disabledDateFunc: disabledDateFunc || ((_d) => false)
32
+ });
33
+ const titles = $derived(new CalendarTitles(calendar));
34
+ const multipleSelection = $derived(getMultipleSelection());
35
+ const year = $derived(pickerMonth.getFullYear());
36
+ function getMultipleSelection() {
37
+ let inProgress = selectDatesHover !== null;
38
+ if (selectedDates == null || !selectedDates.length) {
39
+ return {
40
+ isMultiple: false,
41
+ min: new Date(0),
42
+ max: new Date(0),
43
+ inProgress
44
+ };
45
+ }
46
+ if (selectDatesHover === null) {
47
+ inProgress = !_rangeSelector.isValid();
48
+ }
49
+ else {
50
+ inProgress = _rangeSelectorMouseOver.isValid();
51
+ }
52
+ return {
53
+ isMultiple: (selectMode == "multiple" || selectMode == "range") && selectedDates.length > 1,
54
+ min: selectedDates.reduce((acc, x) => !acc || x < acc ? x : acc),
55
+ max: selectedDates.reduce((acc, x) => !acc || x > acc ? x : acc),
56
+ inProgress
57
+ };
58
+ }
59
+ function getAnimationClass(existingClass) {
60
+ if (!canBeAnimated) {
61
+ return existingClass;
62
+ }
63
+ switch (_animationRunning) {
64
+ case CalendarVerticalPosition.Top:
65
+ return `${existingClass} animation-running-up`;
66
+ case CalendarVerticalPosition.Bottom:
67
+ return `${existingClass} animation-running-down`;
68
+ default:
69
+ return `${existingClass} animation-none`;
70
+ }
71
+ }
72
+ function onTitleClicked(title) {
73
+ if (title.readOnly) {
74
+ return;
75
+ }
76
+ switch (view) {
77
+ // Days -> Months
78
+ case "days":
79
+ _pickerView = "months";
80
+ break;
81
+ // Months -> Years
82
+ case "months":
83
+ _pickerView = "years";
84
+ break;
85
+ }
86
+ }
87
+ async function onPreviousButtonClicked(e) {
88
+ await startNewAnimationAsync(CalendarVerticalPosition.Bottom);
89
+ switch (view) {
90
+ case "days":
91
+ pickerMonth.setMonth(pickerMonth.getMonth() - 1);
92
+ break;
93
+ case "months":
94
+ pickerMonth.setFullYear(pickerMonth.getFullYear() - 1);
95
+ break;
96
+ case "years":
97
+ pickerMonth.setFullYear(pickerMonth.getFullYear() - 12);
98
+ break;
99
+ }
100
+ pickerMonth = new Date(pickerMonth);
101
+ }
102
+ async function onNextButtonHandlerAsync(e) {
103
+ await startNewAnimationAsync(CalendarVerticalPosition.Top);
104
+ switch (view) {
105
+ case "days":
106
+ pickerMonth.setMonth(pickerMonth.getMonth() + 1);
107
+ break;
108
+ case "months":
109
+ pickerMonth.setFullYear(pickerMonth.getFullYear() + 1);
110
+ break;
111
+ case "years":
112
+ pickerMonth.setFullYear(pickerMonth.getFullYear() + 12);
113
+ break;
114
+ }
115
+ pickerMonth = new Date(pickerMonth);
116
+ }
117
+ async function onSelectDayHandlerAsync(value_, dayDisabled) {
118
+ if (!dayDisabled) {
119
+ switch (selectMode) {
120
+ // Single selection
121
+ case "single":
122
+ onDateSelected?.(value_);
123
+ break;
124
+ // Multiple selection
125
+ case "multiple":
126
+ if (!selectDatesHover) {
127
+ let newSelectedDates = Array.from(selectedDates);
128
+ if (selectedDates.includes(value_)) {
129
+ newSelectedDates = newSelectedDates.filter(i => i !== value_);
130
+ }
131
+ else {
132
+ newSelectedDates.push(value_);
133
+ }
134
+ onDatesSelected?.(newSelectedDates);
135
+ }
136
+ else {
137
+ const range = selectDatesHover(value_);
138
+ const newSelectedDates = range.filter(day => disabledDateFunc != null ? !disabledDateFunc(day) : true);
139
+ onDatesSelected?.(newSelectedDates);
140
+ }
141
+ break;
142
+ // Range of dates
143
+ case "range":
144
+ const resetRange = (_rangeSelector.isValid() || _rangeSelector.isSingle()) && _rangeSelector.includes(value_);
145
+ // Reset the selection
146
+ if (resetRange) {
147
+ _rangeSelector.clear();
148
+ _rangeSelectorMouseOver.clear();
149
+ }
150
+ // End the selection
151
+ else if (_rangeSelector.start !== null && _rangeSelector.end === null) {
152
+ _rangeSelector.end = value_;
153
+ }
154
+ // Start and close a pre-selection
155
+ else if (selectDatesHover) {
156
+ const range = selectDatesHover(value_);
157
+ _rangeSelector.start = getSmallest(range);
158
+ _rangeSelector.end = getLargest(range);
159
+ }
160
+ // Start the selection
161
+ else {
162
+ _rangeSelector.start = value_;
163
+ _rangeSelector.end = null;
164
+ await onSelectDayMouseOverAsync(value_, false);
165
+ }
166
+ const newSelectedDates = _rangeSelector
167
+ .getAllDates()
168
+ .filter(day => disabledDateFunc != null ? !disabledDateFunc(day) : true);
169
+ onDatesSelected?.(newSelectedDates);
170
+ break;
171
+ }
172
+ }
173
+ }
174
+ async function onSelectDayMouseOverAsync(value, dayDisabled) {
175
+ if (dayDisabled ||
176
+ selectMode === "single" ||
177
+ (_rangeSelector.isSingle() && !selectDatesHover)) {
178
+ return;
179
+ }
180
+ if (!selectDatesHover) {
181
+ _rangeSelectorMouseOver.start = _rangeSelector.start ?? value;
182
+ _rangeSelectorMouseOver.end = value;
183
+ }
184
+ else {
185
+ const range = selectDatesHover(value);
186
+ _rangeSelectorMouseOver.start = getSmallest(range);
187
+ _rangeSelectorMouseOver.end = getLargest(range);
188
+ }
189
+ _selectedDatesMouseOver = !disabledDateFunc
190
+ ? _rangeSelectorMouseOver.getAllDates()
191
+ : _rangeSelectorMouseOver.getAllDates().filter(day => !disabledDateFunc(day));
192
+ }
193
+ async function onSelectMonthHandlerAsync(year, month, isReadOnly) {
194
+ if (isReadOnly) {
195
+ return;
196
+ }
197
+ const newValue = new Date(year, month, 1, 0, 0, 0, 0);
198
+ onDateSelected?.(newValue);
199
+ }
200
+ async function onSelectYearHandlerAsync(year, isReadOnly) {
201
+ if (isReadOnly) {
202
+ return;
203
+ }
204
+ const newValue = new Date(year, 0, 1, 0, 0, 0, 0);
205
+ onDateSelected?.(newValue);
206
+ }
207
+ function allDaysAreDisabled(start, end) {
208
+ if (!disabledDateFunc) {
209
+ return false;
210
+ }
211
+ for (let day = start; day <= end; day.setDate(day.getDate() + 1)) {
212
+ if (!disabledDateFunc(day)) {
213
+ return false;
214
+ }
215
+ }
216
+ return true;
217
+ }
218
+ function getDayProperties(day) {
219
+ return new CalendarDay(calendar, day);
220
+ }
221
+ function getMonthProperties(year, month) {
222
+ return new CalendarMonth(calendar, new Date(year, month));
223
+ }
224
+ function getYearProperties(year) {
225
+ return new CalendarYear(calendar, new Date(year, 0, 1));
226
+ }
227
+ function pickerMonthSelectAsync(month) {
228
+ pickerMonth = month ?? new Date();
229
+ _pickerView = "days";
230
+ }
231
+ function pickerYearSelectAsync(year) {
232
+ pickerMonth = year ?? new Date();
233
+ _pickerView = "days";
234
+ }
235
+ async function startNewAnimationAsync(position) {
236
+ if (!canBeAnimated) {
237
+ return;
238
+ }
239
+ _animationRunning = CalendarVerticalPosition.Unset;
240
+ await tick();
241
+ _animationRunning = position;
242
+ }
243
+ </script>
244
+
245
+ {#snippet arrowUp()}
246
+ <svg
247
+ width="24"
248
+ height="24"
249
+ viewBox="0 0 24 24"
250
+ fill="var(--neutral-fill-strong-focus)"
251
+ xmlns="http://www.w3.org/2000/svg"
252
+ >
253
+ <path d="M4.2 10.73a.75.75 0 001.1 1.04l5.95-6.25v14.73a.75.75 0 001.5 0V5.52l5.95 6.25a.75.75 0 001.1-1.04l-7.08-7.42a1 1 0 00-1.44 0L4.2 10.73z" />
254
+ </svg>
255
+ {/snippet}
256
+ {#snippet arrowDown()}
257
+ <svg
258
+ width="24"
259
+ height="24"
260
+ viewBox="0 0 24 24"
261
+ fill="var(--neutral-fill-strong-focus)"
262
+ xmlns="http://www.w3.org/2000/svg"
263
+ >
264
+ <path d="M19.8 13.27a.75.75 0 00-1.1-1.04l-5.95 6.25V3.75a.75.75 0 10-1.5 0v14.73L5.3 12.23a.75.75 0 10-1.1 1.04l7.08 7.42a1 1 0 001.44 0l7.07-7.42z" />
265
+ </svg>
266
+ {/snippet}
267
+
268
+ <div
269
+ {...restProps}
270
+ class="{restProps.class || ''}"
271
+ class:fluent-calendar={view === "days"}
272
+ class:fluent-month={view === "months"}
273
+ class:fluent-year={view === "years"}
274
+ >
275
+ {#if !_pickerView || _pickerView === "days"}
276
+ <div>
277
+ <!-- Title bar (label, previous and next buttons) -->
278
+ <div class="title" part="title" aria-label="{titles.label}">
279
+ <div
280
+ part="label" class={getAnimationClass('label')}
281
+ role="button" tabindex="0"
282
+ onclick={() => onTitleClicked(titles)}
283
+ onkeydown={() => onTitleClicked(titles)}
284
+ >
285
+ {titles.label}
286
+ </div>
287
+ <div part="move" class="change-period">
288
+ {#if titles.previousDisabled}
289
+ <div class="previous" disabled="true"></div>
290
+ {:else}
291
+ <div
292
+ class="previous" title="{titles.previousTitle}"
293
+ role="button" tabindex="0"
294
+ onclick={onPreviousButtonClicked}
295
+ onkeydown={onPreviousButtonClicked}
296
+ >
297
+ {@render arrowUp()}
298
+ </div>
299
+ {/if}
300
+ {#if titles.nextDisabled}
301
+ <div class="next" disabled="true"></div>
302
+ {:else}
303
+ <div
304
+ class="next" title="{titles.nextTitle}"
305
+ role="button" tabindex="0"
306
+ onclick={onNextButtonHandlerAsync}
307
+ onkeydown={onNextButtonHandlerAsync}
308
+ >
309
+ {@render arrowDown()}
310
+ </div>
311
+ {/if}
312
+ </div>
313
+ </div>
314
+
315
+ {#if view === "days"}
316
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
317
+ <div class="days" part="days" onmouseleave={ev => _selectedDatesMouseOver = []}>
318
+ <!-- Titles: Mon, Tue, ... -->
319
+ <div class="week-days" part="week-days">
320
+ {#each calendarExtended.getDayNames() as weekDay}
321
+ <div class="week-day" part="week-day" title={weekDay.name} abbr={weekDay.name}>
322
+ {weekDay.shorted}
323
+ </div>
324
+ {/each}
325
+ </div>
326
+
327
+ {#each {length: 5} as _, i}
328
+ <!-- A week of 7 days -->
329
+ <div class="week">
330
+ {#each calendarExtended.getDaysOfWeek(i) as day}
331
+ {@const dayProperties = getDayProperties(day)}
332
+
333
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
334
+ <!-- svelte-ignore a11y_mouse_events_have_key_events -->
335
+ <div
336
+ part="day"
337
+ class={getAnimationClass('day')}
338
+ role={dayProperties.isDisabled || dayProperties.isInactive ? null : 'button'}
339
+ tabindex={dayProperties.isDisabled || dayProperties.isInactive ? null : 0}
340
+ disabled={dayProperties.isDisabled}
341
+ inactive={dayProperties.isInactive}
342
+ today={dayProperties.isToday}
343
+ selected={dayProperties.isSelected}
344
+ multi-day={dayProperties.isMultiDaySelected}
345
+ multi-day-over={multipleSelection.inProgress && _selectedDatesMouseOver.includes(day)}
346
+ multi-start={multipleSelection.isMultiple && selectMode === "range" && multipleSelection.min === day}
347
+ multi-end={multipleSelection.isMultiple && selectMode === "range" && multipleSelection.max === day}
348
+ aria-label={dayProperties.title}
349
+ value={dayProperties.dayIdentifier}
350
+ onkeydown={ev => onSelectDayHandlerAsync(day, dayProperties.isDisabled || dayProperties.isInactive || readonly || false)}
351
+ onclick={ev => onSelectDayHandlerAsync(day, dayProperties.isDisabled || dayProperties.isInactive || readonly || false)}
352
+ onmouseover={ev => onSelectDayMouseOverAsync(day, dayProperties.isDisabled || dayProperties.isInactive || readonly || false)}
353
+ >
354
+ {#if daySnippet}
355
+ {@render daySnippet(dayProperties)}
356
+ {:else}
357
+ {dayProperties.dayNumber}
358
+ {/if}
359
+ </div>
360
+ {/each}
361
+ </div>
362
+ {/each}
363
+ </div>
364
+ {:else if view === "months"}
365
+ <div class="months" part="months">
366
+ {#each calendarExtended.getMonthNames() as month}
367
+ {@const monthProperties = getMonthProperties(year, month.index)}
368
+
369
+ <div
370
+ class={getAnimationClass('month')}
371
+ selected={monthProperties.isSelected}
372
+ readonly={monthProperties.isReadOnly}
373
+ disabled={monthProperties.isDisabled}
374
+ aria-label={monthProperties.title}
375
+ title={monthProperties.title}
376
+ value={monthProperties.monthIdentifier}
377
+ role="button"
378
+ tabindex={monthProperties.isDisabled || monthProperties.isReadOnly ? null : 0}
379
+ onkeydown={ev => onSelectMonthHandlerAsync(year, month.index, monthProperties.isReadOnly)}
380
+ onclick={ev => onSelectMonthHandlerAsync(year, month.index, monthProperties.isReadOnly)}
381
+ >
382
+ {month.abbreviated}
383
+ </div>
384
+ {/each}
385
+ </div>
386
+ {:else if view === "years"}
387
+ <div class="years" part="years">
388
+ {#each calendarExtended.getYearsRange() as year}
389
+ {@const yearProperties = getYearProperties(year.year)}
390
+
391
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
392
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
393
+ <div
394
+ class={getAnimationClass('year')}
395
+ selected={yearProperties.isSelected}
396
+ readonly={yearProperties.isReadOnly}
397
+ disabled={yearProperties.isDisabled}
398
+ aria-label={year.year}
399
+ title={year.year}
400
+ value={yearProperties.yearIdentifier}
401
+ tabindex={yearProperties.isDisabled || yearProperties.isReadOnly ? null : 0}
402
+ onkeydown={ev => onSelectYearHandlerAsync(year.year, yearProperties.isReadOnly)}
403
+ onclick={ev => onSelectYearHandlerAsync(year.year, yearProperties.isReadOnly)}
404
+ >
405
+ {year.year}
406
+ </div>
407
+ {/each}
408
+ </div>
409
+ {/if}
410
+ </div>
411
+ {/if}
412
+
413
+ {#if _pickerView === "months"}
414
+ <Calendar
415
+ View="months"
416
+ Value={pickerMonth}
417
+ ValueChanged={pickerMonthSelectAsync}
418
+ CheckIfSelectedValueHasChanged={false}
419
+ {readonly}
420
+ {culture}
421
+ disabledSelectable={disabledCheckAllDaysOfMonthYear}
422
+ {animatePeriodChanges}
423
+ disabledCheckAllDaysOfMonthYear={disabledCheckAllDaysOfMonthYear}
424
+ {disabledDateFunc}
425
+ />
426
+ {/if}
427
+
428
+ {#if _pickerView === "years"}
429
+ <Calendar
430
+ view="years"
431
+ value={pickerMonth}
432
+ valueChanged={pickerYearSelectAsync}
433
+ checkIfSelectedValueHasChanged={false}
434
+ {readonly}
435
+ {culture}
436
+ disabledSelectable={disabledSelectable}
437
+ {animatePeriodChanges}
438
+ disabledCheckAllDaysOfMonthYear={disabledCheckAllDaysOfMonthYear}
439
+ {disabledDateFunc}
440
+ />
441
+ {/if}
442
+ </div>
@@ -0,0 +1,27 @@
1
+ import Calendar from "./Calendar.svelte";
2
+ import type { SlotType } from "../types/index.js";
3
+ import type { CalendarSelectMode, CalendarView } from "../fluent-ui/calendar/fluent-calendar.js";
4
+ import type DayFormat from "../fluent-ui/calendar/day-format.js";
5
+ type Props = {
6
+ value?: Date;
7
+ selectedDates?: Date[];
8
+ pickerMonth?: Date;
9
+ culture?: Intl.Locale;
10
+ view?: CalendarView;
11
+ selectMode?: CalendarSelectMode;
12
+ checkIfSelectedValueHasChanged?: boolean;
13
+ disabledDateFunc?: (date: Date) => boolean;
14
+ disabledCheckAllDaysOfMonthYear?: boolean;
15
+ animatePeriodChanges?: boolean;
16
+ disabledSelectable?: boolean;
17
+ dayFormat?: typeof DayFormat["TwoDigit"] | null;
18
+ readonly?: boolean;
19
+ selectDatesHover?: ((date: Date) => Date[]) | null | undefined;
20
+ onDatesSelected?: (values: Date[]) => void;
21
+ onDateSelected?: (value: Date) => void;
22
+ day?: SlotType;
23
+ [prop: string]: any;
24
+ };
25
+ declare const Calendar: import("svelte").Component<Props, {}, "pickerMonth">;
26
+ type Calendar = ReturnType<typeof Calendar>;
27
+ export default Calendar;
@@ -0,0 +1,14 @@
1
+ <script lang="ts">import { fluentCard, provideFluentDesignSystem } from "@fluentui/web-components";
2
+ import { classList, styleList } from "../helpers/html.js";
3
+ provideFluentDesignSystem().register(fluentCard());
4
+ let { width = undefined, height = undefined, areaRestricted = undefined, class: classParam = undefined, style: styleParam = undefined, minimalStyle = undefined, children = undefined, ...restProps } = $props();
5
+ const styles = $derived(styleList(styleParam, width && `--card-width: ${width}${typeof width === "number" ? "px" : ""}`, height && `--card-height: ${height}${typeof height === "number" ? "px" : ""}`));
6
+ const classes = $derived(classList(classParam, minimalStyle && "fluent-card-minimal-style"));
7
+ $inspect("class and style", { styles, classes });
8
+ </script>
9
+
10
+ <fluent-card
11
+ {...restProps} class={classes} class:area-restricted={areaRestricted} style={styles}
12
+ >
13
+ {@render children?.()}
14
+ </fluent-card>
@@ -0,0 +1,14 @@
1
+ import type { SlotType } from "../types/index.js";
2
+ type Props = {
3
+ width?: string | number;
4
+ height?: string | number;
5
+ areaRestricted?: boolean;
6
+ class?: string;
7
+ style?: string;
8
+ minimalStyle?: boolean;
9
+ children?: SlotType;
10
+ [prop: string]: any;
11
+ };
12
+ declare const Card: import("svelte").Component<Props, {}, "">;
13
+ type Card = ReturnType<typeof Card>;
14
+ export default Card;
@@ -0,0 +1,38 @@
1
+ <script lang="ts">import { fluentCheckbox, provideFluentDesignSystem } from "@fluentui/web-components";
2
+ provideFluentDesignSystem().register(fluentCheckbox());
3
+ let { checked = $bindable(), withIntermediate = undefined, disabled = undefined, readonly = undefined, children = undefined, onClick = undefined } = $props();
4
+ let intermediate = $state(false);
5
+ function handleOnClick(ev) {
6
+ ev.preventDefault();
7
+ ev.stopImmediatePropagation();
8
+ if (readonly || disabled) {
9
+ return;
10
+ }
11
+ const previousValue = $state.snapshot(checked);
12
+ // intermediate state not working
13
+ // const newChecked = (ev as any).target.checked
14
+ // if (withIntermediate) {
15
+ // if (previousValue && !intermediate) {
16
+ // console.log("setting intermediate")
17
+ // intermediate = true
18
+ // } else {
19
+ // console.log("regular update checked")
20
+ // checked = newChecked
21
+ // intermediate = false
22
+ // }
23
+ // } else {
24
+ // checked = newChecked
25
+ // }
26
+ checked = ev.target.checked;
27
+ onClick?.(ev, previousValue);
28
+ }
29
+ </script>
30
+
31
+ <fluent-checkbox
32
+ {checked}
33
+ {readonly}
34
+ {disabled}
35
+ onclick={handleOnClick}
36
+ >
37
+ {@render children?.()}
38
+ </fluent-checkbox>
@@ -0,0 +1,17 @@
1
+ type Props = {
2
+ checked: boolean | null;
3
+ withIntermediate?: boolean;
4
+ autofocus?: boolean;
5
+ children?: any;
6
+ disabled?: boolean;
7
+ readonly?: boolean;
8
+ required?: boolean;
9
+ checkValidity?: () => boolean;
10
+ reportValidity?: () => boolean;
11
+ setCustomValidity?: (message: string) => any;
12
+ setValidity?: (flags: any, message: any, anchor: any) => void;
13
+ onClick?: (ev: PointerEvent, previousValue: boolean | null) => void;
14
+ };
15
+ declare const Checkbox: import("svelte").Component<Props, {}, "checked">;
16
+ type Checkbox = ReturnType<typeof Checkbox>;
17
+ export default Checkbox;
@@ -0,0 +1,91 @@
1
+ <script lang="ts">import { provideFluentDesignSystem, fluentCombobox, } from "@fluentui/web-components";
2
+ import Option from "./Option.svelte";
3
+ import { setContext, untrack } from "svelte";
4
+ import { createSelectedOptions } from "../data/selected-options.svelte.js";
5
+ provideFluentDesignSystem().register(fluentCombobox());
6
+ let { id, value = $bindable(), options = undefined, autocomplete = undefined, open = undefined, currentValue = undefined, placeholder = undefined, position = undefined, disabled = undefined, readonly = undefined, appearance = undefined, required = undefined, autofocus = undefined, name = undefined, children = undefined, ...restProps } = $props();
7
+ const selectedOptions = createSelectedOptions(value);
8
+ setContext("selected-options", selectedOptions);
9
+ let element = undefined;
10
+ // $inspect(id, "combobox selected options", selectedOptions.value)
11
+ // update value: V
12
+ $effect(() => {
13
+ // console.log(id, "combobox V", {
14
+ // value: untrack(() => $state.snapshot(value)),
15
+ // selectedOptions: untrack(() => $state.snapshot(selectedOptions.value)),
16
+ // equal: isValueEqualToContext(untrack(() => value), untrack(() => selectedOptions.value))
17
+ // })
18
+ if (isValueEqualToContext(value, untrack(() => selectedOptions.value))) {
19
+ // console.log(id, "combobox V equal", {value, selectedOptions: untrack(() => selectedOptions.value)})
20
+ return;
21
+ }
22
+ // reactivity-loop seems to be handled well by Svelte alone...
23
+ selectedOptions.value = untrack(() => selectedOptions.toContextValue)($state.snapshot(value));
24
+ // this is used to update this combobox's visible selected value's text inside the input
25
+ if (element) {
26
+ const selectedOptionElement = element.options.find((x) => x.value === value?.[0]);
27
+ const selectedIndex = element.options.findIndex((x) => x.value === value?.[0]);
28
+ if ((element.value !== value?.[0] || element.selectedIndex !== selectedIndex) &&
29
+ selectedOptionElement) {
30
+ element.value =
31
+ selectedOptionElement.dataset.optionLabel ||
32
+ selectedOptionElement.innerText.trim();
33
+ element.selectedIndex = selectedIndex;
34
+ }
35
+ }
36
+ });
37
+ // update value: ^
38
+ $effect(() => {
39
+ // console.log(id, "combobox ^", {
40
+ // value: untrack(() => $state.snapshot(value)),
41
+ // selectedOptions: $state.snapshot(untrack(() => selectedOptions.value)),
42
+ // equal: isValueEqualToContext(untrack(() => value), untrack(() => selectedOptions.value))
43
+ // })
44
+ if (isValueEqualToContext(untrack(() => value), selectedOptions.value)) {
45
+ // console.log(id,
46
+ // "combobox ^ equal",
47
+ // {value: untrack(() => value), selectedOptions: $state.snapshot(selectedOptions.value)}
48
+ // )
49
+ return;
50
+ }
51
+ if (untrack(() => readonly || disabled)) {
52
+ selectedOptions.set(untrack(() => $state.snapshot(value)));
53
+ return;
54
+ }
55
+ // console.log(id, "setting value in effect", $selectedValue)
56
+ // reactivity-loop seems to be handled well by Svelte alone...
57
+ value = $state.snapshot(selectedOptions.value);
58
+ });
59
+ function isValueEqualToContext(value, ctxValue) {
60
+ return (!value && !ctxValue)
61
+ || (value instanceof Array
62
+ ? value[0]
63
+ : value) === ctxValue?.[0];
64
+ }
65
+ </script>
66
+
67
+ <fluent-combobox
68
+ bind:this={element}
69
+ {autocomplete}
70
+ {open}
71
+ {currentValue}
72
+ {placeholder}
73
+ {position}
74
+ {disabled}
75
+ {readonly}
76
+ {appearance}
77
+ {required}
78
+ {autofocus}
79
+ {name}
80
+ {...restProps}
81
+ >
82
+ {#if children}
83
+ {@render children()}
84
+ {:else}
85
+ {#each options ?? [] as item (item.value)}
86
+ <Option value={item.value} label={item.label} disabled={item.disabled}>
87
+ {item.label}
88
+ </Option>
89
+ {/each}
90
+ {/if}
91
+ </fluent-combobox>
@@ -0,0 +1,21 @@
1
+ import type { OptionItem, SelectedValue, SlotType } from "../types/index.js";
2
+ type Props = {
3
+ id: string;
4
+ value: SelectedValue;
5
+ options?: OptionItem[];
6
+ children?: SlotType;
7
+ autocomplete?: any;
8
+ open?: boolean;
9
+ currentValue?: any;
10
+ placeholder?: string;
11
+ position?: string;
12
+ disabled?: boolean;
13
+ readonly?: boolean;
14
+ appearance?: string;
15
+ required?: boolean;
16
+ autofocus?: any;
17
+ name?: string;
18
+ };
19
+ declare const Combobox: import("svelte").Component<Props, {}, "value">;
20
+ type Combobox = ReturnType<typeof Combobox>;
21
+ export default Combobox;
@@ -0,0 +1,7 @@
1
+ <script lang="ts">let { children = undefined } = $props();
2
+ export {};
3
+ </script>
4
+
5
+ <div class="content-region">
6
+ {@render children?.()}
7
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { SlotType } from "../types/index.js";
2
+ type Props = {
3
+ children?: SlotType;
4
+ };
5
+ declare const ContentRegion: import("svelte").Component<Props, {}, "">;
6
+ type ContentRegion = ReturnType<typeof ContentRegion>;
7
+ export default ContentRegion;