@lekoala/slot-picker 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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +370 -0
  3. package/custom-elements.json +53 -0
  4. package/dist/slot-picker.css +597 -0
  5. package/dist/slot-picker.js +1382 -0
  6. package/dist/slot-picker.min.css +1 -0
  7. package/dist/slot-picker.min.js +36 -0
  8. package/dist/types/date.d.ts +23 -0
  9. package/dist/types/date.d.ts.map +1 -0
  10. package/dist/types/define.d.ts +2 -0
  11. package/dist/types/define.d.ts.map +1 -0
  12. package/dist/types/index.d.ts +6 -0
  13. package/dist/types/index.d.ts.map +1 -0
  14. package/dist/types/locales/ar.d.ts +20 -0
  15. package/dist/types/locales/ar.d.ts.map +1 -0
  16. package/dist/types/locales/de.d.ts +20 -0
  17. package/dist/types/locales/de.d.ts.map +1 -0
  18. package/dist/types/locales/en.d.ts +20 -0
  19. package/dist/types/locales/en.d.ts.map +1 -0
  20. package/dist/types/locales/es.d.ts +20 -0
  21. package/dist/types/locales/es.d.ts.map +1 -0
  22. package/dist/types/locales/fr.d.ts +20 -0
  23. package/dist/types/locales/fr.d.ts.map +1 -0
  24. package/dist/types/locales/hi.d.ts +20 -0
  25. package/dist/types/locales/hi.d.ts.map +1 -0
  26. package/dist/types/locales/id.d.ts +20 -0
  27. package/dist/types/locales/id.d.ts.map +1 -0
  28. package/dist/types/locales/it.d.ts +20 -0
  29. package/dist/types/locales/it.d.ts.map +1 -0
  30. package/dist/types/locales/ja.d.ts +20 -0
  31. package/dist/types/locales/ja.d.ts.map +1 -0
  32. package/dist/types/locales/ko.d.ts +20 -0
  33. package/dist/types/locales/ko.d.ts.map +1 -0
  34. package/dist/types/locales/nl.d.ts +20 -0
  35. package/dist/types/locales/nl.d.ts.map +1 -0
  36. package/dist/types/locales/pl.d.ts +20 -0
  37. package/dist/types/locales/pl.d.ts.map +1 -0
  38. package/dist/types/locales/pt-BR.d.ts +20 -0
  39. package/dist/types/locales/pt-BR.d.ts.map +1 -0
  40. package/dist/types/locales/pt-PT.d.ts +20 -0
  41. package/dist/types/locales/pt-PT.d.ts.map +1 -0
  42. package/dist/types/locales/ru.d.ts +20 -0
  43. package/dist/types/locales/ru.d.ts.map +1 -0
  44. package/dist/types/locales/tr.d.ts +20 -0
  45. package/dist/types/locales/tr.d.ts.map +1 -0
  46. package/dist/types/locales/zh-CN.d.ts +20 -0
  47. package/dist/types/locales/zh-CN.d.ts.map +1 -0
  48. package/dist/types/messages.d.ts +67 -0
  49. package/dist/types/messages.d.ts.map +1 -0
  50. package/dist/types/model.d.ts +213 -0
  51. package/dist/types/model.d.ts.map +1 -0
  52. package/dist/types/slot-picker.d.ts +182 -0
  53. package/dist/types/slot-picker.d.ts.map +1 -0
  54. package/dist/types/source.d.ts +45 -0
  55. package/dist/types/source.d.ts.map +1 -0
  56. package/dist/types/views/columns.d.ts +28 -0
  57. package/dist/types/views/columns.d.ts.map +1 -0
  58. package/dist/types/views/day.d.ts +27 -0
  59. package/dist/types/views/day.d.ts.map +1 -0
  60. package/dist/types/views/shared.d.ts +99 -0
  61. package/dist/types/views/shared.d.ts.map +1 -0
  62. package/docs/USE_CASES.md +197 -0
  63. package/package.json +148 -0
  64. package/src/date.js +66 -0
  65. package/src/define.js +5 -0
  66. package/src/index.js +25 -0
  67. package/src/locales/ar.js +18 -0
  68. package/src/locales/de.js +18 -0
  69. package/src/locales/en.js +18 -0
  70. package/src/locales/es.js +18 -0
  71. package/src/locales/fr.js +18 -0
  72. package/src/locales/hi.js +18 -0
  73. package/src/locales/id.js +18 -0
  74. package/src/locales/it.js +18 -0
  75. package/src/locales/ja.js +18 -0
  76. package/src/locales/ko.js +18 -0
  77. package/src/locales/nl.js +18 -0
  78. package/src/locales/pl.js +18 -0
  79. package/src/locales/pt-BR.js +18 -0
  80. package/src/locales/pt-PT.js +18 -0
  81. package/src/locales/ru.js +18 -0
  82. package/src/locales/tr.js +18 -0
  83. package/src/locales/zh-CN.js +18 -0
  84. package/src/messages.js +44 -0
  85. package/src/model.js +357 -0
  86. package/src/slot-picker.css +597 -0
  87. package/src/slot-picker.js +1094 -0
  88. package/src/source.js +87 -0
  89. package/src/views/columns.js +108 -0
  90. package/src/views/day.js +122 -0
  91. package/src/views/shared.js +157 -0
