noph-ui 0.52.0 → 0.53.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 (103) hide show
  1. package/dist/animation.d.ts +1 -13
  2. package/dist/animation.js +18 -13
  3. package/dist/button/Button.svelte +2 -14
  4. package/dist/button/IconButton.svelte +5 -18
  5. package/dist/button/SegmentedButton.svelte +8 -11
  6. package/dist/card/Card.svelte +3 -19
  7. package/dist/card/types.d.ts +12 -2
  8. package/dist/carousel/Carousel.svelte +77 -14
  9. package/dist/carousel/CarouselItem.svelte +26 -14
  10. package/dist/carousel/carouselMorph.js +1 -1
  11. package/dist/carousel/carouselStrategy.js +25 -27
  12. package/dist/checkbox/Checkbox.svelte +1 -8
  13. package/dist/chip/FilterChip.svelte +1 -13
  14. package/dist/date-picker/Calendar.svelte +31 -30
  15. package/dist/date-picker/Calendar.svelte.d.ts +2 -0
  16. package/dist/date-picker/CalendarHeader.svelte +84 -62
  17. package/dist/date-picker/CalendarHeader.svelte.d.ts +3 -0
  18. package/dist/date-picker/DatePickerDialog.svelte +134 -75
  19. package/dist/date-picker/DatePickerDialog.svelte.d.ts +4 -3
  20. package/dist/date-picker/DateRangePicker.svelte +226 -78
  21. package/dist/date-picker/DateRangePicker.svelte.d.ts +3 -3
  22. package/dist/date-picker/DockedDatePicker.svelte +76 -464
  23. package/dist/date-picker/DockedDatePicker.svelte.d.ts +2 -2
  24. package/dist/date-picker/DockedDateTimePicker.svelte +128 -525
  25. package/dist/date-picker/DockedDateTimePicker.svelte.d.ts +2 -2
  26. package/dist/date-picker/DockedPickerField.svelte +221 -0
  27. package/dist/date-picker/DockedPickerField.svelte.d.ts +9 -0
  28. package/dist/date-picker/MonthPanel.svelte +291 -0
  29. package/dist/date-picker/MonthPanel.svelte.d.ts +12 -0
  30. package/dist/date-picker/SelectionList.svelte +7 -6
  31. package/dist/date-picker/SelectionList.svelte.d.ts +1 -0
  32. package/dist/date-picker/TimeColumn.svelte +2 -6
  33. package/dist/date-picker/TimeColumn.svelte.d.ts +1 -0
  34. package/dist/date-picker/YearGrid.svelte +2 -11
  35. package/dist/date-picker/YearGrid.svelte.d.ts +1 -0
  36. package/dist/date-picker/dateUtils.d.ts +4 -0
  37. package/dist/date-picker/dateUtils.js +15 -88
  38. package/dist/date-picker/exitVisibility.svelte.js +13 -6
  39. package/dist/date-picker/formatters.d.ts +16 -0
  40. package/dist/date-picker/formatters.js +48 -15
  41. package/dist/date-picker/internalTypes.d.ts +59 -1
  42. package/dist/date-picker/shortcuts.d.ts +11 -0
  43. package/dist/date-picker/shortcuts.js +40 -0
  44. package/dist/date-picker/timeUtils.d.ts +8 -3
  45. package/dist/date-picker/timeUtils.js +33 -51
  46. package/dist/date-picker/types.d.ts +22 -0
  47. package/dist/icons/Icon.svelte +1 -4
  48. package/dist/internal/exit.css +0 -14
  49. package/dist/internal/field.css +337 -0
  50. package/dist/internal/focus-ring.css +23 -8
  51. package/dist/internal/pop-in.css +19 -0
  52. package/dist/internal/visually-hidden.css +11 -0
  53. package/dist/list/Item.svelte +32 -18
  54. package/dist/menu/Menu.svelte +6 -25
  55. package/dist/menu/Menu.svelte.d.ts +1 -0
  56. package/dist/navigation-bar/NavigationBarItem.svelte +6 -30
  57. package/dist/navigation-drawer/NavigationDrawerItem.svelte +4 -11
  58. package/dist/navigation-rail/NavigationRailItem.svelte +2 -13
  59. package/dist/press.svelte.d.ts +0 -1
  60. package/dist/press.svelte.js +0 -11
  61. package/dist/progress/CircularProgress.svelte +26 -81
  62. package/dist/progress/CircularProgress.svelte.d.ts +1 -0
  63. package/dist/progress/LinearProgress.svelte +19 -151
  64. package/dist/progress/LinearProgress.svelte.d.ts +1 -0
  65. package/dist/progress/four-color.css +34 -0
  66. package/dist/radio/Radio.svelte +6 -9
  67. package/dist/ripple/Ripple.svelte +8 -16
  68. package/dist/search/Search.svelte +2 -9
  69. package/dist/search/Search.svelte.d.ts +1 -0
  70. package/dist/select/Check.svelte +8 -31
  71. package/dist/select/Check.svelte.d.ts +1 -1
  72. package/dist/select/NativeSelect.svelte +97 -366
  73. package/dist/select/NativeSelect.svelte.d.ts +1 -0
  74. package/dist/select/Option.svelte +1 -9
  75. package/dist/select/Select.svelte +139 -746
  76. package/dist/select/Select.svelte.d.ts +1 -0
  77. package/dist/select/VirtualList.svelte +0 -1
  78. package/dist/sheet/Sheet.svelte +11 -22
  79. package/dist/slider/Slider.svelte +13 -37
  80. package/dist/slider/Slider.svelte.d.ts +1 -0
  81. package/dist/switch/Switch.svelte +2 -8
  82. package/dist/tabs/Tab.svelte +2 -4
  83. package/dist/text-field/TextField.svelte +81 -609
  84. package/dist/text-field/TextField.svelte.d.ts +1 -0
  85. package/dist/time-picker/ClockDial.svelte +8 -25
  86. package/dist/time-picker/ClockDial.svelte.d.ts +2 -0
  87. package/dist/time-picker/DockedTimePicker.svelte +102 -244
  88. package/dist/time-picker/DockedTimePicker.svelte.d.ts +2 -2
  89. package/dist/time-picker/PeriodSelector.svelte +8 -7
  90. package/dist/time-picker/PeriodSelector.svelte.d.ts +1 -0
  91. package/dist/time-picker/TimeInputs.svelte +13 -2
  92. package/dist/time-picker/TimePickerDialog.svelte +32 -26
  93. package/dist/time-picker/TimePickerDialog.svelte.d.ts +2 -2
  94. package/dist/time-picker/TimePickerPanel.svelte +26 -4
  95. package/dist/time-picker/TimeSelectors.svelte +4 -9
  96. package/dist/time-picker/TimeSelectors.svelte.d.ts +1 -0
  97. package/dist/time-picker/internalTypes.d.ts +2 -0
  98. package/dist/time-picker/timePickerState.svelte.js +3 -9
  99. package/dist/tooltip/RichTooltip.svelte +2 -23
  100. package/dist/tooltip/RichTooltip.svelte.d.ts +1 -0
  101. package/dist/tooltip/Tooltip.svelte +2 -24
  102. package/dist/tooltip/Tooltip.svelte.d.ts +1 -0
  103. package/package.json +12 -12
