@magicx-eng/ai-autocomplete-vanilla 0.17.0 → 0.19.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.
- package/README.md +48 -13
- package/dist/index.d.mts +314 -44
- package/dist/index.d.ts +314 -44
- package/dist/index.js +39 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +39 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -147,7 +147,42 @@ interface AccessTokenResult {
|
|
|
147
147
|
expiresAt?: number;
|
|
148
148
|
}
|
|
149
149
|
type APIConfig = APIKeyConfig | AccessTokenConfig;
|
|
150
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Supplies the options for one suggestion type in place of the server's,
|
|
152
|
+
* which are never shown for an overridden type.
|
|
153
|
+
*
|
|
154
|
+
* Called
|
|
155
|
+
* - the moment a pill of this type becomes active (a response suggests it, a
|
|
156
|
+
* skip or a selection moves it to the front, a completed param of this type
|
|
157
|
+
* is tapped to re-edit), with whatever the user has already typed for it —
|
|
158
|
+
* usually `""`, the request for the default list;
|
|
159
|
+
* - again on the SDK's typing debounce with each new phrase, so a consumer
|
|
160
|
+
* whose options live behind a request can run a second search or page
|
|
161
|
+
* through a larger list. Return the same list early if the phrase is
|
|
162
|
+
* already covered by what was last returned.
|
|
163
|
+
*
|
|
164
|
+
* A plain array is applied synchronously — the right shape for a fixed or
|
|
165
|
+
* locally computed list. A promise shows the dropdown's loading state until it
|
|
166
|
+
* settles. Either way the answer is listed as-is, never filtered again by the
|
|
167
|
+
* phrase it was produced for, so a fuzzy or synonym match survives. Between
|
|
168
|
+
* two calls the previous answer is filtered locally by what the user types,
|
|
169
|
+
* for instant feedback.
|
|
170
|
+
*
|
|
171
|
+
* The server is not asked for suggestions while an override owns the active
|
|
172
|
+
* pill. It is asked again when the user answers or skips the pill, and as a
|
|
173
|
+
* fallback when the override returns an empty list for a non-empty phrase —
|
|
174
|
+
* the typed text then goes to the server the way it does for a pill with no
|
|
175
|
+
* matching options. An empty answer for `""` leaves the pill with no options,
|
|
176
|
+
* and the override is not re-asked for a phrase it has already answered empty.
|
|
177
|
+
*
|
|
178
|
+
* Honour `signal` in anything asynchronous: it is aborted when a newer phrase
|
|
179
|
+
* supersedes this call, when the pill stops being active, and on `destroy()`.
|
|
180
|
+
* A rejected promise or a throw is contained — logged once per instance and
|
|
181
|
+
* treated as an empty answer.
|
|
182
|
+
*/
|
|
183
|
+
type OptionOverride = (query: string, signal: AbortSignal, suggestion: Suggestion) => Promise<SuggestionOption[]> | SuggestionOption[];
|
|
184
|
+
/** Per-suggestion-type option overrides, keyed by the suggestion's `type`. */
|
|
185
|
+
type OptionOverrides = Record<string, OptionOverride>;
|
|
151
186
|
/**
|
|
152
187
|
* A single product card in the dropdown's product strip.
|
|
153
188
|
*
|
|
@@ -264,6 +299,17 @@ declare function isoDate(d: Date): string;
|
|
|
264
299
|
* - a different year: "March 23 2027".
|
|
265
300
|
*/
|
|
266
301
|
declare function formatDate(d: Date): string;
|
|
302
|
+
/**
|
|
303
|
+
* A date written as month and day, with the year only when it isn't this one —
|
|
304
|
+
* {@link formatDate} without the weekday shorthand.
|
|
305
|
+
*
|
|
306
|
+
* The shorthand is what a range must not use. "Tuesday - Friday" names four
|
|
307
|
+
* possible spans depending on when it is read, and the two ends of a range are
|
|
308
|
+
* read against each other rather than against today, so the one thing the
|
|
309
|
+
* weekday form is good at — naming a day inside this week unambiguously —
|
|
310
|
+
* stops being true the moment it is half of a span. See `formatDateRange`.
|
|
311
|
+
*/
|
|
312
|
+
declare function formatAbsoluteDate(d: Date): string;
|
|
267
313
|
/**
|
|
268
314
|
* Inverse of {@link formatDate}, for re-opening the calendar on the month a
|
|
269
315
|
* completed date param already holds. Reads all three committed shapes — a
|
|
@@ -326,21 +372,29 @@ declare function cellDay(option: SuggestionOption | undefined): number | null;
|
|
|
326
372
|
*
|
|
327
373
|
* `"options"` is every suggestion the server has ever sent: pick one of its
|
|
328
374
|
* options, or type to filter them. `"date"` ignores the options entirely and
|
|
329
|
-
* renders a calendar instead.
|
|
375
|
+
* renders a calendar instead. `"date-range"` renders the same calendar,
|
|
376
|
+
* answered in two taps — a start and an end — and committed as one span.
|
|
330
377
|
*/
|
|
331
|
-
type FormatType = "options" | "date";
|
|
378
|
+
type FormatType = "options" | "date" | "date-range";
|
|
379
|
+
/** Whether this format is answered by a calendar rather than by a list. */
|
|
380
|
+
declare function isCalendarFormat(format: FormatType): boolean;
|
|
332
381
|
/**
|
|
333
382
|
* Decide how a suggestion should be answered.
|
|
334
383
|
*
|
|
335
|
-
* The server cannot send a `formatType` yet, so a suggestion
|
|
336
|
-
*
|
|
337
|
-
* options ignored.
|
|
384
|
+
* The server cannot send a `formatType` yet, so a suggestion that holds a date
|
|
385
|
+
* is detected here — by the options it offers, and failing that by its name —
|
|
386
|
+
* and rendered as a calendar with those options ignored.
|
|
338
387
|
*
|
|
339
|
-
*
|
|
388
|
+
* The detection is deliberately the LAST resort. A `formatType` that *is* on
|
|
340
389
|
* the wire always wins, so the day the server starts sending one this function
|
|
341
|
-
* needs a single
|
|
390
|
+
* needs a single block deleted — the datepicker itself, and every gate that
|
|
342
391
|
* consults this, keep working untouched.
|
|
343
392
|
*
|
|
393
|
+
* Options are read before the name because they are the stronger evidence:
|
|
394
|
+
* they are the values themselves, while a name is what someone chose to call
|
|
395
|
+
* them. A parameter called `travel_date` whose options are all spans is a span
|
|
396
|
+
* parameter, whatever its name says.
|
|
397
|
+
*
|
|
344
398
|
* Accepts anything with a `type`, not a `Suggestion`, so re-edit can ask the
|
|
345
399
|
* same question about a completed param via its `suggestionType`.
|
|
346
400
|
*/
|
|
@@ -391,6 +445,20 @@ interface CoreInputState {
|
|
|
391
445
|
* never shows results belonging to an older query.
|
|
392
446
|
*/
|
|
393
447
|
products: Product[];
|
|
448
|
+
/**
|
|
449
|
+
* The consumer's {@link OptionSource} request for the pill on screen — the
|
|
450
|
+
* active suggestion, or the completed param being re-edited. `type` is the
|
|
451
|
+
* suggestion type it was asked for and `query` the phrase it was asked with;
|
|
452
|
+
* the answer itself is written into that suggestion's (or param's) `options`
|
|
453
|
+
* so every reader of those — filtering, exact-match promotion, the re-edit
|
|
454
|
+
* cache — sees it without knowing where it came from. Null when no source
|
|
455
|
+
* owns the pill on screen. Owned by `OptionSourceController`.
|
|
456
|
+
*/
|
|
457
|
+
optionSearch: {
|
|
458
|
+
type: string;
|
|
459
|
+
query: string;
|
|
460
|
+
status: "loading" | "done";
|
|
461
|
+
} | null;
|
|
394
462
|
activeDropdownIndex: number;
|
|
395
463
|
newParamId: string | null;
|
|
396
464
|
isLoading: boolean;
|
|
@@ -416,7 +484,7 @@ interface CoreInputState {
|
|
|
416
484
|
/** Current caret offset within the editor. Tracked via DOM `selectionchange`. */
|
|
417
485
|
caretOffset: number | null;
|
|
418
486
|
/**
|
|
419
|
-
* True for ~
|
|
487
|
+
* True for ~170ms after a user-initiated option selection so the press
|
|
420
488
|
* animation can finish before the dropdown switches to its loading skeleton.
|
|
421
489
|
* Set by selectOption / ReEditManager.selectOption, cleared by a timer.
|
|
422
490
|
*/
|
|
@@ -433,6 +501,25 @@ interface CoreInputState {
|
|
|
433
501
|
dateViewMonth: (DateMonthView & {
|
|
434
502
|
key: string;
|
|
435
503
|
}) | null;
|
|
504
|
+
/**
|
|
505
|
+
* The first end of a range the user is part-way through picking, as
|
|
506
|
+
* `YYYY-MM-DD`, or null when no pick is in progress. Surfaces to readers as
|
|
507
|
+
* the derived `dateRangeStart`, the way `dateViewMonth` surfaces as
|
|
508
|
+
* `dateView`.
|
|
509
|
+
*
|
|
510
|
+
* Only meaningful while `activeFormatType` is `"date-range"`, where a date is
|
|
511
|
+
* answered in two taps. `key` names the parameter the pick belongs to (see
|
|
512
|
+
* `dateViewKey`), and unlike `dateViewMonth` a stale one is not merely
|
|
513
|
+
* ignored — it is cleared, by the invariant in `AIAutocomplete`'s
|
|
514
|
+
* constructor. Scoping alone would only HIDE it, and every key it can carry
|
|
515
|
+
* reproduces exactly later in a session: the same pill type re-suggested, the
|
|
516
|
+
* same param re-edited, the same span re-tapped. A resurrected start would
|
|
517
|
+
* then pair with an unrelated tap and commit a span nobody chose.
|
|
518
|
+
*/
|
|
519
|
+
pendingRangeStart: {
|
|
520
|
+
iso: string;
|
|
521
|
+
key: string;
|
|
522
|
+
} | null;
|
|
436
523
|
/**
|
|
437
524
|
* Set while the user is picking a date for a span the server identified as
|
|
438
525
|
* one — "september 5th" in "fly to vegas on september 5th".
|
|
@@ -462,6 +549,20 @@ interface CoreInputState {
|
|
|
462
549
|
*/
|
|
463
550
|
text: string;
|
|
464
551
|
iso: string | null;
|
|
552
|
+
/**
|
|
553
|
+
* The other end, when the span reads as a range ("september 11 to november
|
|
554
|
+
* 16") rather than as one day. Null for a single date, and null for a range
|
|
555
|
+
* whose text couldn't be read — which costs the pre-selection only.
|
|
556
|
+
*/
|
|
557
|
+
isoEnd: string | null;
|
|
558
|
+
/**
|
|
559
|
+
* How this span is answered — a calendar, or a calendar in two taps.
|
|
560
|
+
*
|
|
561
|
+
* Resolved once when the picker opens and carried here rather than
|
|
562
|
+
* re-derived, because it depends on the span's own text (a `travel_date`
|
|
563
|
+
* written as a span is a range) and the derive layer only sees its type.
|
|
564
|
+
*/
|
|
565
|
+
format: FormatType;
|
|
465
566
|
} | null;
|
|
466
567
|
}
|
|
467
568
|
/**
|
|
@@ -474,8 +575,9 @@ interface CoreDerivedState {
|
|
|
474
575
|
actionableSuggestions: Suggestion[];
|
|
475
576
|
/**
|
|
476
577
|
* What the dropdown renders. Options for the active pill, filtered by what
|
|
477
|
-
* the user typed — EXCEPT when `activeFormatType` is
|
|
478
|
-
* are the visible month's calendar
|
|
578
|
+
* the user typed — EXCEPT when `activeFormatType` is a calendar one
|
|
579
|
+
* (`"date"` / `"date-range"`), where these are the visible month's calendar
|
|
580
|
+
* cells and the server's own options for
|
|
479
581
|
* that suggestion are ignored. See {@link buildDateOptions}.
|
|
480
582
|
*/
|
|
481
583
|
filteredOptions: SuggestionOption[];
|
|
@@ -487,9 +589,30 @@ interface CoreDerivedState {
|
|
|
487
589
|
* exact-match gates in `fetchController`).
|
|
488
590
|
*/
|
|
489
591
|
activeFormatType: FormatType;
|
|
490
|
-
/** The month the datepicker is showing. Null unless `activeFormatType` is
|
|
592
|
+
/** The month the datepicker is showing. Null unless `activeFormatType` is a calendar one. */
|
|
491
593
|
dateView: DateMonthView | null;
|
|
594
|
+
/**
|
|
595
|
+
* The first end of a range already picked, as `YYYY-MM-DD`, while the user is
|
|
596
|
+
* choosing the second. Null whenever no pick is in progress — including for
|
|
597
|
+
* every non-range format, so a UI can read it without checking the format
|
|
598
|
+
* first. The calendars paint the span between it and the highlighted cell.
|
|
599
|
+
*/
|
|
600
|
+
dateRangeStart: string | null;
|
|
492
601
|
placeholderText: string;
|
|
602
|
+
/**
|
|
603
|
+
* The phrase the active pill's options are filtered by — what the user has
|
|
604
|
+
* typed for it, trimmed — or, during a re-edit, the replacement typed so
|
|
605
|
+
* far. `""` when nothing has been typed for the pill yet. This is the query
|
|
606
|
+
* an {@link OptionSource} is asked with.
|
|
607
|
+
*/
|
|
608
|
+
optionQuery: string;
|
|
609
|
+
/**
|
|
610
|
+
* True while the consumer's {@link OptionSource} for the pill on screen has
|
|
611
|
+
* been asked and hasn't answered yet. The built-in dropdowns show their
|
|
612
|
+
* loading skeleton for it exactly as they do for `isLoading`; a custom UI
|
|
613
|
+
* should treat it the same way. Never true for a pill without a source.
|
|
614
|
+
*/
|
|
615
|
+
isSearchingOptions: boolean;
|
|
493
616
|
isDropdownOpen: boolean;
|
|
494
617
|
/**
|
|
495
618
|
* Whether the active (leading) pill should render in its `selected` state
|
|
@@ -648,6 +771,7 @@ declare class AIAutocomplete {
|
|
|
648
771
|
private keyboardController;
|
|
649
772
|
private pillsController;
|
|
650
773
|
private productsController;
|
|
774
|
+
private optionSource;
|
|
651
775
|
private reEdit;
|
|
652
776
|
private modeController;
|
|
653
777
|
private container;
|
|
@@ -656,11 +780,9 @@ declare class AIAutocomplete {
|
|
|
656
780
|
private domRefs;
|
|
657
781
|
private dropdownRefs;
|
|
658
782
|
private timers;
|
|
659
|
-
/** One per instance — see {@link ConsumerBoundary}. Shared by the emitter
|
|
783
|
+
/** One per instance — see {@link ConsumerBoundary}. Shared by the emitter and `subscribe()`. */
|
|
660
784
|
private boundary;
|
|
661
785
|
/** Identity of the raw override record the wrapped copy below was built from. */
|
|
662
|
-
private rawOverrides;
|
|
663
|
-
private wrappedOverrides;
|
|
664
786
|
private subscriberCount;
|
|
665
787
|
private emitter;
|
|
666
788
|
private sessionId;
|
|
@@ -844,24 +966,6 @@ declare class AIAutocomplete {
|
|
|
844
966
|
selectOption(option: SuggestionOption): void;
|
|
845
967
|
private startSelectionAnimationTimer;
|
|
846
968
|
private fireTelemetry;
|
|
847
|
-
/**
|
|
848
|
-
* `this.opts` with every `optionOverrides` entry wrapped in the instance's
|
|
849
|
-
* {@link ConsumerBoundary}.
|
|
850
|
-
*
|
|
851
|
-
* The derive layer calls these functions on the SDK's stack — from
|
|
852
|
-
* `getState()`, and from inside the store's notification drain — so an
|
|
853
|
-
* un-wrapped throw would unwind whatever internal operation triggered the
|
|
854
|
-
* derive and abort delivery of every queued notification with it, taking the
|
|
855
|
-
* instance down rather than just the override. Wrapped, a failed override
|
|
856
|
-
* answers `undefined` and each call site falls back to the server's options.
|
|
857
|
-
*
|
|
858
|
-
* Memoized on the raw record's identity so a swapped integration is
|
|
859
|
-
* re-wrapped while a stable one isn't re-wrapped on every derive. Note
|
|
860
|
-
* `update({ optionOverrides })` only becomes visible on the next store write
|
|
861
|
-
* — the derived layer memoizes on inputs identity, and `update` doesn't
|
|
862
|
-
* invalidate it for this key. Pre-existing, and unchanged by the wrapping.
|
|
863
|
-
*/
|
|
864
|
-
private deriveOpts;
|
|
865
969
|
private setupContainer;
|
|
866
970
|
private buildAndRenderFull;
|
|
867
971
|
private buildAndRenderDropdown;
|
|
@@ -974,6 +1078,149 @@ declare function resolveIdentifiedDate(param: {
|
|
|
974
1078
|
isoDate?: unknown;
|
|
975
1079
|
}, opts?: LooseDateOptions): string | null;
|
|
976
1080
|
|
|
1081
|
+
/**
|
|
1082
|
+
* A span of days, both ends inclusive, as `YYYY-MM-DD`. `start <= end` always —
|
|
1083
|
+
* every producer here orders the two.
|
|
1084
|
+
*/
|
|
1085
|
+
interface DateRange {
|
|
1086
|
+
start: string;
|
|
1087
|
+
end: string;
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* What joins the two ends of a committed range.
|
|
1091
|
+
*
|
|
1092
|
+
* A spaced hyphen, because the committed text lands verbatim in the user's own
|
|
1093
|
+
* sentence and is what the server parses back. `parseLooseDateRange` reads far
|
|
1094
|
+
* more separators than this one — it has to, since it is also what reads a
|
|
1095
|
+
* server's option text and the user's own words — but the SDK only ever writes
|
|
1096
|
+
* this one.
|
|
1097
|
+
*/
|
|
1098
|
+
declare const RANGE_SEPARATOR = " - ";
|
|
1099
|
+
/** Metadata key holding a committed range's start, as `YYYY-MM-DD`. */
|
|
1100
|
+
declare const DATE_RANGE_META_START = "aiaDateRangeStart";
|
|
1101
|
+
/** Metadata key holding a committed range's end, as `YYYY-MM-DD`. */
|
|
1102
|
+
declare const DATE_RANGE_META_END = "aiaDateRangeEnd";
|
|
1103
|
+
/**
|
|
1104
|
+
* Best-effort parse of a span of days written in the user's (or the server's)
|
|
1105
|
+
* own words — "September 11 - October 13", "September 11 to November 16",
|
|
1106
|
+
* "13/05/2026 - 20/05/2026".
|
|
1107
|
+
*
|
|
1108
|
+
* Each half goes through {@link parseLooseDate}, so a range reads exactly the
|
|
1109
|
+
* date formats a single date does, and refuses exactly what it refuses. Same
|
|
1110
|
+
* trade as everywhere in this corner of the SDK: **null is a normal outcome**.
|
|
1111
|
+
* It costs the range picker's pre-selection, or keeps a suggestion rendering as
|
|
1112
|
+
* a plain option list — never correctness.
|
|
1113
|
+
*
|
|
1114
|
+
* Refused on purpose:
|
|
1115
|
+
* - A backwards span ("October 13 - September 11"). Nothing here can tell a
|
|
1116
|
+
* typo from a year boundary the writer left implicit, and silently swapping
|
|
1117
|
+
* the ends would answer a question the user didn't ask.
|
|
1118
|
+
* - A shared-month shorthand ("September 11 - 13"). The right half alone is
|
|
1119
|
+
* not a date, and inferring the month from the left half is the kind of
|
|
1120
|
+
* guess this file exists not to make.
|
|
1121
|
+
* - Anything where two different splits both read as a range — the text is
|
|
1122
|
+
* then genuinely ambiguous about where its own separator is.
|
|
1123
|
+
*
|
|
1124
|
+
* A yearless half resolves the way {@link parseLooseDate} resolves one: to its
|
|
1125
|
+
* next occurrence. That is what makes "December 30 - January 5" read as the
|
|
1126
|
+
* turn of the year rather than as a backwards span.
|
|
1127
|
+
*/
|
|
1128
|
+
declare function parseLooseDateRange(text: string | undefined | null, opts?: LooseDateOptions): DateRange | null;
|
|
1129
|
+
/**
|
|
1130
|
+
* The committed text for a range — "September 11 - October 13".
|
|
1131
|
+
*
|
|
1132
|
+
* Each end is written by {@link formatAbsoluteDate}, never by `formatDate`:
|
|
1133
|
+
* the weekday shorthand it would use for a nearby day ("Tuesday") names a
|
|
1134
|
+
* different date every week it is read, which a single answer can carry and a
|
|
1135
|
+
* span cannot.
|
|
1136
|
+
*
|
|
1137
|
+
* A span of one day commits as that day alone. "September 11 - September 11"
|
|
1138
|
+
* is not how anyone writes it, and the range is still recoverable from the
|
|
1139
|
+
* option's metadata when the answer is re-edited.
|
|
1140
|
+
*/
|
|
1141
|
+
declare function formatDateRange(range: DateRange): string;
|
|
1142
|
+
/**
|
|
1143
|
+
* The range an already-answered param holds, so both its ends can be marked
|
|
1144
|
+
* when it is re-opened.
|
|
1145
|
+
*
|
|
1146
|
+
* Metadata first — it is what the SDK itself wrote, exact and free of the
|
|
1147
|
+
* yearless-date resolution the text form needs. Text second, which is what a
|
|
1148
|
+
* range that reached the input any other way (a server-identified span, a
|
|
1149
|
+
* consumer's controlled value) has.
|
|
1150
|
+
*/
|
|
1151
|
+
declare function selectedRangeFor(param: {
|
|
1152
|
+
text?: string;
|
|
1153
|
+
metadata?: Record<string, unknown>;
|
|
1154
|
+
} | undefined | null, opts?: LooseDateOptions): DateRange | null;
|
|
1155
|
+
|
|
1156
|
+
/**
|
|
1157
|
+
* What a calendar paints as answered.
|
|
1158
|
+
*
|
|
1159
|
+
* Three fields rather than one because they answer three different questions,
|
|
1160
|
+
* and a range picker shows two of them at once: what is already committed
|
|
1161
|
+
* (`selectedIso` for a day, `selectedRange` for a span) and what the user is
|
|
1162
|
+
* half-way through picking (`rangeStart`). {@link visibleDateRange} folds the
|
|
1163
|
+
* last two into the span actually drawn.
|
|
1164
|
+
*/
|
|
1165
|
+
interface DateSelection {
|
|
1166
|
+
/** `YYYY-MM-DD` a re-edited single-date param already holds, or null. */
|
|
1167
|
+
selectedIso: string | null;
|
|
1168
|
+
/** Both ends of a re-edited range param, or null. */
|
|
1169
|
+
selectedRange: DateRange | null;
|
|
1170
|
+
/** The first end of a range being picked right now, or null. */
|
|
1171
|
+
rangeStart: string | null;
|
|
1172
|
+
}
|
|
1173
|
+
/**
|
|
1174
|
+
* The calendar's selection, read off core state.
|
|
1175
|
+
*
|
|
1176
|
+
* Every package's dropdown needs exactly this, and computing it four times
|
|
1177
|
+
* over — vanilla Tier 1, vanilla Tier 2, the React hook, the Angular
|
|
1178
|
+
* controller — is how the four copies would come to disagree about which cells
|
|
1179
|
+
* a re-edited range fills. Typed structurally so each of them can hand it the
|
|
1180
|
+
* state object it already has.
|
|
1181
|
+
*/
|
|
1182
|
+
declare function dateSelectionFor(state: {
|
|
1183
|
+
activeFormatType: FormatType;
|
|
1184
|
+
editingIdentified: {
|
|
1185
|
+
iso: string | null;
|
|
1186
|
+
isoEnd: string | null;
|
|
1187
|
+
} | null;
|
|
1188
|
+
editingParam: {
|
|
1189
|
+
text: string;
|
|
1190
|
+
metadata?: Record<string, unknown>;
|
|
1191
|
+
} | null;
|
|
1192
|
+
dateRangeStart: string | null;
|
|
1193
|
+
}): DateSelection;
|
|
1194
|
+
/**
|
|
1195
|
+
* The span the calendar should paint right now.
|
|
1196
|
+
*
|
|
1197
|
+
* While a first end is pending, that is the live span between it and whatever
|
|
1198
|
+
* the user is pointing at — the preview every range picker shows, which is also
|
|
1199
|
+
* what tells them the first tap registered. Otherwise it is the answer already
|
|
1200
|
+
* committed, if there is one.
|
|
1201
|
+
*/
|
|
1202
|
+
declare function visibleDateRange(args: {
|
|
1203
|
+
pendingStart: string | null;
|
|
1204
|
+
highlightedIso: string | null;
|
|
1205
|
+
selected: DateRange | null;
|
|
1206
|
+
}): DateRange | null;
|
|
1207
|
+
/**
|
|
1208
|
+
* How one cell renders against the current selection: filled at either end of
|
|
1209
|
+
* the span, banded in between.
|
|
1210
|
+
*
|
|
1211
|
+
* Shared by all three packages' calendars so a range can't be painted three
|
|
1212
|
+
* subtly different ways. `selectedIso` is the single-date answer, which is
|
|
1213
|
+
* mutually exclusive with `range` in practice but costs nothing to fold in
|
|
1214
|
+
* here — it keeps every cell's appearance one function call at every call site.
|
|
1215
|
+
*/
|
|
1216
|
+
declare function dateCellMarks(iso: string | null, args: {
|
|
1217
|
+
selectedIso: string | null;
|
|
1218
|
+
range: DateRange | null;
|
|
1219
|
+
}): {
|
|
1220
|
+
selected: boolean;
|
|
1221
|
+
inRange: boolean;
|
|
1222
|
+
};
|
|
1223
|
+
|
|
977
1224
|
/**
|
|
978
1225
|
* Entrance choreography for the dropdown's option rows.
|
|
979
1226
|
*
|
|
@@ -1071,12 +1318,18 @@ declare function needsOptionsGridMeasurement(count: number, isMobile: boolean):
|
|
|
1071
1318
|
*
|
|
1072
1319
|
* Web, five-plus options: two columns of three visible rows — but only when
|
|
1073
1320
|
* every option provably fits on one line. Rows fill row-major (even indices
|
|
1074
|
-
* left, odd right)
|
|
1075
|
-
*
|
|
1076
|
-
*
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
1079
|
-
*
|
|
1321
|
+
* left, odd right). The left track is exactly as wide as its widest option
|
|
1322
|
+
* (a fixed pixel width from the measurement) and the right track takes the
|
|
1323
|
+
* rest of the grid — which is at least its own widest option, because
|
|
1324
|
+
* `left + right <= gridWidth` is the fit check. So the second column starts
|
|
1325
|
+
* right where the first column's longest text ends, and short options such as
|
|
1326
|
+
* sizes sit beside each other. (Splitting the width in proportion to the two
|
|
1327
|
+
* maxima, as this used to, handed ALL the slack out in that ratio too: one
|
|
1328
|
+
* long option in the left column and "34"-length options on the right gave
|
|
1329
|
+
* the left column ~85% of the box and pushed the right column to the far
|
|
1330
|
+
* edge, 2026-09-03.) When the pair doesn't fit — or there are no usable
|
|
1331
|
+
* measurements (SSR, hidden grid, loading skeletons) — the layout stays one
|
|
1332
|
+
* scrollable column.
|
|
1080
1333
|
*
|
|
1081
1334
|
* `rowWidths` are single-line pixel widths of the rendered rows (see
|
|
1082
1335
|
* `measureOptionsGrid`); `gridWidth` is the grid's content width.
|
|
@@ -1236,10 +1489,17 @@ declare function renderEditableContent(args: RenderEditableArgs): void;
|
|
|
1236
1489
|
* When the option list is taller than its scroll box, a small round button
|
|
1237
1490
|
* with a down chevron sits at the bottom-centre of the list. It slides up into
|
|
1238
1491
|
* view from behind the dropdown's lower edge (the footer, when the dropdown
|
|
1239
|
-
* opens below the input) the moment there is more to scroll to,
|
|
1240
|
-
*
|
|
1241
|
-
* click. The reference (the RB2B support panel,
|
|
1242
|
-
* disc that rises from behind the composer over
|
|
1492
|
+
* opens below the input) the moment there is more to scroll to, dissolves in
|
|
1493
|
+
* place once the list is scrolled to its end, and scrolls the list a page on
|
|
1494
|
+
* click. The entrance follows the reference (the RB2B support panel,
|
|
1495
|
+
* 2026-08-19): a white 32 px disc that rises from behind the composer over
|
|
1496
|
+
* ~150–180 ms, no fade. The exit deliberately does not mirror it — sliding
|
|
1497
|
+
* back down read as the disc "falling" into the footer (2026-09-03), so
|
|
1498
|
+
* instead it fades out where it stands, with a slight shrink, over
|
|
1499
|
+
* SCROLL_ARROW_LEAVE_MS. The stylesheets key the two moves off two attributes:
|
|
1500
|
+
* `data-aia-visible` (rise, stay) and `data-aia-leaving` (dissolve), which
|
|
1501
|
+
* this controller holds for the fade's length and then clears, so the disc
|
|
1502
|
+
* re-parks below the edge — invisibly — ready to rise again.
|
|
1243
1503
|
*
|
|
1244
1504
|
* The DOM differs per package (vanilla builds the button here; React and
|
|
1245
1505
|
* Angular render their own markup with the same classes and data attributes),
|
|
@@ -1262,6 +1522,16 @@ declare const SCROLL_ARROW_CLASS = "magicx-aia-scroll-arrow";
|
|
|
1262
1522
|
declare const SCROLL_ARROW_ATTR = "data-aia-scroll-arrow";
|
|
1263
1523
|
/** Present on the button while it is shown. The stylesheets slide it in on this. */
|
|
1264
1524
|
declare const SCROLL_ARROW_VISIBLE_ATTR = "data-aia-visible";
|
|
1525
|
+
/**
|
|
1526
|
+
* Present on the button while it fades out. The stylesheets dissolve it in
|
|
1527
|
+
* place on this; the controller clears it after SCROLL_ARROW_LEAVE_MS.
|
|
1528
|
+
*/
|
|
1529
|
+
declare const SCROLL_ARROW_LEAVING_ATTR = "data-aia-leaving";
|
|
1530
|
+
/**
|
|
1531
|
+
* Length of the fade-out. Mirrors the `[data-aia-leaving]` transition in each
|
|
1532
|
+
* package's stylesheet — change both together.
|
|
1533
|
+
*/
|
|
1534
|
+
declare const SCROLL_ARROW_LEAVE_MS = 240;
|
|
1265
1535
|
/** Inline custom property: how far the button's bottom edge sits above the dropdown's padding edge. */
|
|
1266
1536
|
declare const SCROLL_ARROW_BOTTOM_VAR = "--aia-scroll-arrow-bottom";
|
|
1267
1537
|
declare const SCROLL_ARROW_LABEL = "Scroll down for more options";
|
|
@@ -1420,4 +1690,4 @@ interface SubmitResultExtras {
|
|
|
1420
1690
|
*/
|
|
1421
1691
|
declare function buildSubmitResult(text: string, completedParams: CompletedParamState[], skippedParams?: SkippedParamState[], extras?: SubmitResultExtras): AutocompleteResult;
|
|
1422
1692
|
|
|
1423
|
-
export { AIAutocomplete, type APIConfig, type APIKeyConfig, ATTRIBUTION_URL, type AccessTokenConfig, type AccessTokenResult, type AppearanceMode, type AutocompleteRequest, type AutocompleteResponse, type AutocompleteResult, type CompletedParam, type CompletedParamState, type CoreOptions, type CoreState, type DateMonthView, type FormatType, type IdentifiedParam, type IdentifiedParamState, type InputItem, type LooseDateOptions, ModeController, OPTIONS_GRID_MOBILE_QUERY, OPTION_ENTER_DELAY_VAR, OPTION_ENTER_FADE_MS, OPTION_ENTER_RISE_MS, OPTION_ENTER_RISE_PX, OPTION_ENTER_STAGGER_MS, type OptionOverrides, type OptionsGridLayout, type OptionsGridPlan, PLACEHOLDER_FADE_OUT_MS, PLACEHOLDER_LEAVING_ATTR, PLACEHOLDER_SWAP_GAP_MS, PLACEHOLDER_TYPE_MS, PLACEHOLDER_WORD_PAUSE_MS, type Product, type ProductsConfig, type RecentlySuggested, type RenderMode, SCROLL_ARROW_ATTR, SCROLL_ARROW_BOTTOM_VAR, SCROLL_ARROW_CLASS, SCROLL_ARROW_LABEL, SCROLL_ARROW_VISIBLE_ATTR, SKIPPED_PARAM_TEXT, type ScrollArrowArgs, type ScrollArrowController, type Segment, type SkippedParamState, type Store, type SubmitResultExtras, type Suggestion, type SuggestionOption, type TaskKind, WEEKDAY_LABELS, addMonths, attachScrollArrow, buildAttributionUrl, buildDateOptions, buildQuery, buildSubmitResult, cellDay, cellIso, computeOptionsGridLayout, createStore, cursorIsAtEnd, extractPlainText, formatDate, getCursorOffset, getFooterHint, identifiedParamLabel, isOptionsGridMobileViewport, isoDate, measureOptionsGrid, monthLabel, needsOptionsGridMeasurement, optionEnterDelayMs, optionsEntranceDurationMs, optionsGridTemplateColumns, parseDate, parseLooseDate, plainTextLength, planOptionsGrid, previousGraphemeBoundary, renderEditableContent, resolveFormatType, resolveIdentifiedDate, scrollCaretIntoView, selectedIsoFromText, setCursorOffset, toWireIdentifiedParams, withSkippedParams };
|
|
1693
|
+
export { AIAutocomplete, type APIConfig, type APIKeyConfig, ATTRIBUTION_URL, type AccessTokenConfig, type AccessTokenResult, type AppearanceMode, type AutocompleteRequest, type AutocompleteResponse, type AutocompleteResult, type CompletedParam, type CompletedParamState, type CoreOptions, type CoreState, DATE_RANGE_META_END, DATE_RANGE_META_START, type DateMonthView, type DateRange, type DateSelection, type FormatType, type IdentifiedParam, type IdentifiedParamState, type InputItem, type LooseDateOptions, ModeController, OPTIONS_GRID_MOBILE_QUERY, OPTION_ENTER_DELAY_VAR, OPTION_ENTER_FADE_MS, OPTION_ENTER_RISE_MS, OPTION_ENTER_RISE_PX, OPTION_ENTER_STAGGER_MS, type OptionOverride, type OptionOverrides, type OptionsGridLayout, type OptionsGridPlan, PLACEHOLDER_FADE_OUT_MS, PLACEHOLDER_LEAVING_ATTR, PLACEHOLDER_SWAP_GAP_MS, PLACEHOLDER_TYPE_MS, PLACEHOLDER_WORD_PAUSE_MS, type Product, type ProductsConfig, RANGE_SEPARATOR, type RecentlySuggested, type RenderMode, SCROLL_ARROW_ATTR, SCROLL_ARROW_BOTTOM_VAR, SCROLL_ARROW_CLASS, SCROLL_ARROW_LABEL, SCROLL_ARROW_LEAVE_MS, SCROLL_ARROW_LEAVING_ATTR, SCROLL_ARROW_VISIBLE_ATTR, SKIPPED_PARAM_TEXT, type ScrollArrowArgs, type ScrollArrowController, type Segment, type SkippedParamState, type Store, type SubmitResultExtras, type Suggestion, type SuggestionOption, type TaskKind, WEEKDAY_LABELS, addMonths, attachScrollArrow, buildAttributionUrl, buildDateOptions, buildQuery, buildSubmitResult, cellDay, cellIso, computeOptionsGridLayout, createStore, cursorIsAtEnd, dateCellMarks, dateSelectionFor, extractPlainText, formatAbsoluteDate, formatDate, formatDateRange, getCursorOffset, getFooterHint, identifiedParamLabel, isCalendarFormat, isOptionsGridMobileViewport, isoDate, measureOptionsGrid, monthLabel, needsOptionsGridMeasurement, optionEnterDelayMs, optionsEntranceDurationMs, optionsGridTemplateColumns, parseDate, parseLooseDate, parseLooseDateRange, plainTextLength, planOptionsGrid, previousGraphemeBoundary, renderEditableContent, resolveFormatType, resolveIdentifiedDate, scrollCaretIntoView, selectedIsoFromText, selectedRangeFor, setCursorOffset, toWireIdentifiedParams, visibleDateRange, withSkippedParams };
|