@@ -0,0 +1,67 @@
1
+ declare const DEFAULT_MESSAGES: {
2
+ previous: string;
3
+ next: string;
4
+ home: string;
5
+ nextAvailability: string;
6
+ showMore: string;
7
+ showLess: string;
8
+ loading: string;
9
+ empty: string;
10
+ closed: string;
11
+ closedRange: string;
12
+ rangeEmptyTitle: string;
13
+ rangeEmptyDescription: string;
14
+ rangeEmptyNext: string;
15
+ oneSlot: string;
16
+ manySlots: string;
17
+ days: string;
18
+ };
19
+ /** Copy of the current global message defaults. */
20
+ export declare function getDefaultMessages(): {
21
+ previous: string;
22
+ next: string;
23
+ home: string;
24
+ nextAvailability: string;
25
+ showMore: string;
26
+ showLess: string;
27
+ loading: string;
28
+ empty: string;
29
+ closed: string;
30
+ closedRange: string;
31
+ rangeEmptyTitle: string;
32
+ rangeEmptyDescription: string;
33
+ rangeEmptyNext: string;
34
+ oneSlot: string;
35
+ manySlots: string;
36
+ days: string;
37
+ };
38
+ /**
39
+ * Update the global defaults applied to every instance without its own
40
+ * `messages` override. Merges into the current defaults.
41
+ * @param {Partial<typeof DEFAULT_MESSAGES>|null|undefined} messages
42
+ */
43
+ export declare function setDefaultMessages(messages: Partial<typeof DEFAULT_MESSAGES> | null | undefined): void;
44
+ /**
45
+ * Resolution hierarchy: DEFAULT_MESSAGES -> global defaults -> instance.
46
+ * @param {Partial<typeof DEFAULT_MESSAGES>|null|undefined} messages
47
+ */
48
+ export declare function resolveMessages(messages: Partial<typeof DEFAULT_MESSAGES> | null | undefined): {
49
+ previous: string;
50
+ next: string;
51
+ home: string;
52
+ nextAvailability: string;
53
+ showMore: string;
54
+ showLess: string;
55
+ loading: string;
56
+ empty: string;
57
+ closed: string;
58
+ closedRange: string;
59
+ rangeEmptyTitle: string;
60
+ rangeEmptyDescription: string;
61
+ rangeEmptyNext: string;
62
+ oneSlot: string;
63
+ manySlots: string;
64
+ days: string;
65
+ };
66
+ export { DEFAULT_MESSAGES };
67
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/messages.js"],"names":[],"mappings":"AAAA,QAAA,MAAM,gBAAgB;IACpB,QAAQ;IACR,IAAI;IACJ,IAAI;IACJ,gBAAgB;IAChB,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,KAAK;IACL,MAAM;IACN,WAAW;IACX,eAAe;IACf,qBAAqB;IACrB,cAAc;IACd,OAAO;IACP,SAAS;IACT,IAAI;CACL,CAAC;AAIF,mDAAmD;AACnD,wBAAgB,kBAAkB;;;;;;;;;;;;;;;;;EAEjC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAFhC,OAAO,CAAC,OAAO,gBAAgB,CAAC,GAAC,IAAI,GAAC,SAEN,QAE1C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAF7B,OAAO,CAAC,OAAO,gBAAgB,CAAC,GAAC,IAAI,GAAC,SAET;;;;;;;;;;;;;;;;;EAEvC;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Default width-to-capacity ladder for `responsive` projection.
3
+ * Resolved against the component's own inline size, never the viewport.
4
+ * Calibrated after navigation stopped reserving grid tracks: each step is the
5
+ * width at which a column still measures ~110px in the fixtures.
6
+ * @type {readonly {minWidth:number,dayCount:number}[]}
7
+ */
8
+ export declare const RESPONSIVE_BREAKPOINTS: readonly {
9
+ minWidth: number;
10
+ dayCount: number;
11
+ }[];
12
+ export type Slot = {
13
+ start: string;
14
+ end?: string;
15
+ disabled?: boolean;
16
+ description?: string;
17
+ tone?: string;
18
+ meta?: unknown;
19
+ };
20
+ export type DayNotice = {
21
+ label: string;
22
+ description?: string;
23
+ meta?: unknown;
24
+ };
25
+ export type SlotDay = {
26
+ date: string;
27
+ slots: Slot[];
28
+ closed?: boolean;
29
+ notice?: DayNotice;
30
+ };
31
+ /** @param {string} value */
32
+ export declare function isTimeValue(value: string): boolean;
33
+ /**
34
+ * Canonical slot value: a civil date and a time, no timezone.
35
+ * Rejects impossible dates such as 2026-02-31.
36
+ * @param {string} value
37
+ */
38
+ export declare function isSlotValue(value: string): boolean;
39
+ /** @param {string} date @param {string} time */
40
+ export declare function slotValue(date: string, time: string): string;
41
+ /** @param {SlotDay[]} input */
42
+ export declare function normalizeDays(input: SlotDay[]): {
43
+ date: string;
44
+ slots: {
45
+ start: string;
46
+ end?: string;
47
+ disabled?: boolean;
48
+ description?: string;
49
+ tone?: string;
50
+ meta?: unknown;
51
+ }[];
52
+ closed?: boolean | undefined;
53
+ notice?: {
54
+ label: string;
55
+ description?: string;
56
+ meta?: unknown;
57
+ } | undefined;
58
+ }[];
59
+ /**
60
+ * Fill missing days so an empty day remains visible.
61
+ * @param {SlotDay[]} days
62
+ * @param {string} start
63
+ * @param {number} dayCount
64
+ */
65
+ export declare function visibleDays(days: SlotDay[], start: string, dayCount: number): {
66
+ date: string;
67
+ slots: {
68
+ start: string;
69
+ end?: string;
70
+ disabled?: boolean;
71
+ description?: string;
72
+ tone?: string;
73
+ meta?: unknown;
74
+ }[];
75
+ closed?: boolean | undefined;
76
+ notice?: {
77
+ label: string;
78
+ description?: string;
79
+ meta?: unknown;
80
+ } | undefined;
81
+ }[];
82
+ /**
83
+ * Presentation-only collapse: keep the first N slot rows.
84
+ * Hidden slots stay part of the loaded model, so selection is unaffected;
85
+ * rendering and keyboard navigation must agree on this exact subset.
86
+ * @param {SlotDay[]} days
87
+ * @param {number} maxVisibleRows
88
+ * @param {boolean} expanded
89
+ */
90
+ export declare function collapsedDays(days: SlotDay[], maxVisibleRows: number, expanded: boolean): {
91
+ rows: number;
92
+ hasOverflow: boolean;
93
+ days: {
94
+ date: string;
95
+ closed?: boolean;
96
+ notice?: DayNotice;
97
+ slots: Slot[];
98
+ }[];
99
+ };
100
+ /**
101
+ * True when `min`/`max` describe a consistent bound. Both empty is valid
102
+ * (unbounded); `min > max` is an explicit invalid configuration.
103
+ * @param {string} min
104
+ * @param {string} max
105
+ */
106
+ export declare function isValidRange(min: string, max: string): boolean;
107
+ /**
108
+ * Reduce a requested day count to the days actually available inside the
109
+ * bounds. Step 2 of the pipeline: requested count -> bounded count.
110
+ * Invalid bounds (`min > max`) resolve to 0, never a magic window.
111
+ * @param {number} dayCount
112
+ * @param {string} min
113
+ * @param {string} max
114
+ */
115
+ export declare function boundedDayCount(dayCount: number, min: string, max: string): number;
116
+ /**
117
+ * Normalize an override ladder: descending widths, sane counts.
118
+ * @param {{minWidth?:number,dayCount?:number}[]} breakpoints
119
+ * @returns {{minWidth:number,dayCount:number}[]}
120
+ */
121
+ export declare function normalizeBreakpoints(breakpoints: {
122
+ minWidth?: number;
123
+ dayCount?: number;
124
+ }[]): {
125
+ minWidth: number;
126
+ dayCount: number;
127
+ }[];
128
+ /**
129
+ * Step 3 of the pipeline: adapt the bounded count to the component's own
130
+ * inline size. Never exceeds the bounded count, never exceeds a breakpoint.
131
+ * @param {number} dayCount
132
+ * @param {number} width
133
+ * @param {readonly {minWidth:number,dayCount:number}[]} [breakpoints]
134
+ */
135
+ export declare function resolveVisibleDayCount(dayCount: number, width: number, breakpoints?: readonly {
136
+ minWidth: number;
137
+ dayCount: number;
138
+ }[]): number;
139
+ /**
140
+ * Keep a window inside its bounds without shrinking it below the requested
141
+ * count unless the interval itself is shorter.
142
+ * @param {string} start
143
+ * @param {string} min
144
+ * @param {string} max
145
+ * @param {number} dayCount
146
+ */
147
+ export declare function clampStart(start: string, min: string, max: string, dayCount: number): string;
148
+ /**
149
+ * Stable range adjustment: keep `start` when `date` is already visible,
150
+ * otherwise shift just enough to bring `date` back into the window.
151
+ * Shared by resize, `goTo`, and min/max/day-count changes.
152
+ * @param {string} start
153
+ * @param {number} dayCount
154
+ * @param {string} date
155
+ * @param {string} min
156
+ * @param {string} max
157
+ */
158
+ export declare function ensureVisible(start: string, dayCount: number, date: string, min: string, max: string): string;
159
+ /**
160
+ * Any appointment slot in the visible window.
161
+ * @param {SlotDay[]} days
162
+ */
163
+ export declare function hasSlots(days: SlotDay[]): boolean;
164
+ /**
165
+ * Any meaningful day content: a slot, a notice or a closed day. A window with
166
+ * no slot but a notice or a closed state must keep its projection, so an
167
+ * exception or a recurring closure stays visible and is not collapsed into
168
+ * "no availability".
169
+ * @param {SlotDay[]} days
170
+ */
171
+ export declare function hasDayContent(days: SlotDay[]): boolean;
172
+ /**
173
+ * @param {string} start
174
+ * @param {number} dayCount
175
+ */
176
+ export declare function rangeDetail(start: string, dayCount: number): {
177
+ start: string;
178
+ end: string;
179
+ dayCount: number;
180
+ };
181
+ /**
182
+ * Civil-only active day resolution.
183
+ * Loaded slots never influence the consulted day:
184
+ * absent/invalid maps to start, out-of-range clamps to the visible range.
185
+ * @param {string} start
186
+ * @param {number} dayCount
187
+ * @param {string} activeDate
188
+ */
189
+ export declare function resolveActiveDate(start: string, dayCount: number, activeDate: string): string;
190
+ /**
191
+ * @param {SlotDay[]} days
192
+ * @returns {{dayIndex:number, slotIndex:number, value:string}[]}
193
+ */
194
+ export declare function focusableSlots(days: SlotDay[]): {
195
+ dayIndex: number;
196
+ slotIndex: number;
197
+ value: string;
198
+ }[];
199
+ /**
200
+ * Keyboard focus movement. Disabled slots are skipped: they stay visible
201
+ * and activatable-guarded, but never take keyboard focus.
202
+ * @param {SlotDay[]} days
203
+ * @param {{dayIndex:number,slotIndex:number}} current
204
+ * @param {"up"|"down"|"left"|"right"|"home"|"end"} direction
205
+ */
206
+ export declare function moveFocus(days: SlotDay[], current: {
207
+ dayIndex: number;
208
+ slotIndex: number;
209
+ }, direction: "up" | "down" | "left" | "right" | "home" | "end"): {
210
+ dayIndex: number;
211
+ slotIndex: number;
212
+ };
213
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/model.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ export type SlotDay = import("./model.js").SlotDay;
2
+ export type FocusDirection = "up" | "down" | "left" | "right" | "home" | "end";
3
+ export type ResponsiveBreakpoint = {
4
+ minWidth: number;
5
+ dayCount: number;
6
+ };
7
+ export type ConfigureOptions = Partial<{
8
+ min: string;
9
+ max: string;
10
+ start: string;
11
+ dayCount: number;
12
+ layout: "columns" | "day";
13
+ value: string;
14
+ maxVisibleRows: number;
15
+ responsive: boolean;
16
+ homeDate: string | null;
17
+ responsiveBreakpoints: ResponsiveBreakpoint[] | null;
18
+ closedDays: "show" | "hide";
19
+ }>;
20
+ /** @typedef {import("./model.js").SlotDay} SlotDay */
21
+ /** @typedef {"up"|"down"|"left"|"right"|"home"|"end"} FocusDirection */
22
+ /** @typedef {{minWidth:number,dayCount:number}} ResponsiveBreakpoint */
23
+ /**
24
+ * @typedef {Partial<{
25
+ * min: string,
26
+ * max: string,
27
+ * start: string,
28
+ * dayCount: number,
29
+ * layout: "columns"|"day",
30
+ * value: string,
31
+ * maxVisibleRows: number,
32
+ * responsive: boolean,
33
+ * homeDate: string|null,
34
+ * responsiveBreakpoints: ResponsiveBreakpoint[]|null,
35
+ * closedDays: "show"|"hide",
36
+ * }>} ConfigureOptions
37
+ */
38
+ /**
39
+ * Inline appointment slot chooser.
40
+ *
41
+ * Canonical public values:
42
+ * - dates: YYYY-MM-DD
43
+ * - times: HH:mm
44
+ * - value: YYYY-MM-DDTHH:mm
45
+ *
46
+ * State:
47
+ * - dayCount: consumer's maximum intention
48
+ * - visibleDayCount: capacity actually resolved from bounds + width
49
+ * - start/range: visible civil range
50
+ * - activeDate: consulted day
51
+ * - focusedValue: keyboard target, never a selection
52
+ * - value: selected local slot value
53
+ * - homeDate: reference date for `goHome()`, unrelated to `min`
54
+ *
55
+ * Invariants:
56
+ * - resize changes the range, never `value`;
57
+ * - navigation changes the range, never `value`;
58
+ * - day activation changes `activeDate`, never `value`;
59
+ * - slot activation changes `activeDate` and `value`;
60
+ * - event order is stable: `rangechange` then `daychange`, then any reload.
61
+ */
62
+ export declare class SlotPickerElement extends HTMLElement {
63
+ #private;
64
+ static observedAttributes: string[];
65
+ constructor();
66
+ connectedCallback(): void;
67
+ disconnectedCallback(): void;
68
+ /**
69
+ * @param {string} name
70
+ * @param {string|null} oldValue
71
+ * @param {string|null} newValue
72
+ */
73
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
74
+ get start(): string;
75
+ set start(value: string);
76
+ get dayCount(): number;
77
+ /** @param {number} value */
78
+ set dayCount(value: number);
79
+ /**
80
+ * Consumer's maximum intention.
81
+ * @see visibleDayCount for the resolved value.
82
+ */
83
+ get visibleDayCount(): number;
84
+ get responsive(): boolean;
85
+ set responsive(value: boolean);
86
+ /** @returns {readonly ResponsiveBreakpoint[]} */
87
+ get responsiveBreakpoints(): readonly ResponsiveBreakpoint[];
88
+ /** @param {ResponsiveBreakpoint[]|null} value */
89
+ set responsiveBreakpoints(value: ResponsiveBreakpoint[] | null);
90
+ get min(): string;
91
+ set min(value: string);
92
+ get max(): string;
93
+ set max(value: string);
94
+ /**
95
+ * Canonical selection. A malformed attribute (markup is not guaranteed to be
96
+ * valid) reads as empty instead of breaking the upgrade; the property setter
97
+ * still rejects it explicitly.
98
+ */
99
+ get value(): string;
100
+ set value(value: string);
101
+ get activeDate(): string;
102
+ set activeDate(value: string);
103
+ /** Reference date used by `goHome()`. Never confused with `min`. */
104
+ get homeDate(): string;
105
+ set homeDate(value: string);
106
+ get layout(): "columns" | "day";
107
+ set layout(value: string);
108
+ /**
109
+ * Notice projection strategy:
110
+ * - `action` (default) renders only an accessible control that emits
111
+ * `noticeactivate`, so the application owns the detailed presentation;
112
+ * - `inline` additionally renders the readable notice content, which stays
113
+ * non-interactive;
114
+ * - `none` renders nothing.
115
+ */
116
+ get noticeDisplay(): "action" | "inline" | "none";
117
+ set noticeDisplay(value: string);
118
+ /**
119
+ * Projection policy for `closed` days:
120
+ * - `show` (default) renders every civil day;
121
+ * - `hide` omits closed days from the projection without changing the civil
122
+ * range, `previous()`/`next()` or `source.load()`.
123
+ */
124
+ get closedDays(): "hide" | "show";
125
+ set closedDays(value: string);
126
+ get expanded(): boolean;
127
+ set expanded(value: boolean);
128
+ get maxVisibleRows(): number;
129
+ set maxVisibleRows(value: number);
130
+ /** @returns {SlotDay[]} */
131
+ get days(): SlotDay[];
132
+ /** @param {SlotDay[]} value */
133
+ set days(value: SlotDay[]);
134
+ /** @param {import("./source.js").SlotSource|null} source */
135
+ set source(source: import("./source.js").SlotSource | null);
136
+ get source(): import("./source.js").SlotSource | null;
137
+ /**
138
+ * Instance overrides only. Global defaults from `setDefaultMessages()` are
139
+ * resolved at render time, so they also reach already-created instances.
140
+ * @param {Partial<typeof import("./messages.js").DEFAULT_MESSAGES>|null} value
141
+ */
142
+ set messages(value: Partial<typeof import("./messages.js").DEFAULT_MESSAGES> | null);
143
+ /**
144
+ * Locale used for `Intl` formatting. `locale` wins over the native `lang`,
145
+ * then the document language, then the browser language.
146
+ */
147
+ get locale(): string;
148
+ set locale(value: string);
149
+ /** Resolved visible civil range. Empty and invalid when count is 0. */
150
+ get range(): {
151
+ start: string;
152
+ end: string;
153
+ dayCount: number;
154
+ };
155
+ previous(): void;
156
+ next(): void;
157
+ /**
158
+ * Bring `date` into the visible range and consult it.
159
+ * Event order: `rangechange` then `daychange`.
160
+ * @param {string} date
161
+ * @returns {string} the resolved active date, or "" when the range is invalid
162
+ */
163
+ goTo(date: string): string;
164
+ /** Return to the reference window. Distinct from `min` and from `previous()`. */
165
+ goHome(): string;
166
+ /**
167
+ * Ask the source (or, failing that, the `nextrequest` event) for the next
168
+ * known availability beyond the visible range. Never merged with `next()`.
169
+ * @param {{after?:string}} [options]
170
+ * @returns {Promise<string|null>}
171
+ */
172
+ goToNextAvailability(options?: {
173
+ after?: string;
174
+ }): Promise<string | null>;
175
+ /**
176
+ * Apply several settings as one transaction: no intermediate load or event.
177
+ * @param {ConfigureOptions} [options]
178
+ */
179
+ configure(options?: ConfigureOptions): void;
180
+ reload(): Promise<void>;
181
+ }
182
+ //# sourceMappingURL=slot-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot-picker.d.ts","sourceRoot":"","sources":["../../src/slot-picker.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /** @typedef {{start:string,end:string,dayCount:number,signal:AbortSignal}} SourceContext */
2
+ /** @typedef {{after:string,signal:AbortSignal}} NextContext */
3
+ /** @typedef {(context:SourceContext) => Promise<unknown>|unknown} SlotSourceFunction */
4
+ /** @typedef {{load:(context:SourceContext) => Promise<unknown>|unknown, next?:(context:NextContext) => Promise<string|null|undefined>|string|null|undefined}} SlotSourceObject */
5
+ /** @typedef {SlotSourceFunction|SlotSourceObject} SlotSource */
6
+ export type SourceContext = {
7
+ start: string;
8
+ end: string;
9
+ dayCount: number;
10
+ signal: AbortSignal;
11
+ };
12
+ export type NextContext = {
13
+ after: string;
14
+ signal: AbortSignal;
15
+ };
16
+ export type SlotSourceFunction = (context: SourceContext) => Promise<unknown> | unknown;
17
+ export type SlotSourceObject = {
18
+ load: (context: SourceContext) => Promise<unknown> | unknown;
19
+ next?: (context: NextContext) => Promise<string | null | undefined> | string | null | undefined;
20
+ };
21
+ export type SlotSource = SlotSourceFunction | SlotSourceObject;
22
+ export declare class SlotSourceController {
23
+ #private;
24
+ /** @param {SlotSource|null} source */
25
+ set source(source: SlotSource | null);
26
+ get source(): SlotSource | null;
27
+ /** Whether the current source can resolve a date beyond the visible range. */
28
+ get hasNext(): boolean;
29
+ abort(): void;
30
+ /** @param {{start:string,end:string,dayCount:number}} range */
31
+ load(range: {
32
+ start: string;
33
+ end: string;
34
+ dayCount: number;
35
+ }): Promise<unknown>;
36
+ /**
37
+ * Ask the source for the next known availability after `after`.
38
+ * Superseded calls are aborted; a stale response resolves to null.
39
+ * @param {{after:string}} context
40
+ */
41
+ next({ after }: {
42
+ after: string;
43
+ }): Promise<string | null>;
44
+ }
45
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/source.js"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,+DAA+D;AAC/D,wFAAwF;AACxF,kLAAkL;AAClL,gEAAgE;AAJ5D,YAAwE,aAAa,GAA3E;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,GAAG,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,WAAW,CAAA;CAAC,CAAe;AACrF,YAA6C,WAAW,GAA9C;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,WAAW,CAAA;CAAC,CAAa;AACxD,YAA+D,kBAAkB,GAAvE,CAAC,OAAO,EAAC,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,GAAC,OAAO,CAAoB;AACjF,YAA2J,gBAAgB,GAAjK;IAAC,IAAI,EAAC,CAAC,OAAO,EAAC,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,GAAC,OAAO,CAAC;IAAC,IAAI,CAAC,EAAC,CAAC,OAAO,EAAC,WAAW,KAAK,OAAO,CAAC,MAAM,GAAC,IAAI,GAAC,SAAS,CAAC,GAAC,MAAM,GAAC,IAAI,GAAC,SAAS,CAAA;CAAC,CAAkB;AAC3K,YAA+C,UAAU,GAA/C,kBAAkB,GAAC,gBAAgB,CAAY;AAE7D,qBAAa,oBAAoB;;IAU/B,sCAAsC;IACtC,IAAI,MAAM,CAAC,MAAM,EADL,UAAU,GAAC,IACN,EAQhB;IAED,IAAI,MAAM,IAXE,UAAU,GAAC,IAAI,CAa1B;IAED,8EAA8E;IAC9E,IAAI,OAAO,YAGV;IAED,KAAK,SAKJ;IAED,+DAA+D;IACzD,IAAI,CAAC,KAAK,EADJ;QAAC,KAAK,EAAC,MAAM,CAAC;QAAA,GAAG,EAAC,MAAM,CAAC;QAAA,QAAQ,EAAC,MAAM,CAAA;KACpC,oBAiBf;IAED;;;;OAIG;IACG,IAAI,CAAC,EAAE,KAAK,EAAE,EAFT;QAAC,KAAK,EAAC,MAAM,CAAA;KAEJ,0BAgBnB;CACF"}
@@ -0,0 +1,28 @@
1
+ export type SlotDay = import("../model.js").SlotDay;
2
+ export type ColumnsMessages = import("./shared.js").SlotCountMessages & {
3
+ empty: string;
4
+ closed: string;
5
+ };
6
+ /** @typedef {import("../model.js").SlotDay} SlotDay */
7
+ /** @typedef {import("./shared.js").SlotCountMessages & {empty:string,closed:string}} ColumnsMessages */
8
+ /**
9
+ * Columns projection: N civil days side by side with their slots.
10
+ * Empty days render a real DOM empty state (messages.empty); alignment
11
+ * placeholders are aria-hidden and only used when the day has slots
12
+ * but fewer rows than the visible grid.
13
+ * @param {{visible:SlotDay[],value:string,focusedValue:string,maxVisibleRows:number,expanded:boolean,noticeDisplay:"inline"|"action"|"none",messages:ColumnsMessages,locale:string}} options
14
+ */
15
+ export declare function renderColumns({ visible, value, focusedValue, maxVisibleRows, expanded, noticeDisplay, messages, locale, }: {
16
+ visible: SlotDay[];
17
+ value: string;
18
+ focusedValue: string;
19
+ maxVisibleRows: number;
20
+ expanded: boolean;
21
+ noticeDisplay: "inline" | "action" | "none";
22
+ messages: ColumnsMessages;
23
+ locale: string;
24
+ }): {
25
+ html: string;
26
+ hasOverflow: boolean;
27
+ };
28
+ //# sourceMappingURL=columns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../../src/views/columns.js"],"names":[],"mappings":"AAeI,YAAyC,OAAO,GAAtC,OAAO,aAAa,EAAE,OAAO,CAAS;AAChD,YAAkF,eAAe,GAAvF,OAAO,aAAa,EAAE,iBAAiB,GAAG;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAA;CAAC,CAAiB;AADrG,uDAAuD;AACvD,wGAAwG;AAExG;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,KAAK,EACL,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,MAAM,GACP,EAXU;IAAC,OAAO,EAAC,OAAO,EAAE,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,YAAY,EAAC,MAAM,CAAC;IAAA,cAAc,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,OAAO,CAAC;IAAA,aAAa,EAAC,QAAQ,GAAC,QAAQ,GAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,eAAe,CAAC;IAAA,MAAM,EAAC,MAAM,CAAA;CAWlL;;;EAyEA"}
@@ -0,0 +1,27 @@
1
+ export type SlotDay = import("../model.js").SlotDay;
2
+ export type DayMessages = import("./shared.js").SlotCountMessages & {
3
+ empty: string;
4
+ closed: string;
5
+ days: string;
6
+ };
7
+ /** @typedef {import("../model.js").SlotDay} SlotDay */
8
+ /** @typedef {import("./shared.js").SlotCountMessages & {empty:string,closed:string,days:string}} DayMessages */
9
+ /**
10
+ * Day projection: a strip of days plus the slots of the consulted day.
11
+ * The strip uses aria-pressed (consulted day), never aria-current="date".
12
+ * Today stays independently discoverable via data-today.
13
+ * @param {{visible:SlotDay[],activeDate:string,today:string,value:string,focusedValue:string,noticeDisplay:"inline"|"action"|"none",messages:DayMessages,locale:string}} options
14
+ */
15
+ export declare function renderDay({ visible, activeDate, today, value, focusedValue, noticeDisplay, messages, locale, }: {
16
+ visible: SlotDay[];
17
+ activeDate: string;
18
+ today: string;
19
+ value: string;
20
+ focusedValue: string;
21
+ noticeDisplay: "inline" | "action" | "none";
22
+ messages: DayMessages;
23
+ locale: string;
24
+ }): {
25
+ html: string;
26
+ };
27
+ //# sourceMappingURL=day.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"day.d.ts","sourceRoot":"","sources":["../../../src/views/day.js"],"names":[],"mappings":"AAeI,YAAyC,OAAO,GAAtC,OAAO,aAAa,EAAE,OAAO,CAAS;AAChD,YAA8F,WAAW,GAA/F,OAAO,aAAa,EAAE,iBAAiB,GAAG;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,IAAI,EAAC,MAAM,CAAA;CAAC,CAAa;AAD7G,uDAAuD;AACvD,gHAAgH;AAEhH;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,UAAU,EACV,KAAK,EACL,KAAK,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,MAAM,GACP,EAXU;IAAC,OAAO,EAAC,OAAO,EAAE,CAAC;IAAA,UAAU,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,YAAY,EAAC,MAAM,CAAC;IAAA,aAAa,EAAC,QAAQ,GAAC,QAAQ,GAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,WAAW,CAAC;IAAA,MAAM,EAAC,MAAM,CAAA;CAWtK;;EAwFA"}