@@ -1,30 +1,15 @@
1
1
  <script lang="ts">
2
- import { exitVisibility } from './exitVisibility.svelte.js'
3
2
  import Button from '../button/Button.svelte'
4
- import IconButton from '../button/IconButton.svelte'
5
- import Divider from '../divider/Divider.svelte'
6
3
  import CalendarToday from '../icons/CalendarToday.svelte'
7
- import Menu from '../menu/Menu.svelte'
8
- import { formReset } from '../form-reset.js'
9
- import { syncOpenEffect } from '../popover.svelte.js'
10
- import TextField from '../text-field/TextField.svelte'
11
4
  import { onMount, tick } from 'svelte'
12
- import Calendar from './Calendar.svelte'
13
- import CalendarHeader from './CalendarHeader.svelte'
14
- import SelectionList from './SelectionList.svelte'
5
+ import DockedPickerField from './DockedPickerField.svelte'
6
+ import MonthPanel from './MonthPanel.svelte'
15
7
  import {
16
- addMonths,
17
- clampMonthInYear,
18
- compareDays,
19
8
  DEFAULT_YEAR_RANGE,
20
9
  formatDate,
21
10
  getDatePattern,
22
11
  getFirstDayOfWeek,
23
- getMonthNames,
24
- getWeekRowCount,
25
- isMonthWithin,
26
12
  isWithin,
27
- isYearWithin,
28
13
  parseDateInput,
29
14
  parseISODate,
30
15
  startOfMonth,
@@ -38,8 +23,6 @@
38
23
  defaultValue,
39
24
  // eslint-disable-next-line @typescript-eslint/no-unused-vars -- pulled out of the rest props on purpose
40
25
  type,
41
- 'aria-invalid': ariaInvalid,
42
- style,
43
26
  displayMonth = $bindable(),
44
27
  open = $bindable(false),
45
28
  element = $bindable(),
@@ -51,15 +34,7 @@
51
34
  isDateEnabled,
52
35
  adjacentMonthDays = false,
53
36
  label = 'Date',
54
- supportingText,
55
- issues,
56
37
  variant = 'outlined',
57
- name,
58
- form,
59
- required,
60
- disabled,
61
- readonly,
62
- noAsterisk,
63
38
  autocomplete = 'off',
64
39
  cancelLabel = 'Cancel',
65
40
  confirmLabel = 'OK',
@@ -72,28 +47,15 @@
72
47
  openCalendarLabel = 'Show date picker',
73
48
  invalidDateMessage = 'Enter a valid date.',
74
49
  selectedDateLabel = 'selected',
75
- onchange,
76
- oninput,
77
- onblur,
50
+ shortcutLabels,
78
51
  ...attributes
79
52
  }: DockedDatePickerProps = $props()
80
53
 
81
54
  const ISO_PATTERN = 'YYYY-MM-DD'
82
55
 
83
- const uid = $props.id()
84
-
85
- let menuElement = $state<HTMLDivElement>()
86
- // Keeps the content while the menu animates out, so it fades as a whole, not as an empty box.
87
- const exit = exitVisibility()
88
- let mode = $state<'days' | 'months' | 'years'>('days')
89
- let listMode = $state<'months' | 'years' | undefined>(undefined)
56
+ let field = $state<DockedPickerField>()
57
+ let panel = $state<MonthPanel>()
90
58
  let pending = $state<ISODate | undefined>(undefined)
91
- let focusedDay = $state<Date | undefined>(undefined)
92
- let inputElement = $state<HTMLInputElement | HTMLTextAreaElement>()
93
- let valueInput = $state<HTMLInputElement>()
94
-
95
- let typed = $state.raw<{ source: ISODate | null | undefined; text: string } | undefined>()
96
- let invalidText = $state<string | undefined>()
97
59
  let monthBeforeOpen: ISODate | undefined
98
60
 
99
61
  let current = $derived<ISODate | undefined>(
@@ -101,7 +63,6 @@
101
63
  )
102
64
 
103
65
  let todayValue = $derived(getToday())
104
- let week = $derived(firstDayOfWeek ?? getFirstDayOfWeek(locale))
105
66
  let minDate = $derived(parseISODate(min))
106
67
  let maxDate = $derived(parseISODate(max))
107
68
  let committed = $derived(parseISODate(current))
@@ -113,374 +74,100 @@
113
74
  })
114
75
 
115
76
  let localeKnown = $derived(locale !== undefined || mounted)
116
- let pattern = $derived(localeKnown ? getDatePattern(locale) : ISO_PATTERN)
117
77
  let monthDate = $derived(
118
78
  parseISODate(displayMonth) ?? startOfMonth(pendingDate ?? committed ?? todayValue),
119
79
  )
120
- let monthNames = $derived(getMonthNames(locale, 'long'))
121
- let shortMonthNames = $derived(getMonthNames(locale, 'short'))
122
- let rowCount = $derived(getWeekRowCount(monthDate, week))
123
-
124
- const setMode = (next: 'days' | 'months' | 'years') => {
125
- if (mode === next) return
126
- mode = next
127
- if (next !== 'days') listMode = next
128
- }
129
-
130
- const leaveList = async () => {
131
- setMode('days')
132
- await tick()
133
- focusCalendar()
134
- }
135
-
136
- const formatValue = () => {
137
- if (!committed) return ''
138
- return localeKnown ? formatDate(committed, locale) : toISODate(committed)
139
- }
140
-
141
- let text = $derived(typed && typed.source === current ? typed.text : formatValue())
142
-
143
- let inputInvalid = $derived(invalidText !== undefined && invalidText === text)
144
-
145
- let monthOptions = $derived(
146
- monthNames.map((monthName, index) => ({
147
- value: index,
148
- label: monthName,
149
- disabled: !isMonthWithin(monthDate.getFullYear(), index, minDate, maxDate),
150
- })),
151
- )
152
-
153
- let yearOptions = $derived(
154
- Array.from({ length: yearRange[1] - yearRange[0] + 1 }, (_, index) => {
155
- const year = yearRange[0] + index
156
- return {
157
- value: year,
158
- label: `${year}`,
159
- disabled: !isYearWithin(year, minDate, maxDate),
160
- }
161
- }),
162
- )
163
-
164
- let canPreviousMonth = $derived(
165
- !minDate ||
166
- compareDays(new Date(monthDate.getFullYear(), monthDate.getMonth(), 0), minDate) >= 0,
167
- )
168
- let canNextMonth = $derived(
169
- !maxDate ||
170
- compareDays(new Date(monthDate.getFullYear(), monthDate.getMonth() + 1, 1), maxDate) <= 0,
171
- )
172
- let canPreviousYear = $derived(
173
- monthDate.getFullYear() > yearRange[0] &&
174
- (!minDate || compareDays(addMonths(monthDate, -12), startOfMonth(minDate)) >= 0),
175
- )
176
- let canNextYear = $derived(
177
- monthDate.getFullYear() < yearRange[1] &&
178
- (!maxDate || compareDays(addMonths(monthDate, 12), startOfMonth(maxDate)) <= 0),
179
- )
180
80
 
181
81
  const setMonth = (date: Date) => {
182
82
  displayMonth = toISODate(startOfMonth(date))
183
83
  }
184
84
 
185
- const commit = (next: ISODate | undefined) => {
186
- if (current === next) return
187
- value = next
188
- onchange?.(next)
189
- }
190
-
191
- const restoreDefault = () => {
192
- const next = typeof defaultValue === 'string' ? defaultValue : undefined
193
- if (valueInput) valueInput.value = next ?? ''
194
- queueMicrotask(() => {
195
- typed = undefined
196
- invalidText = undefined
197
- pending = undefined
198
- value = next
199
- text = formatValue()
200
- })
201
- }
202
-
203
- const isShowing = () => !!menuElement?.matches(':popover-open')
204
-
205
- const openPicker = () => {
206
- if (isShowing()) return
207
- if (disabled || readonly) {
208
- open = false
209
- return
210
- }
211
- menuElement?.showPopover()
212
- }
213
-
214
- const focusCalendarWhenReady = async () => {
215
- await tick()
216
- focusCalendar()
217
- }
218
-
219
- export const show = () => openPicker()
220
-
221
- export const close = () => {
222
- if (isShowing()) menuElement?.hidePopover()
223
- }
224
-
225
- syncOpenEffect(
226
- () => menuElement,
227
- () => open,
228
- show,
229
- close,
230
- )
231
-
232
- const focusCalendar = () => {
233
- menuElement?.querySelector<HTMLElement>('.np-calendar-day[tabindex="0"]')?.focus()
234
- }
235
-
236
- const closePicker = (restoreFocus = true) => {
237
- menuElement?.hidePopover()
238
- if (restoreFocus) {
239
- element?.querySelector<HTMLElement>('input')?.focus()
240
- }
241
- }
242
-
243
- const selectDay = (date: Date) => {
244
- pending = toISODate(date)
245
- setMonth(date)
246
- focusedDay = date
247
- }
248
-
249
- const confirm = () => {
250
- typed = undefined
251
- invalidText = undefined
252
- commit(pending)
253
- closePicker()
254
- }
255
-
256
- const usableDate = (typed: string) => {
257
- const parsed = parseDateInput(typed, locale)
258
- if (!parsed) return undefined
259
- if (!isWithin(parsed, minDate, maxDate)) return undefined
260
- return (isDateEnabled?.(parsed) ?? true) ? parsed : undefined
261
- }
262
-
263
- const handleInput = (event: Event) => {
264
- const next = (event.currentTarget as HTMLInputElement).value
265
- const parsed = usableDate(next)
266
- commit(parsed ? toISODate(parsed) : undefined)
267
- if (parsed) setMonth(parsed)
268
- typed = { source: current, text: next }
269
- invalidText = undefined
270
- }
271
-
272
- const handleBlur = () => {
273
- if (!text.trim()) {
274
- invalidText = undefined
275
- return
276
- }
277
- const parsed = usableDate(text)
278
- invalidText = parsed ? undefined : text
279
- if (parsed) typed = undefined
85
+ const usableDate = (text: string) => {
86
+ const parsed = parseDateInput(text, locale)
87
+ if (!parsed || !isWithin(parsed, minDate, maxDate)) return undefined
88
+ return (isDateEnabled?.(parsed) ?? true) ? toISODate(parsed) : undefined
280
89
  }
281
90
 
282
- $effect(() => {
283
- const input = inputElement
284
- if (!input) return
285
- const unusable = text.trim() !== '' && !usableDate(text)
286
- input.setCustomValidity(unusable ? invalidDateMessage : '')
287
- })
288
-
289
- const chooseMonth = (month: number) => {
290
- setMonth(new Date(monthDate.getFullYear(), month, 1))
291
- leaveList()
292
- }
293
-
294
- const chooseYear = (year: number) => {
295
- setMonth(new Date(year, clampMonthInYear(year, monthDate.getMonth(), minDate, maxDate), 1))
296
- leaveList()
297
- }
91
+ export const show = () => field?.show()
92
+ export const close = () => field?.close()
298
93
  </script>
299
94
 
300
- <TextField
95
+ <DockedPickerField
301
96
  {...attributes}
302
- class={['np-docked-date-picker', attributes.class]}
303
- style={`anchor-name:--${uid};${style ?? ''}`}
97
+ bind:this={field}
98
+ kind="date-picker"
99
+ bind:value
100
+ bind:open
101
+ bind:element
102
+ {current}
103
+ resetValue={typeof defaultValue === 'string' ? defaultValue : undefined}
304
104
  {label}
305
105
  {variant}
306
- {issues}
307
- {disabled}
308
- {readonly}
309
- {required}
310
- {noAsterisk}
311
106
  {autocomplete}
312
- supportingText={supportingText ?? pattern}
313
- bind:value={text}
314
- bind:element
315
- bind:inputElement
316
- aria-invalid={inputInvalid || issues?.length || ariaInvalid === true || ariaInvalid === 'true'
317
- ? 'true'
318
- : undefined}
319
- oninput={(event) => {
320
- handleInput(event)
321
- oninput?.(event)
107
+ pattern={localeKnown ? getDatePattern(locale) : ISO_PATTERN}
108
+ openLabel={openCalendarLabel}
109
+ invalidMessage={invalidDateMessage}
110
+ format={() =>
111
+ committed ? (localeKnown ? formatDate(committed, locale) : toISODate(committed)) : ''}
112
+ parse={usableDate}
113
+ ontyped={(date) => setMonth(parseISODate(date)!)}
114
+ onrestore={() => (pending = undefined)}
115
+ onmenukeydown={(event) => panel?.handleKeydown(event)}
116
+ onopen={async () => {
117
+ monthBeforeOpen = displayMonth
118
+ pending = current
119
+ await tick()
120
+ panel?.focus()
322
121
  }}
323
- onblur={(event) => {
324
- handleBlur()
325
- onblur?.(event)
122
+ onclosed={() => {
123
+ panel?.reset()
124
+ displayMonth = monthBeforeOpen
326
125
  }}
327
126
  >
328
- {#snippet end()}
329
- <IconButton
330
- type="button"
331
- aria-label={openCalendarLabel}
332
- aria-expanded={open}
333
- aria-haspopup="dialog"
334
- aria-controls={open ? `${uid}-calendar` : undefined}
335
- {disabled}
336
- onclick={() => {
337
- if (open) closePicker()
338
- else openPicker()
339
- }}
340
- >
341
- <CalendarToday />
342
- </IconButton>
127
+ {#snippet icon()}
128
+ <CalendarToday />
343
129
  {/snippet}
344
- </TextField>
345
- <input
346
- bind:this={valueInput}
347
- {@attach formReset(restoreDefault)}
348
- class="np-docked-date-picker-value"
349
- type="hidden"
350
- value={current ?? ''}
351
- {name}
352
- {form}
353
- {disabled}
354
- />
355
-
356
- <Menu
357
- id="{uid}-calendar"
358
- role="dialog"
359
- aria-label={label}
360
- aria-modal="false"
361
- class="np-docked-date-picker-menu"
362
- style={`position-anchor:--${uid};`}
363
- --np-menu-justify-self="none"
364
- --np-menu-position-area="bottom span-right"
365
- --np-menu-over-anchor-position-area="span-all span-right"
366
- --np-menu-margin="0"
367
- --np-menu-container-color="var(--np-docked-date-picker-container-color, var(--np-color-surface-container-high))"
368
- --np-menu-container-shape="var(--np-docked-date-picker-container-shape, var(--np-shape-corner-large))"
369
- anchor={element}
370
- bind:element={menuElement}
371
- bind:open
372
- ontoggle={({ newState }) => {
373
- if (newState === 'open') {
374
- exit.show()
375
- monthBeforeOpen = displayMonth
376
- pending = current
377
- focusCalendarWhenReady()
378
- }
379
- if (newState === 'closed') {
380
- // Reset once the menu is gone, not while it still shows.
381
- exit.scheduleExit(menuElement, () => {
382
- setMode('days')
383
- listMode = undefined
384
- focusedDay = undefined
385
- displayMonth = monthBeforeOpen
386
- })
387
- }
388
- }}
389
- >
390
- {#if open || exit.visible}
391
- <div class="np-docked-date-picker-container" style:--np-calendar-rows={rowCount}>
392
- <CalendarHeader
393
- {mode}
394
- monthLabel={shortMonthNames[monthDate.getMonth()]}
395
- yearLabel={`${monthDate.getFullYear()}`}
396
- {canPreviousMonth}
397
- {canNextMonth}
398
- {canPreviousYear}
399
- {canNextYear}
400
- {previousMonthLabel}
401
- {nextMonthLabel}
402
- {previousYearLabel}
403
- {nextYearLabel}
404
- {selectMonthLabel}
405
- {selectYearLabel}
406
- monthListId="{uid}-months"
407
- yearListId="{uid}-years"
408
- onpreviousmonth={() => setMonth(addMonths(monthDate, -1))}
409
- onnextmonth={() => setMonth(addMonths(monthDate, 1))}
410
- onpreviousyear={() => setMonth(addMonths(monthDate, -12))}
411
- onnextyear={() => setMonth(addMonths(monthDate, 12))}
412
- ontogglemonths={() => setMode(mode === 'months' ? 'days' : 'months')}
413
- ontoggleyears={() => setMode(mode === 'years' ? 'days' : 'years')}
414
- />
415
-
416
- <div class="np-docked-date-picker-views">
417
- <div class="np-docked-date-picker-body" inert={mode !== 'days'}>
418
- <Calendar
419
- month={monthDate}
420
- selected={pendingDate}
421
- min={minDate}
422
- max={maxDate}
423
- {locale}
424
- firstDayOfWeek={week}
425
- {isDateEnabled}
426
- {adjacentMonthDays}
427
- dynamicRows
428
- todayDate={todayValue}
429
- focusedDate={focusedDay}
430
- selectedLabel={selectedDateLabel}
431
- onselect={selectDay}
432
- onmonthstep={(delta) => setMonth(addMonths(monthDate, delta))}
433
- onfocusday={(date) => {
434
- focusedDay = date
435
- if (
436
- date.getMonth() !== monthDate.getMonth() ||
437
- date.getFullYear() !== monthDate.getFullYear()
438
- ) {
439
- setMonth(date)
440
- }
441
- }}
442
- />
443
- </div>
444
-
445
- {#if listMode}
446
- <div class={['np-docked-date-picker-menu-view', mode !== 'days' && 'open']}>
447
- <div class="np-docked-date-picker-menu-shade">
448
- <Divider --np-divider-color="var(--np-color-outline-variant)" />
449
- {#if listMode === 'months'}
450
- <SelectionList
451
- id="{uid}-months"
452
- aria-label={selectMonthLabel}
453
- options={monthOptions}
454
- value={monthDate.getMonth()}
455
- onselect={chooseMonth}
456
- />
457
- {:else}
458
- <SelectionList
459
- id="{uid}-years"
460
- aria-label={selectYearLabel}
461
- options={yearOptions}
462
- value={monthDate.getFullYear()}
463
- onselect={chooseYear}
464
- />
465
- {/if}
466
- </div>
467
- </div>
468
- {/if}
469
- </div>
470
-
471
- <div class="np-docked-date-picker-actions">
472
- <Button type="button" variant="text" onclick={() => closePicker()}>{cancelLabel}</Button>
473
- <Button type="button" variant="text" onclick={confirm}>{confirmLabel}</Button>
474
- </div>
130
+ <div class="np-docked-date-picker-container">
131
+ <MonthPanel
132
+ bind:this={panel}
133
+ month={monthDate}
134
+ selected={pendingDate}
135
+ min={minDate}
136
+ max={maxDate}
137
+ {locale}
138
+ firstDayOfWeek={firstDayOfWeek ?? getFirstDayOfWeek(locale)}
139
+ {yearRange}
140
+ {isDateEnabled}
141
+ {adjacentMonthDays}
142
+ today={todayValue}
143
+ {previousMonthLabel}
144
+ {nextMonthLabel}
145
+ {previousYearLabel}
146
+ {nextYearLabel}
147
+ {selectMonthLabel}
148
+ {selectYearLabel}
149
+ {selectedDateLabel}
150
+ {shortcutLabels}
151
+ onmonth={setMonth}
152
+ onselect={(date) => {
153
+ pending = toISODate(date)
154
+ setMonth(date)
155
+ }}
156
+ onconfirm={(date) => field?.confirm(toISODate(date))}
157
+ />
158
+
159
+ <div class="np-docked-date-picker-actions">
160
+ <Button type="button" variant="text" onclick={() => field?.closePicker()}
161
+ >{cancelLabel}</Button
162
+ >
163
+ <Button type="button" variant="text" onclick={() => field?.confirm(pending)}
164
+ >{confirmLabel}</Button
165
+ >
475
166
  </div>
476
- {/if}
477
- </Menu>
167
+ </div>
168
+ </DockedPickerField>
478
169
 
479
170
  <style>
480
- :global(.np-docked-date-picker-menu .np-menu) {
481
- padding: 0;
482
- }
483
-
484
171
  .np-docked-date-picker-container {
485
172
  box-sizing: border-box;
486
173
  display: flex;
@@ -491,19 +178,6 @@
491
178
  color: var(--np-color-on-surface);
492
179
  }
493
180
 
494
- .np-docked-date-picker-container :global(.np-date-picker-header) {
495
- margin-inline: 0.75rem;
496
- }
497
-
498
- .np-docked-date-picker-views {
499
- position: relative;
500
- margin-top: 1.875rem;
501
- }
502
-
503
- .np-docked-date-picker-body {
504
- padding-inline: 0.75rem;
505
- }
506
-
507
181
  .np-docked-date-picker-actions {
508
182
  display: flex;
509
183
  justify-content: flex-end;
@@ -518,66 +192,4 @@
518
192
  :global(.np-docked-date-picker-actions .np-button) {
519
193
  height: 2.25rem;
520
194
  }
521
-
522
- .np-docked-date-picker-menu-view {
523
- position: absolute;
524
- inset: 0;
525
- overflow: hidden;
526
- visibility: hidden;
527
- }
528
-
529
- .np-docked-date-picker-menu-view.open {
530
- visibility: visible;
531
- }
532
-
533
- .np-docked-date-picker-menu-shade {
534
- display: flex;
535
- flex-direction: column;
536
- height: 100%;
537
- translate: 0 -100%;
538
- opacity: 0.6;
539
- background-color: var(
540
- --np-docked-date-picker-container-color,
541
- var(--np-color-surface-container-high)
542
- );
543
- }
544
-
545
- .np-docked-date-picker-menu-view.open .np-docked-date-picker-menu-shade {
546
- translate: 0 0;
547
- opacity: 1;
548
- }
549
-
550
- .np-docked-date-picker-menu-view :global(.np-date-picker-selection-list) {
551
- flex: 1;
552
- min-height: 0;
553
- }
554
-
555
- @media (prefers-reduced-motion: no-preference) {
556
- .np-docked-date-picker-menu-view {
557
- transition: visibility var(--np-motion-expressive-default-effects);
558
- }
559
-
560
- .np-docked-date-picker-menu-shade {
561
- transition:
562
- translate var(--np-motion-expressive-default-effects),
563
- opacity var(--np-motion-expressive-fast-effects);
564
- }
565
-
566
- .np-docked-date-picker-menu-view.open .np-docked-date-picker-menu-shade {
567
- transition:
568
- translate var(--np-motion-expressive-default-effects),
569
- opacity var(--np-motion-expressive-default-effects);
570
- }
571
-
572
- @starting-style {
573
- .np-docked-date-picker-menu-view.open .np-docked-date-picker-menu-shade {
574
- translate: 0 -100%;
575
- opacity: 0.6;
576
- }
577
- }
578
- }
579
-
580
- .np-docked-date-picker-container :global(.np-divider) {
581
- flex: none;
582
- }
583
195
  </style>
@@ -1,7 +1,7 @@
1
1
  import type { DockedDatePickerProps } from './types.js';
2
2
  declare const DockedDatePicker: import("svelte").Component<DockedDatePickerProps, {
3
- show: () => void;
4
- close: () => void;
3
+ show: () => void | undefined;
4
+ close: () => any;
5
5
  }, "open" | "element" | "value" | "displayMonth">;
6
6
  type DockedDatePicker = ReturnType<typeof DockedDatePicker>;
7
7
  export default DockedDatePicker;