@aceshooting/lyra-ui 17.0.0 → 18.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.
- package/CHANGELOG.md +483 -0
- package/README.md +2 -2
- package/custom-elements.json +1 -1
- package/design-tokens.json +1 -1
- package/dist/cli/migration-contract.json +1 -1
- package/dist/components/conversation/message-actions/message-actions.class.d.ts +2 -1
- package/dist/components/conversation/streaming-text/streaming-text-core.class.d.ts +22 -0
- package/dist/components/conversation/streaming-text/streaming-text-core.class.js +1 -0
- package/dist/components/conversation/streaming-text/streaming-text.class.d.ts +22 -0
- package/dist/components/conversation/streaming-text/streaming-text.class.js +1 -0
- package/dist/components/conversation/thread-list/thread-list.class.js +1 -1
- package/dist/components/data/table/table.styles.js +1 -1
- package/dist/components/forms/combobox/combobox.class.d.ts +12 -2
- package/dist/components/forms/combobox/combobox.class.js +2 -2
- package/dist/components/forms/combobox/combobox.styles.js +1 -1
- package/dist/components/forms/icon-button/icon-button.class.d.ts +18 -9
- package/dist/components/forms/select/select.class.d.ts +63 -8
- package/dist/components/forms/select/select.class.js +4 -4
- package/dist/components/forms/select/select.styles.js +1 -1
- package/dist/components/layout/filter-bar/filter-bar.class.d.ts +148 -14
- package/dist/components/layout/filter-bar/filter-bar.class.js +12 -4
- package/dist/components/layout/filter-bar/filter-bar.styles.js +1 -1
- package/dist/components/layout/reorder-list/reorder-list.class.js +1 -1
- package/dist/components/layout/virtual-list/virtual-list.class.d.ts +154 -18
- package/dist/components/layout/virtual-list/virtual-list.class.js +12 -7
- package/dist/components/media/map/map.class.d.ts +269 -14
- package/dist/components/media/map/map.class.js +62 -30
- package/dist/components/media/map/map.styles.js +1 -1
- package/dist/components/utility/copy-button/copy-button.class.d.ts +4 -3
- package/dist/custom-elements-jsx.d.ts +1 -1
- package/dist/events.d.ts +13 -1
- package/dist/internal/package-metadata.d.ts +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/dist/internal/tokens.styles.js +1 -1
- package/dist/lyra.d.ts +1 -1
- package/dist/lyra.js +1 -1
- package/dist/styles/tokens-root.css +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/testing/lyra-tag-event-map.js +1 -1
- package/dist/translations/ar/retrieval.js +1 -1
- package/dist/translations/ar/shared.js +1 -1
- package/dist/translations/de/retrieval.js +1 -1
- package/dist/translations/de/shared.js +1 -1
- package/dist/translations/es/retrieval.js +1 -1
- package/dist/translations/es/shared.js +1 -1
- package/dist/translations/fa/retrieval.js +1 -1
- package/dist/translations/fa/shared.js +1 -1
- package/dist/translations/fr/retrieval.js +1 -1
- package/dist/translations/fr/shared.js +1 -1
- package/dist/translations/he/retrieval.js +1 -1
- package/dist/translations/he/shared.js +1 -1
- package/dist/translations/it/retrieval.js +1 -1
- package/dist/translations/it/shared.js +1 -1
- package/dist/translations/ja/retrieval.js +1 -1
- package/dist/translations/ja/shared.js +1 -1
- package/dist/translations/pt-BR/retrieval.js +1 -1
- package/dist/translations/pt-BR/shared.js +1 -1
- package/dist/translations/ro/agent-tools.d.ts +1 -0
- package/dist/translations/ro/agent-tools.js +1 -0
- package/dist/translations/ro/charts.d.ts +1 -0
- package/dist/translations/ro/charts.js +1 -0
- package/dist/translations/ro/conversation.d.ts +1 -0
- package/dist/translations/ro/conversation.js +1 -0
- package/dist/translations/ro/data.d.ts +1 -0
- package/dist/translations/ro/data.js +1 -0
- package/dist/translations/ro/forms.d.ts +1 -0
- package/dist/translations/ro/forms.js +1 -0
- package/dist/translations/ro/layout.d.ts +1 -0
- package/dist/translations/ro/layout.js +1 -0
- package/dist/translations/ro/media.d.ts +1 -0
- package/dist/translations/ro/media.js +1 -0
- package/dist/translations/ro/overlays.d.ts +1 -0
- package/dist/translations/ro/overlays.js +1 -0
- package/dist/translations/ro/retrieval.d.ts +1 -0
- package/dist/translations/ro/retrieval.js +1 -0
- package/dist/translations/ro/shared.d.ts +1 -0
- package/dist/translations/ro/shared.js +1 -0
- package/dist/translations/ro/utility.d.ts +1 -0
- package/dist/translations/ro/utility.js +1 -0
- package/dist/translations/ro/viewers.d.ts +1 -0
- package/dist/translations/ro/viewers.js +5 -0
- package/dist/translations/ro.d.ts +1 -0
- package/dist/translations/ro.js +1 -0
- package/dist/translations/ru/retrieval.js +1 -1
- package/dist/translations/ru/shared.js +1 -1
- package/dist/translations/zh-CN/retrieval.js +1 -1
- package/dist/translations/zh-CN/shared.js +1 -1
- package/dist/vue.d.ts +1 -1
- package/llms/components/lr-button.md +5 -4
- package/llms/components/lr-card.md +2 -1
- package/llms/components/lr-combobox.md +11 -0
- package/llms/components/lr-filter-bar.md +123 -7
- package/llms/components/lr-icon-button.md +17 -8
- package/llms/components/lr-map.md +127 -8
- package/llms/components/lr-option.md +11 -0
- package/llms/components/lr-select.md +45 -3
- package/llms/components/lr-streaming-text-core.md +7 -3
- package/llms/components/lr-streaming-text.md +7 -2
- package/llms/components/lr-virtual-list.md +53 -0
- package/llms/shared.md +47 -3
- package/llms/tokens.md +7 -4
- package/llms-full.txt +465 -36
- package/package.json +28 -2
- package/registrations.json +1 -1
- package/vscode-css-data.json +1 -1
- package/vscode-html-data.json +1 -1
- package/web-types.json +1 -1
|
@@ -11,8 +11,10 @@ import type{LyraEventDetailSnapshot}from'../../../internal/lyra-element.js';impo
|
|
|
11
11
|
* toolbar-button shape for a small fixed set of independently togglable categories, with the
|
|
12
12
|
* same `string[]` value a `'combobox'` with `multiple` carries. `'custom'` delegates rendering
|
|
13
13
|
* and event-to-value conversion to the definition's `custom` adapter, so an existing Lyra
|
|
14
|
-
* control can participate without this component growing a branch for every control family.
|
|
15
|
-
|
|
14
|
+
* control can participate without this component growing a branch for every control family.
|
|
15
|
+
* `'chip'` is the one type that maps to no control at all: its value is owned by a widget
|
|
16
|
+
* elsewhere on the page, and this component renders only its active-filter chip. */
|
|
17
|
+
export type LyraFilterBarControlType='select'|'combobox'|'checkbox-menu'|'date'|'date-range'|'text'|'chip'|'custom';
|
|
16
18
|
/** One closed-set choice for a `'select'`/`'combobox'` filter. */
|
|
17
19
|
export interface LyraFilterBarOption{readonly value:string;readonly label:string;
|
|
18
20
|
/** Optional decorative leading visual rendered into the `<lr-option>`'s `start` slot — a status
|
|
@@ -94,9 +96,11 @@ readonly onFocusout:()=>void;}
|
|
|
94
96
|
* inside the filter bar's `filter-control` part and is re-rendered with the current value. */
|
|
95
97
|
export interface LyraFilterBarCustomControl{readonly render:(context:LyraFilterBarCustomControlContext)=>TemplateResult;readonly adapter:LyraFilterBarCustomControlAdapter;}
|
|
96
98
|
/** Whether a filter's `label` renders as the composed control's own visible label -- `'visible'`,
|
|
97
|
-
* the default and the behaviour every definition had before this option existed --
|
|
98
|
-
*
|
|
99
|
-
|
|
99
|
+
* the default and the behaviour every definition had before this option existed -- is routed to
|
|
100
|
+
* that control's accessible name instead (`'hidden'`), for a compact toolbar row, or is
|
|
101
|
+
* `'auto'`: rendered as the visible label while the bar's own allocation is wide enough for it,
|
|
102
|
+
* and visually clipped (never removed, so the name is unchanged) once it is not. */
|
|
103
|
+
export type LyraFilterBarLabelVisibility='visible'|'hidden'|'auto';
|
|
100
104
|
/** Which currently-active filters `render()`'s chip row shows -- see `LyraFilterBar.activeFiltersDisplay`. */
|
|
101
105
|
export type LyraFilterBarActiveFiltersDisplay='all'|'changed'|'hidden';interface LyraFilterBarDefinitionBase{
|
|
102
106
|
/** Stable, unique business identity and the key used in `LyraFilterBarValue`. */
|
|
@@ -123,7 +127,17 @@ readonly icon?:unknown;
|
|
|
123
127
|
* default) or is routed to its accessible name instead (`'hidden'`) -- which also supplies the
|
|
124
128
|
* label as the control's `placeholder` when the definition declares none, so the field still
|
|
125
129
|
* reads as itself with no stacked label above it. The label never simply disappears: routing it
|
|
126
|
-
* is the point, and a filter whose label were dropped would leave the control unnamed.
|
|
130
|
+
* is the point, and a filter whose label were dropped would leave the control unnamed.
|
|
131
|
+
*
|
|
132
|
+
* `'auto'` is the width-dependent middle: the label renders exactly as `'visible'` does --
|
|
133
|
+
* same stacked label element, same accessible name computed from it, no `aria-label` and no
|
|
134
|
+
* placeholder fallback -- and is *visually clipped* by this component's own stylesheet once the
|
|
135
|
+
* bar's own allocation drops below `30rem` (a container query on the host, so it reads the bar's
|
|
136
|
+
* allocated width and not the viewport's). Clipped, never removed: the name comes from the same
|
|
137
|
+
* node at every width, which is exactly what visually hiding `::part(filter-control-label)` from
|
|
138
|
+
* a consumer stylesheet could not achieve. The threshold is fixed rather than themeable -- a
|
|
139
|
+
* container query's prelude cannot read a custom property, so a `--lr-*` hook for it would parse
|
|
140
|
+
* and silently never apply. */
|
|
127
141
|
readonly labelVisibility?:LyraFilterBarLabelVisibility;}
|
|
128
142
|
/** The composed fields whose control also ships a built-in clear action. `'checkbox-menu'` is
|
|
129
143
|
* deliberately absent: its composed `<lr-dropdown>` has no clear affordance of its own, and the
|
|
@@ -207,9 +221,46 @@ readonly presets?:readonly LyraDateRangePreset[];}export interface LyraFilterBar
|
|
|
207
221
|
* debounce left: before this field existed, a custom free-text filter had to hand-roll the same
|
|
208
222
|
* timer plus its flush/cancel lifecycle itself to get the same behaviour. */
|
|
209
223
|
readonly debounce?:number;}
|
|
224
|
+
/** A control-less filter whose value is owned by a widget elsewhere on the page -- a calendar
|
|
225
|
+
* heatmap cell, a map selection, a chart brush. `<lr-filter-bar>` renders NO control for it and it
|
|
226
|
+
* occupies NO toolbar cell, but it is a filter in every other sense this component knows: it lives
|
|
227
|
+
* in `value` under its own `filterId`, rides every `lr-input`/`lr-reset` detail, counts toward
|
|
228
|
+
* `hasActiveFilters` (so it enables the reset button) and `invalidFilterIds`, renders a removable
|
|
229
|
+
* active-filter chip subject to `activeFiltersDisplay`, and is cleared by a chip removal and by
|
|
230
|
+
* `reset()` alongside every other filter.
|
|
231
|
+
*
|
|
232
|
+
* It extends the shared definition base rather than the composed one for the same reason
|
|
233
|
+
* `'custom'` does: `size`/`icon`/`labelVisibility`/`clearable` have no control to be forwarded to,
|
|
234
|
+
* so declaring them would be inert public API. The inherited `placeholder` is likewise inert here
|
|
235
|
+
* (there is no field to place it in), exactly as it already is for `'custom'`. The inherited
|
|
236
|
+
* `required` IS honoured, but only in bookkeeping: a required-but-empty chip filter appears in
|
|
237
|
+
* `invalidFilterIds` and fails `checkValidity()`, while rendering no inline error -- this component
|
|
238
|
+
* renders no element for that filter on which one could appear, so the widget that owns the value
|
|
239
|
+
* owns its error affordance too. The inherited `defaultValue` is
|
|
240
|
+
* restored by `reset()` and compared by `activeFiltersDisplay: 'changed'` like any other type's. */
|
|
241
|
+
export interface LyraFilterBarChipDefinition extends LyraFilterBarDefinitionBase{readonly type:'chip';
|
|
242
|
+
/** The chip's text for the current value. `locale` is `effectiveLocale` -- the same value every
|
|
243
|
+
* built-in type's own chip formatting (`getListFormat`/`getDateTimeFormat`) and a custom
|
|
244
|
+
* adapter's `formatValue` already receive -- because such a value is normally a formatted string
|
|
245
|
+
* (a localized date) rather than a label looked up in an options list. Caller-supplied copy, so
|
|
246
|
+
* (like `label`) this component does not route the result through `this.localize()`; passing the
|
|
247
|
+
* locale is what lets the caller do it. Omitted falls back to the same ladder a custom adapter's
|
|
248
|
+
* omitted `formatValue` uses: a string array formats as a localized conjunction list, any other
|
|
249
|
+
* value renders `String(value)`, and `undefined` renders `''`. */
|
|
250
|
+
readonly formatValue?:(value:LyraFilterBarFieldValue,locale:string)=>string;
|
|
251
|
+
/** The value written when this filter's chip is removed (or `clearFilter()` runs). Defaults to
|
|
252
|
+
* `''`, matching what every non-multi built-in type writes. Declare `[]` for a `string[]`-valued
|
|
253
|
+
* chip filter. A domain sentinel (`'all'`) must be paired with `isEmpty`, or the bar will treat
|
|
254
|
+
* the "cleared" value as still set and keep rendering a chip for it -- the identical pairing
|
|
255
|
+
* `LyraFilterBarCustomControlAdapter.clearValue`/`isEmpty` documents. */
|
|
256
|
+
readonly clearValue?:LyraFilterBarFieldValue;
|
|
257
|
+
/** Optional domain-specific empty predicate. Omitted, this filter uses the same built-in rule
|
|
258
|
+
* every non-`'custom'` type uses: absent, `false`, `''` and `[]` are empty, everything else is
|
|
259
|
+
* set. */
|
|
260
|
+
readonly isEmpty?:(value:LyraFilterBarFieldValue)=>boolean;}
|
|
210
261
|
/** A host-declared filter. The discriminant makes choice options and custom adapters mandatory
|
|
211
262
|
* exactly where runtime needs them, while excluding irrelevant fields from every other mode. */
|
|
212
|
-
export type LyraFilterBarFilterDefinition=LyraFilterBarSelectDefinition|LyraFilterBarComboboxDefinition|LyraFilterBarCheckboxMenuDefinition|LyraFilterBarTextDefinition|LyraFilterBarDateDefinition|LyraFilterBarDateRangeDefinition|LyraFilterBarCustomDefinition;
|
|
263
|
+
export type LyraFilterBarFilterDefinition=LyraFilterBarSelectDefinition|LyraFilterBarComboboxDefinition|LyraFilterBarCheckboxMenuDefinition|LyraFilterBarTextDefinition|LyraFilterBarDateDefinition|LyraFilterBarDateRangeDefinition|LyraFilterBarChipDefinition|LyraFilterBarCustomDefinition;
|
|
213
264
|
/**
|
|
214
265
|
* The whole filter bar's current state: a plain, JSON-serializable object keyed by
|
|
215
266
|
* `LyraFilterBarFilterDefinition.filterId`. This is the entire URL-querystring/app-state serialization
|
|
@@ -226,9 +277,10 @@ export type LyraFilterBarValue=Readonly<Record<string,LyraFilterBarFieldValue>>;
|
|
|
226
277
|
* a `multiple` `'combobox'`) and a `'combobox'` with `multiple: true` narrow to `readonly
|
|
227
278
|
* string[]`; every other `'combobox'` and every `'select'`/`'text'`/`'date'`/`'date-range'` narrow
|
|
228
279
|
* to `string`; a `'custom'` definition keeps the full unconstrained `LyraFilterBarFieldValue`,
|
|
229
|
-
* since its adapter is free to use either boolean meaning (see `LyraFilterBarCustomControlAdapter`)
|
|
280
|
+
* since its adapter is free to use either boolean meaning (see `LyraFilterBarCustomControlAdapter`),
|
|
281
|
+
* and so does a `'chip'` definition, whose value is owned by a widget this component never renders.
|
|
230
282
|
*/
|
|
231
|
-
export type LyraFilterBarDefinitionValue<D extends LyraFilterBarFilterDefinition> =D extends LyraFilterBarCheckboxMenuDefinition?readonly string[]:D extends LyraFilterBarComboboxDefinition?D extends{multiple:true;}?readonly string[]:string:D extends LyraFilterBarCustomDefinition?LyraFilterBarFieldValue:string;
|
|
283
|
+
export type LyraFilterBarDefinitionValue<D extends LyraFilterBarFilterDefinition> =D extends LyraFilterBarCheckboxMenuDefinition?readonly string[]:D extends LyraFilterBarComboboxDefinition?D extends{multiple:true;}?readonly string[]:string:D extends LyraFilterBarCustomDefinition?LyraFilterBarFieldValue:D extends LyraFilterBarChipDefinition?LyraFilterBarFieldValue:string;
|
|
232
284
|
/**
|
|
233
285
|
* `LyraFilterBarValue` narrowed to a keyed record whose per-`filterId` value type follows the
|
|
234
286
|
* matching entry in `Defs` -- the filter-bar analogue of `LyraPickerValue<Multiple>`.
|
|
@@ -324,6 +376,26 @@ export type LyraFilterBarInputEvent<Defs extends readonly LyraFilterBarFilterDef
|
|
|
324
376
|
* button role, so writing one would be silently inert. A revealed `required` error still reaches
|
|
325
377
|
* assistive technology, as a screen-reader-only run inside the trigger's accessible name.
|
|
326
378
|
*
|
|
379
|
+
* A `'chip'` filter is the one type that composes no control at all. Its value is owned by a widget
|
|
380
|
+
* elsewhere on the page -- a calendar heatmap cell, a map selection, a chart brush -- so the bar
|
|
381
|
+
* renders no field for it and it claims no toolbar cell (no `field` wrapper, and therefore no blank
|
|
382
|
+
* column where an empty one's validation spacer would otherwise reserve a row of height). It is a
|
|
383
|
+
* filter in every other sense: it lives in `value` under its own `filterId`, rides every
|
|
384
|
+
* `lr-input`/`lr-reset` detail, counts toward `hasActiveFilters` (so it enables the reset button,
|
|
385
|
+
* which is exactly the "clear all" action an all-chip bar needs) and `invalidFilterIds`, renders a
|
|
386
|
+
* removable active-filter chip subject to `activeFiltersDisplay`, and is cleared by a chip removal
|
|
387
|
+
* and by `reset()` alongside every other filter. Its chip text comes from an optional
|
|
388
|
+
* `formatValue(value, locale)` receiving `effectiveLocale` -- the same locale every built-in type's
|
|
389
|
+
* own chip formatting and a custom adapter's `formatValue` already receive; omitted, a string array
|
|
390
|
+
* formats as a localized conjunction list and anything else renders `String(value)` verbatim, never
|
|
391
|
+
* through the date branch that would reformat an ISO day or mangle a value containing a slash.
|
|
392
|
+
* `clearValue` (default `''`) is what a chip removal writes; a domain sentinel must be paired with
|
|
393
|
+
* `isEmpty`, exactly as a custom adapter's own `clearValue`/`isEmpty` are. Its inherited
|
|
394
|
+
* `placeholder` is inert (there is no field to place it in), as it already is for `'custom'`, and
|
|
395
|
+
* its inherited `required` is honoured in bookkeeping only: a required-but-empty chip filter joins
|
|
396
|
+
* `invalidFilterIds`/`checkValidity()`/`lr-validity-change` but renders no inline error, since this
|
|
397
|
+
* component renders no element of its own on which one could appear.
|
|
398
|
+
*
|
|
327
399
|
* Controlled, like every other Lyra data component: `value` is a plain, JSON-serializable object
|
|
328
400
|
* (`LyraFilterBarValue`) the host reads/writes directly -- this component never touches
|
|
329
401
|
* `location`/`history`/storage itself, so turning `value` into (and back out of) a URL
|
|
@@ -382,7 +454,9 @@ export type LyraFilterBarInputEvent<Defs extends readonly LyraFilterBarFilterDef
|
|
|
382
454
|
* alone) when `filterId` is not a plain CSS ident (ASCII letters/digits/`-`/`_`, starting with a
|
|
383
455
|
* letter) -- `part` is a space-separated token list like `class`, so an id containing whitespace
|
|
384
456
|
* would otherwise silently fabricate an unrelated second token (including, in the worst case,
|
|
385
|
-
* one colliding with a real part name like `active-filters`).
|
|
457
|
+
* one colliding with a real part name like `active-filters`). A `'chip'` filter renders no
|
|
458
|
+
* `field` wrapper at all, so neither `::part(field)` nor `::part(field-<filterId>)` ever matches
|
|
459
|
+
* one -- its only rendered surface is its active-filter `chip`.
|
|
386
460
|
* @csspart end - Wrapper around the `end` slot; hidden while nothing is slotted.
|
|
387
461
|
* @csspart filter-control - One filter's composed built-in control, or the wrapper around a
|
|
388
462
|
* custom renderer's control (and around a `'checkbox-menu'`'s dropdown plus its error line).
|
|
@@ -391,6 +465,10 @@ export type LyraFilterBarInputEvent<Defs extends readonly LyraFilterBarFilterDef
|
|
|
391
465
|
* is visually hidden (never removed) under `labelVisibility: 'hidden'` -- except in the one case
|
|
392
466
|
* where the trigger's selection summary already IS the label (hidden routing, no declared
|
|
393
467
|
* `placeholder`, nothing selected), where it is omitted rather than naming the button twice.
|
|
468
|
+
* Under `labelVisibility: 'auto'` this component clips the same element itself once the bar's own
|
|
469
|
+
* allocation drops below `30rem`, and leaves it untouched above that -- so a consumer rule
|
|
470
|
+
* targeting this part sees a visible element at a wide allocation and a hairline, still-named one
|
|
471
|
+
* at a narrow one.
|
|
394
472
|
* @csspart filter-control-label-group - A `'checkbox-menu'` trigger's composed `<lr-button>`'s own
|
|
395
473
|
* label wrapper: the flex row laying out `filter-control-label` and `filter-control-input`
|
|
396
474
|
* beside each other and, with `with-caret`, growing to fill the stretched trigger so its content
|
|
@@ -466,7 +544,12 @@ loading:boolean;
|
|
|
466
544
|
* than `'changed'`/`'hidden'` (including a foreign attribute value) behaves like `'all'`,
|
|
467
545
|
* matching `labelVisibility`'s own foreign-value handling. Removing a chip always clears that
|
|
468
546
|
* filter, exactly as it always has -- this property only changes which already-active filters
|
|
469
|
-
* get a chip in the row, never what removing one does.
|
|
547
|
+
* get a chip in the row, never what removing one does.
|
|
548
|
+
*
|
|
549
|
+
* `'changed'` additionally gates the reset button on `hasChangedFilters` rather than
|
|
550
|
+
* `hasActiveFilters`, so an untouched defaults-only bar -- which renders no chip in this mode --
|
|
551
|
+
* no longer offers an enabled reset that would change nothing. `hasActiveFilters` itself is
|
|
552
|
+
* unaffected by this property in every mode, and so is reset enablement under `'all'`/`'hidden'`. */
|
|
470
553
|
activeFiltersDisplay:LyraFilterBarActiveFiltersDisplay;
|
|
471
554
|
/** Filters that have been visited (focusout'd) at least once -- gates only the *visual*
|
|
472
555
|
* inline-error presentation on each composed control, matching every other form control in
|
|
@@ -506,9 +589,44 @@ get filters():Defs;set filters(next:Defs|null|undefined);
|
|
|
506
589
|
* the manifest type is pinned here rather than left to the inferred alias name.
|
|
507
590
|
* @type {LyraFilterBarValue} */
|
|
508
591
|
get value():LyraFilterBarValueFor<Defs>;set value(next:LyraFilterBarValueFor<Defs> |null|undefined);private renewSchemaContext;private get schemaSignal();private isEmpty;private valueFor;private normalizeValue;
|
|
509
|
-
/** Whether any filter currently has a value
|
|
510
|
-
*
|
|
592
|
+
/** Whether any filter currently has a value -- including one sitting at its own declared
|
|
593
|
+
* `defaultValue`, which is a value the filter holds like any other. Also what gates whether the
|
|
594
|
+
* `active-filters` chip row renders at all, and the reset button's own disabled state in every
|
|
595
|
+
* `activeFiltersDisplay` mode except `'changed'`, where `hasChangedFilters` gates it instead.
|
|
596
|
+
* This getter itself is unaffected by `activeFiltersDisplay`. */
|
|
511
597
|
get hasActiveFilters():boolean;
|
|
598
|
+
/** Whether one filter's current value differs from its own declared `defaultValue`, using
|
|
599
|
+
* `filterValueEqualsDefault` -- the exact equality `activeFiltersDisplay: 'changed'` already
|
|
600
|
+
* filters its chip row on, not a second comparison.
|
|
601
|
+
*
|
|
602
|
+
* The `defaultIsSet` guard is what keeps a *pristine* filter out of the changed set: a filter
|
|
603
|
+
* declaring no meaningful default has nothing to still equal, so "changed" can only mean "holds
|
|
604
|
+
* a value". Reading that case through the raw equality instead would report a pristine bar as
|
|
605
|
+
* changed whenever a filter's cleared reading is a non-`undefined` sentinel -- a `'chip'`
|
|
606
|
+
* definition's own `clearValue` (`''` by default), or a `'custom'` adapter's. */
|
|
607
|
+
private filterIsChanged;
|
|
608
|
+
/** Whether any filter's value differs from its own declared `defaultValue`. Always live, never
|
|
609
|
+
* cached, exactly like `invalidFilterIds`.
|
|
610
|
+
*
|
|
611
|
+
* This is the counterpart to `hasActiveFilters`, not a synonym: a bar whose every filter sits
|
|
612
|
+
* at a non-empty declared default reads `hasActiveFilters === true` (those defaults are real
|
|
613
|
+
* values, and each one still renders its own chip under `activeFiltersDisplay: 'all'`) and
|
|
614
|
+
* `hasChangedFilters === false` -- a bar whose defaults narrow the view on load does not claim
|
|
615
|
+
* the user narrowed it. A filter with no declared `defaultValue` counts as changed the moment it
|
|
616
|
+
* holds any value at all, since there is nothing for it to still equal; conversely, clearing a
|
|
617
|
+
* filter that *does* declare one counts as changed too, because `reset()` would restore it.
|
|
618
|
+
*
|
|
619
|
+
* It differs from the `'changed'` chip row in exactly that last case: the row only ever
|
|
620
|
+
* considers filters that currently hold a value, so a cleared-but-defaulted filter shows no
|
|
621
|
+
* chip while still reading as changed here. */
|
|
622
|
+
get hasChangedFilters():boolean;
|
|
623
|
+
/** What the reset button's own enablement keys on: whether pressing it would change anything.
|
|
624
|
+
* Under `activeFiltersDisplay: 'changed'` -- the mode whose whole premise is that a value
|
|
625
|
+
* sitting at its own declared default is not something the user applied -- that is
|
|
626
|
+
* `hasChangedFilters`, so an untouched defaults-only bar offers no reset to press (and shows no
|
|
627
|
+
* chip to remove either, which is the state the enabled button used to contradict). Every other
|
|
628
|
+
* mode keeps `hasActiveFilters`, byte for byte what this component has always gated on. */
|
|
629
|
+
private get hasResettableFilters();
|
|
512
630
|
/** Filter ids currently failing their own `required` check -- a filter is invalid only when
|
|
513
631
|
* `required` is set and its value is unset (see `isSet`). Always live, never cached. */
|
|
514
632
|
get invalidFilterIds():readonly string[];
|
|
@@ -592,8 +710,24 @@ private renderOption;
|
|
|
592
710
|
* `labelVisibility`. Hiding the label routes it to the control's own `aria-label` (which every
|
|
593
711
|
* composed control here honours over its computed internal name) and, when the definition
|
|
594
712
|
* declares no `placeholder` of its own, also uses it as the placeholder -- so the field still
|
|
595
|
-
* reads as itself once the stacked label is gone.
|
|
713
|
+
* reads as itself once the stacked label is gone.
|
|
714
|
+
*
|
|
715
|
+
* `'auto'` deliberately resolves to the SAME triple as `'visible'`, not to the hidden branch.
|
|
716
|
+
* Under `'auto'` the visible label element still exists at every width -- the narrow state only
|
|
717
|
+
* clips it visually (see `labelAutoAttribute()`) -- so routing the name onto the control as well
|
|
718
|
+
* would name a wide-allocation field twice, and a *narrow* one twice over too, since the clipped
|
|
719
|
+
* label is still in the accessibility tree. Anything other than `'hidden'` (including a foreign
|
|
720
|
+
* value) therefore keeps the visible routing, matching `activeFiltersDisplay`'s own
|
|
721
|
+
* foreign-value handling. */
|
|
596
722
|
private labelRouting;
|
|
723
|
+
/** Marks a filter's rendered control as label-auto for `filter-bar.styles.ts`'s container query,
|
|
724
|
+
* which is what actually clips the label below the threshold. An attribute rather than a class
|
|
725
|
+
* because the same hook has to be readable from a rule reaching into the composed control's own
|
|
726
|
+
* shadow root -- `[data-label-auto]::part(form-control-label)` -- where a class on the host
|
|
727
|
+
* would work equally well but an attribute matches this component's existing `data-filter-id`
|
|
728
|
+
* marker. Absent for every other `labelVisibility`, so an unset filter renders byte-identical
|
|
729
|
+
* markup to before this option existed. */
|
|
730
|
+
private labelAutoAttribute;
|
|
597
731
|
/** A `'checkbox-menu'` row was activated. The composed `<lr-dropdown-item>` fires this
|
|
598
732
|
* cancelable event with its *proposed* next `checked` state and commits that state itself
|
|
599
733
|
* unless the event is prevented -- so this handler always prevents it and derives the next
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{activeElementIn}from"../../../internal/active-element.js";import{collectFocusableElements,deepActiveElement}from"../../../internal/overlay-manager.js";import{getDateTimeFormat,getListFormat}from"../../../internal/intl-cache.js";import{SlotPresenceController}from"../../../internal/slot-presence-controller.js";import{DebounceController}from"../../../internal/debounce-controller.js";import{srOnly}from"../../../internal/a11y.js";import{styles}from"./filter-bar.styles.js";import{LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_filterBarActiveFilters,LYRA_DEFAULT_filterBarReset}from"../../../internal/default-strings.generated.js";const MAX_FILTER_COLLECTION_ENTRIES=1e4,MAX_FILTER_COLLECTION_NODES=5e4,MAX_FILTER_COLLECTION_DEPTH=16,OMIT_FILTER_VALUE=Symbol("omit-filter-value"),EMPTY_FILTERS=Object.freeze([]),EMPTY_VALUE=Object.freeze({}),EMPTY_DATE_PRESETS=Object.freeze([]);function isPlainFilterRecord(value){try{const prototype=Object.getPrototypeOf(value);return prototype===null||Object.getPrototypeOf(prototype)===null}catch{return!1}}function snapshotFilterEntry(value,budget,depth){if(value===null||typeof value!="object"&&typeof value!="function"||typeof value=="function")return value;if(depth>MAX_FILTER_COLLECTION_DEPTH||budget.remaining<=0)return OMIT_FILTER_VALUE;const existing=budget.seen.get(value);if(existing!==void 0)return existing;let isArray=!1;try{isArray=Array.isArray(value)}catch{return OMIT_FILTER_VALUE}if(isArray){const output2=[];budget.seen.set(value,output2);let length=0;try{const descriptor=Object.getOwnPropertyDescriptor(value,"length");descriptor&&"value"in descriptor&&typeof descriptor.value=="number"&&Number.isSafeInteger(descriptor.value)&&descriptor.value>=0&&(length=Math.min(descriptor.value,MAX_FILTER_COLLECTION_ENTRIES))}catch{return Object.freeze(output2)}for(let index=0;index<length&&budget.remaining>0;index+=1){let descriptor;try{descriptor=Object.getOwnPropertyDescriptor(value,String(index))}catch{continue}if(!descriptor||!("value"in descriptor))continue;budget.remaining-=1;const entry=snapshotFilterEntry(descriptor.value,budget,depth+1);entry!==OMIT_FILTER_VALUE&&output2.push(entry)}return Object.freeze(output2)}if(!isPlainFilterRecord(value))return value;const output={};budget.seen.set(value,output);let descriptors;try{descriptors=Object.getOwnPropertyDescriptors(value)}catch{return OMIT_FILTER_VALUE}let retained=0;for(const key of Reflect.ownKeys(descriptors)){if(retained>=MAX_FILTER_COLLECTION_ENTRIES||budget.remaining<=0)break;const descriptor=descriptors[key];if(!descriptor?.enumerable||!("value"in descriptor))continue;retained+=1,budget.remaining-=1;const entry=key==="icon"?descriptor.value:snapshotFilterEntry(descriptor.value,budget,depth+1);entry!==OMIT_FILTER_VALUE&&Object.defineProperty(output,key,{value:entry,enumerable:!0,configurable:!1,writable:!1})}return Object.freeze(output)}function snapshotFilterDefinitions(value){let isArray=!1;try{isArray=Array.isArray(value)}catch{return EMPTY_FILTERS}return isArray?snapshotFilterEntry(value,{remaining:MAX_FILTER_COLLECTION_NODES,seen:new WeakMap},0):EMPTY_FILTERS}function snapshotFilterFieldValue(value){let isArray=!1;try{isArray=Array.isArray(value)}catch{return}if(!isArray)return typeof value=="string"||typeof value=="boolean"||value===void 0?value:void 0;const output=[];let sourceLength=0;try{const descriptor=Object.getOwnPropertyDescriptor(value,"length");descriptor&&"value"in descriptor&&typeof descriptor.value=="number"&&Number.isSafeInteger(descriptor.value)&&descriptor.value>=0&&(sourceLength=descriptor.value)}catch{return Object.freeze(output)}const length=Math.min(sourceLength,MAX_FILTER_COLLECTION_ENTRIES);for(let index=0;index<length;index+=1){let descriptor;try{descriptor=Object.getOwnPropertyDescriptor(value,String(index))}catch{continue}descriptor&&"value"in descriptor&&typeof descriptor.value=="string"&&output.push(descriptor.value)}return Object.freeze(output)}const SELECT_EXPORT_PARTS=["form-control-label: filter-control-label","trigger: filter-control-field","display-input: filter-control-input","start: filter-control-start","end: filter-control-end","listbox: filter-control-listbox","option: filter-control-option","clear-button: filter-control-clear-button","expand-icon: filter-control-expand-icon","error: filter-control-error","hint: filter-control-hint"].join(", "),COMBOBOX_EXPORT_PARTS=["form-control-label: filter-control-label","combobox: filter-control-field","combobox-input: filter-control-input","start: filter-control-start","end: filter-control-end","listbox: filter-control-listbox","option: filter-control-option","tags: filter-control-tags","tag: filter-control-tag","tag-label: filter-control-tag-label","tag__remove-button: filter-control-tag-remove-button","tag__remove-button__base: filter-control-tag-remove-button-base","clear-button: filter-control-clear-button","expand-icon: filter-control-expand-icon","error: filter-control-error","hint: filter-control-hint"].join(", "),INPUT_EXPORT_PARTS=["form-control-label: filter-control-label","input-wrapper: filter-control-field","input: filter-control-input","start: filter-control-start","end: filter-control-end","clear-button: filter-control-clear-button","error: filter-control-error","hint: filter-control-hint"].join(", "),CHECKBOX_MENU_EXPORT_PARTS=["base: filter-control-listbox"].join(", "),CHECKBOX_MENU_TRIGGER_EXPORT_PARTS=["base: filter-control-field","start: filter-control-start","label: filter-control-label-group","caret: filter-control-expand-icon"].join(", "),DATE_INPUT_EXPORT_PARTS=["form-control-label: filter-control-label","input-wrapper: filter-control-field","input: filter-control-input","start: filter-control-start","end: filter-control-end","clear-button: filter-control-clear-button","expand-button: filter-control-expand-button","expand-icon: filter-control-expand-icon","popup: filter-control-popup","error: filter-control-error","hint: filter-control-hint"].join(", "),SAFE_FILTER_ID_PART=/^[a-zA-Z][a-zA-Z0-9_-]*$/;function fieldPartNames(filterId){return SAFE_FILTER_ID_PART.test(filterId)?`field field-${filterId}`:"field"}function isChoiceDefinition(definition){return definition.type==="select"||definition.type==="combobox"||definition.type==="checkbox-menu"}function isBuiltInSet(value){return value==null?!1:typeof value=="boolean"?value:Array.isArray(value)?value.length>0:value!==""}function filterValueEqualsDefault(value,defaultValue){const valueIsArray=Array.isArray(value),defaultIsArray=Array.isArray(defaultValue);return valueIsArray||defaultIsArray?!valueIsArray||!defaultIsArray?!1:value.length===defaultValue.length&&value.every((entry,index)=>entry===defaultValue[index]):Object.is(value,defaultValue)}function defineFilterValueEntry(record,key,value){Object.defineProperty(record,key,{value,enumerable:!0,configurable:!0,writable:!0})}function cloneFilterValueRecord(value){const clone={},descriptors=Object.getOwnPropertyDescriptors(value);let retained=0;for(const key of Reflect.ownKeys(descriptors)){if(retained>=MAX_FILTER_COLLECTION_ENTRIES)break;const descriptor=descriptors[key];if(typeof key!="string"||!descriptor?.enumerable||!("value"in descriptor))continue;retained+=1;const fieldValue=snapshotFilterFieldValue(descriptor.value);fieldValue!==void 0&&defineFilterValueEntry(clone,key,fieldValue)}return clone}function cloneFilterValue(value){return Object.freeze(cloneFilterValueRecord(value))}class LyraFilterBar extends LyraElement{constructor(){super(...arguments),this.label="",this.disabled=!1,this.loading=!1,this.activeFiltersDisplay="all",this.touchedFilters=new Set,this.slotPresence=new SlotPresenceController(this),this._filters=EMPTY_FILTERS,this._value=EMPTY_VALUE,this.rawValue=EMPTY_VALUE,this.debounceControllers=new Map,this.chipFocusGeneration=0,this.schemaGeneration=0,this.onControlChange=(def,e)=>{const control=e.target;if(def.type==="combobox"&&this.isDebounced(def.debounce)){this.scheduleDebounce(def.filterId,control.value,def.debounce);return}this.setFilterValue(def.filterId,control.value,control.appliedPreset)},this.stopControlAlias=event=>{event.stopPropagation()},this.onCustomControlChange=(def,generation,e)=>{e.stopPropagation();const next=def.custom.adapter.valueFromEvent(e);if(this.isDebounced(def.debounce)){this.scheduleDebounce(def.filterId,next,def.debounce,pending=>this.setCustomContextValue(def,generation,pending));return}this.setCustomContextValue(def,generation,next)}}static{this.defaultStrings={...super.defaultStrings,fieldRequired:LYRA_DEFAULT_fieldRequired,filterBarActiveFilters:LYRA_DEFAULT_filterBarActiveFilters,filterBarReset:LYRA_DEFAULT_filterBarReset}}static{this.styles=[LyraElement.styles,srOnly,styles]}static{this.immutableEventDetails=Object.freeze(["lr-validity-change"])}static{this.properties={filters:{attribute:!1,noAccessor:!0},value:{attribute:!1,noAccessor:!0}}}get filters(){return this._filters}set filters(next){const old=this._filters,widened=next;this.cancelDebounce(),this.renewSchemaContext();const seen=new Set;this._filters=Object.freeze(snapshotFilterDefinitions(widened).filter(definition=>{try{return!definition||typeof definition.filterId!="string"||definition.filterId.length===0||definition.filterId!==definition.filterId.trim()||typeof definition.label!="string"||definition.label.trim().length===0||seen.has(definition.filterId)||isChoiceDefinition(definition)&&!Array.isArray(definition.options)||definition.type==="custom"&&(!definition.custom?.adapter||typeof definition.custom.render!="function")?!1:(seen.add(definition.filterId),!0)}catch{return!1}}).map(definition=>{if(!isChoiceDefinition(definition))return definition;const options=definition.options.filter(option=>{try{return option!==null&&typeof option=="object"&&typeof Object.getOwnPropertyDescriptor(option,"value")?.value=="string"&&typeof Object.getOwnPropertyDescriptor(option,"label")?.value=="string"}catch{return!1}});return Object.freeze({...definition,options:Object.freeze(options)})}));const ids=new Set(this._filters.map(definition=>definition.filterId));this.touchedFilters=new Set([...this.touchedFilters].filter(id=>ids.has(id)));const oldValue=this._value;this._value=this.normalizeValue(this.rawValue),this.requestUpdate("filters",old),this._value!==oldValue&&this.requestUpdate("value",oldValue)}get value(){return cloneFilterValue(this._value)}set value(next){const old=this._value,widened=next;try{this.rawValue=cloneFilterValue(widened??EMPTY_VALUE)}catch{this.rawValue=EMPTY_VALUE}this._value=this.normalizeValue(widened),this.requestUpdate("value",old)}renewSchemaContext(){this.schemaAbortController?.abort();const AbortControllerCtor=this.ownerDocument.defaultView?.AbortController??AbortController;this.schemaAbortController=new AbortControllerCtor,this.schemaGeneration+=1}get schemaSignal(){return this.schemaAbortController||this.renewSchemaContext(),this.schemaAbortController.signal}isEmpty(def,value){if(def.type!=="custom")return!isBuiltInSet(value);const{adapter}=def.custom;if(adapter.isEmpty)return adapter.isEmpty(value);const clear=adapter.clearValue;return Array.isArray(value)&&Array.isArray(clear)?value.length===clear.length&&value.every((entry,index)=>entry===clear[index]):Object.is(value,clear)}valueFor(def){return Object.prototype.hasOwnProperty.call(this._value,def.filterId)?this._value[def.filterId]:def.type==="custom"?def.custom.adapter.clearValue:void 0}normalizeValue(value){const normalized={};for(const def of this._filters){let descriptor;try{descriptor=Object.getOwnPropertyDescriptor(value??{},def.filterId)}catch{continue}if(!descriptor||!("value"in descriptor))continue;const fieldValue=snapshotFilterFieldValue(descriptor.value);this.isEmpty(def,fieldValue)||defineFilterValueEntry(normalized,def.filterId,fieldValue)}return Object.freeze(normalized)}get hasActiveFilters(){return this._filters.some(def=>!this.isEmpty(def,this.valueFor(def)))}get invalidFilterIds(){return Object.freeze(this._filters.filter(def=>def.required&&this.isEmpty(def,this.valueFor(def))).map(def=>def.filterId))}checkValidity(){return this.invalidFilterIds.length===0}reportValidity(){const invalid=this.invalidFilterIds;return invalid.length&&(this.touchedFilters=new Set([...this.touchedFilters,...invalid])),invalid.length===0}reset(){if(this.disabled)return;this.cancelDebounce(),this.touchedFilters=new Set;const self=this;self.value=self.resetValue,self.emit("lr-input",Object.freeze({value:self.value,filterId:void 0,appliedPreset:void 0})),self.emit("lr-reset",Object.freeze({value:self.value}))}get resetValue(){const out={};for(const def of this._filters)if(def.defaultValue!==void 0&&!this.isEmpty(def,def.defaultValue)){const value=Array.isArray(def.defaultValue)?Object.freeze([...def.defaultValue]):def.defaultValue;defineFilterValueEntry(out,def.filterId,value)}return Object.freeze(out)}setFilterValue(id,value,appliedPreset){const definition=this._filters.find(candidate=>candidate.filterId===id);if(this.disabled||!definition)return;const next={...this._value};this.isEmpty(definition,value)?delete next[id]:defineFilterValueEntry(next,id,value);const self=this;self.value=next,self.emit("lr-input",Object.freeze({value:self.value,filterId:id,appliedPreset}))}setCustomContextValue(definition,generation,value){generation!==this.schemaGeneration||this.schemaSignal.aborted||!this.isConnected||!this._filters.includes(definition)||this.setFilterValue(definition.filterId,value)}markTouched(id){this.disabled||this.touchedFilters.has(id)||(this.touchedFilters=new Set(this.touchedFilters).add(id))}isDebounced(delay){return typeof delay=="number"&&Number.isFinite(delay)&&delay>0}scheduleDebounce(id,value,delay,commit=pending=>this.setFilterValue(id,pending)){let controller=this.debounceControllers.get(id);if(!controller){const created=new DebounceController(delay,pending=>{this.debounceControllers.get(id)===created&&this.debounceControllers.delete(id),pending!==void 0&&commit(pending)});controller=created,this.debounceControllers.set(id,created)}controller.delayMs=delay,controller.push(value)}hasPendingDebounce(id){return this.debounceControllers.get(id)?.pending??!1}onTextInput(def,e){if(this.disabled)return;const next=e.target.value??"";if(!this.isDebounced(def.debounce)){this.cancelDebounce(def.filterId),this.setFilterValue(def.filterId,next);return}this.scheduleDebounce(def.filterId,next,def.debounce)}flushDebounce(id){this.debounceControllers.get(id)?.flush()}cancelDebounce(id){for(const[key,controller]of this.debounceControllers)id!==void 0&&key!==id||(controller.dispose(),this.debounceControllers.delete(key))}onFieldFocusout(id){this.flushDebounce(id),this.markTouched(id)}repairFocusAfterChipRemoval(index,filterId,shouldRepairFocus){const generation=++this.chipFocusGeneration;shouldRepairFocus&&this.updateComplete.then(()=>{if(!this.isConnected||this.disabled||generation!==this.chipFocusGeneration||deepActiveElement(this.ownerDocument)!==this.ownerDocument.body)return;const chips=this.renderRoot.querySelectorAll('[part="chip"]'),chip=chips[Math.min(index,chips.length-1)],target=chip?collectFocusableElements(chip)[0]:void 0;if(target){target.focus();return}for(const control of this.renderRoot.querySelectorAll("[data-filter-id]"))if(control.dataset.filterId===filterId){collectFocusableElements(control)[0]?.focus();return}})}clearFilter(id,shouldRepairFocus=!1){if(this.disabled)return;this.cancelDebounce(id);const index=this.activeEntries.findIndex(entry=>entry.def.filterId===id),def=this._filters.find(f=>f.filterId===id);if(!def)return;const clearValue=def.type==="custom"?def.custom.adapter.clearValue:def.type==="checkbox-menu"||def.type==="combobox"&&def.multiple?[]:"";this.setFilterValue(id,clearValue),this.repairFocusAfterChipRemoval(Math.max(0,index),id,shouldRepairFocus)}displayValueFor(def,value){if(def.type==="custom"){const formatted=def.custom?.adapter.formatValue?.(value,this.effectiveLocale);return formatted!==void 0?formatted:Array.isArray(value)?getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format(value):value===void 0?"":String(value)}if(isChoiceDefinition(def)){const labels=(Array.isArray(value)?value.filter(entry=>typeof entry=="string"):typeof value=="string"?[value]:[]).map(v=>def.options?.find(o=>o.value===v)?.label??v);return labels.length>1?getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format(labels):labels[0]??""}if(def.type==="text")return typeof value=="string"?value:"";if(typeof value!="string")return"";const formatter=getDateTimeFormat(this.effectiveLocale,{year:"numeric",month:"short",day:"numeric",timeZone:"UTC"}),parseIso=input=>{const match=/^(\d{4})-(\d{2})-(\d{2})$/.exec(input);if(!match)return;const year=Number(match[1]),month=Number(match[2]),day=Number(match[3]),date=new Date(0);return date.setUTCHours(0,0,0,0),date.setUTCFullYear(year,month-1,day),date.getUTCFullYear()===year&&date.getUTCMonth()===month-1&&date.getUTCDate()===day?date:void 0},segments=value.split("/");if(def.type==="date"&&segments.length!==1||def.type==="date-range"&&segments.length!==2)return value;const[startText,endText]=segments,start=parseIso(startText??""),end=endText===void 0?void 0:parseIso(endText);return!start||endText!==void 0&&(!end||end.getTime()<start.getTime())?value:end?formatter.formatRange(start,end):formatter.format(start)}get activeEntries(){return this.activeFiltersDisplay==="hidden"?[]:this._filters.filter(def=>!this.isEmpty(def,this.valueFor(def))).filter(def=>this.activeFiltersDisplay!=="changed"||!filterValueEqualsDefault(this.valueFor(def),def.defaultValue)).map(def=>({def,display:this.displayValueFor(def,this.valueFor(def))}))}disconnectedCallback(){super.disconnectedCallback(),this.cancelDebounce(),this.closeCheckboxMenus(),this.schemaAbortController?.abort(),this.schemaAbortController=void 0,this.schemaGeneration+=1}closeCheckboxMenus(){for(const menu of this.renderRoot?.querySelectorAll("lr-dropdown[data-filter-id]")??[])menu.open&&(menu.open=!1)}connectedCallback(){super.connectedCallback(),this.hasUpdated&&this.closeCheckboxMenus(),(!this.schemaAbortController||this.schemaAbortController.signal.aborted)&&(this.renewSchemaContext(),this.hasUpdated&&this.requestUpdate()),this.hasUpdated&&queueMicrotask(()=>{this.isConnected&&this.syncTextControls()})}syncTextControls(){if(!this._filters.some(def=>def.type==="text"))return;const fields=new Map;for(const node of this.renderRoot.querySelectorAll("lr-input[data-filter-id]")){const element=node,id=element.dataset.filterId;id!==void 0&&fields.set(id,element)}for(const def of this._filters){if(def.type!=="text"||this.hasPendingDebounce(def.filterId))continue;const field=fields.get(def.filterId);if(!field)continue;const raw=this._value[def.filterId],next=typeof raw=="string"?raw:"";field.value!==next&&(field.value=next)}}willUpdate(changed){super.willUpdate(changed),changed.has("disabled")&&this.disabled&&this.cancelDebounce()}updated(changed){if(super.updated(changed),this.syncTextControls(),changed.has("value")||changed.has("filters")){const invalidFilterIds=this.invalidFilterIds,valid=invalidFilterIds.length===0,key=JSON.stringify({valid,invalidFilterIds});key!==this.lastValidityKey&&(this.lastValidityKey=key,this.emit("lr-validity-change",Object.freeze({valid,invalidFilterIds:Object.freeze([...invalidFilterIds])})))}}renderStartAdornment(icon,slotName="start"){return icon==null?nothing:html`<span slot=${slotName} aria-hidden="true" inert>${icon}</span>`}renderOption(option){return html`<lr-option
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{activeElementIn}from"../../../internal/active-element.js";import{collectFocusableElements,deepActiveElement}from"../../../internal/overlay-manager.js";import{getDateTimeFormat,getListFormat}from"../../../internal/intl-cache.js";import{SlotPresenceController}from"../../../internal/slot-presence-controller.js";import{DebounceController}from"../../../internal/debounce-controller.js";import{srOnly}from"../../../internal/a11y.js";import{styles}from"./filter-bar.styles.js";import{LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_filterBarActiveFilters,LYRA_DEFAULT_filterBarReset}from"../../../internal/default-strings.generated.js";const MAX_FILTER_COLLECTION_ENTRIES=1e4,MAX_FILTER_COLLECTION_NODES=5e4,MAX_FILTER_COLLECTION_DEPTH=16,OMIT_FILTER_VALUE=Symbol("omit-filter-value"),EMPTY_FILTERS=Object.freeze([]),EMPTY_VALUE=Object.freeze({}),EMPTY_DATE_PRESETS=Object.freeze([]);function isPlainFilterRecord(value){try{const prototype=Object.getPrototypeOf(value);return prototype===null||Object.getPrototypeOf(prototype)===null}catch{return!1}}function snapshotFilterEntry(value,budget,depth){if(value===null||typeof value!="object"&&typeof value!="function"||typeof value=="function")return value;if(depth>MAX_FILTER_COLLECTION_DEPTH||budget.remaining<=0)return OMIT_FILTER_VALUE;const existing=budget.seen.get(value);if(existing!==void 0)return existing;let isArray=!1;try{isArray=Array.isArray(value)}catch{return OMIT_FILTER_VALUE}if(isArray){const output2=[];budget.seen.set(value,output2);let length=0;try{const descriptor=Object.getOwnPropertyDescriptor(value,"length");descriptor&&"value"in descriptor&&typeof descriptor.value=="number"&&Number.isSafeInteger(descriptor.value)&&descriptor.value>=0&&(length=Math.min(descriptor.value,MAX_FILTER_COLLECTION_ENTRIES))}catch{return Object.freeze(output2)}for(let index=0;index<length&&budget.remaining>0;index+=1){let descriptor;try{descriptor=Object.getOwnPropertyDescriptor(value,String(index))}catch{continue}if(!descriptor||!("value"in descriptor))continue;budget.remaining-=1;const entry=snapshotFilterEntry(descriptor.value,budget,depth+1);entry!==OMIT_FILTER_VALUE&&output2.push(entry)}return Object.freeze(output2)}if(!isPlainFilterRecord(value))return value;const output={};budget.seen.set(value,output);let descriptors;try{descriptors=Object.getOwnPropertyDescriptors(value)}catch{return OMIT_FILTER_VALUE}let retained=0;for(const key of Reflect.ownKeys(descriptors)){if(retained>=MAX_FILTER_COLLECTION_ENTRIES||budget.remaining<=0)break;const descriptor=descriptors[key];if(!descriptor?.enumerable||!("value"in descriptor))continue;retained+=1,budget.remaining-=1;const entry=key==="icon"?descriptor.value:snapshotFilterEntry(descriptor.value,budget,depth+1);entry!==OMIT_FILTER_VALUE&&Object.defineProperty(output,key,{value:entry,enumerable:!0,configurable:!1,writable:!1})}return Object.freeze(output)}function snapshotFilterDefinitions(value){let isArray=!1;try{isArray=Array.isArray(value)}catch{return EMPTY_FILTERS}return isArray?snapshotFilterEntry(value,{remaining:MAX_FILTER_COLLECTION_NODES,seen:new WeakMap},0):EMPTY_FILTERS}function snapshotFilterFieldValue(value){let isArray=!1;try{isArray=Array.isArray(value)}catch{return}if(!isArray)return typeof value=="string"||typeof value=="boolean"||value===void 0?value:void 0;const output=[];let sourceLength=0;try{const descriptor=Object.getOwnPropertyDescriptor(value,"length");descriptor&&"value"in descriptor&&typeof descriptor.value=="number"&&Number.isSafeInteger(descriptor.value)&&descriptor.value>=0&&(sourceLength=descriptor.value)}catch{return Object.freeze(output)}const length=Math.min(sourceLength,MAX_FILTER_COLLECTION_ENTRIES);for(let index=0;index<length;index+=1){let descriptor;try{descriptor=Object.getOwnPropertyDescriptor(value,String(index))}catch{continue}descriptor&&"value"in descriptor&&typeof descriptor.value=="string"&&output.push(descriptor.value)}return Object.freeze(output)}const SELECT_EXPORT_PARTS=["form-control-label: filter-control-label","trigger: filter-control-field","display-input: filter-control-input","start: filter-control-start","end: filter-control-end","listbox: filter-control-listbox","option: filter-control-option","clear-button: filter-control-clear-button","expand-icon: filter-control-expand-icon","error: filter-control-error","hint: filter-control-hint"].join(", "),COMBOBOX_EXPORT_PARTS=["form-control-label: filter-control-label","combobox: filter-control-field","combobox-input: filter-control-input","start: filter-control-start","end: filter-control-end","listbox: filter-control-listbox","option: filter-control-option","tags: filter-control-tags","tag: filter-control-tag","tag-label: filter-control-tag-label","tag__remove-button: filter-control-tag-remove-button","tag__remove-button__base: filter-control-tag-remove-button-base","clear-button: filter-control-clear-button","expand-icon: filter-control-expand-icon","error: filter-control-error","hint: filter-control-hint"].join(", "),INPUT_EXPORT_PARTS=["form-control-label: filter-control-label","input-wrapper: filter-control-field","input: filter-control-input","start: filter-control-start","end: filter-control-end","clear-button: filter-control-clear-button","error: filter-control-error","hint: filter-control-hint"].join(", "),CHECKBOX_MENU_EXPORT_PARTS=["base: filter-control-listbox"].join(", "),CHECKBOX_MENU_TRIGGER_EXPORT_PARTS=["base: filter-control-field","start: filter-control-start","label: filter-control-label-group","caret: filter-control-expand-icon"].join(", "),DATE_INPUT_EXPORT_PARTS=["form-control-label: filter-control-label","input-wrapper: filter-control-field","input: filter-control-input","start: filter-control-start","end: filter-control-end","clear-button: filter-control-clear-button","expand-button: filter-control-expand-button","expand-icon: filter-control-expand-icon","popup: filter-control-popup","error: filter-control-error","hint: filter-control-hint"].join(", "),SAFE_FILTER_ID_PART=/^[a-zA-Z][a-zA-Z0-9_-]*$/;function fieldPartNames(filterId){return SAFE_FILTER_ID_PART.test(filterId)?`field field-${filterId}`:"field"}function isChoiceDefinition(definition){return definition.type==="select"||definition.type==="combobox"||definition.type==="checkbox-menu"}function isBuiltInSet(value){return value==null?!1:typeof value=="boolean"?value:Array.isArray(value)?value.length>0:value!==""}function filterValueEqualsDefault(value,defaultValue){const valueIsArray=Array.isArray(value),defaultIsArray=Array.isArray(defaultValue);return valueIsArray||defaultIsArray?!valueIsArray||!defaultIsArray?!1:value.length===defaultValue.length&&value.every((entry,index)=>entry===defaultValue[index]):Object.is(value,defaultValue)}function defineFilterValueEntry(record,key,value){Object.defineProperty(record,key,{value,enumerable:!0,configurable:!0,writable:!0})}function cloneFilterValueRecord(value){const clone={},descriptors=Object.getOwnPropertyDescriptors(value);let retained=0;for(const key of Reflect.ownKeys(descriptors)){if(retained>=MAX_FILTER_COLLECTION_ENTRIES)break;const descriptor=descriptors[key];if(typeof key!="string"||!descriptor?.enumerable||!("value"in descriptor))continue;retained+=1;const fieldValue=snapshotFilterFieldValue(descriptor.value);fieldValue!==void 0&&defineFilterValueEntry(clone,key,fieldValue)}return clone}function cloneFilterValue(value){return Object.freeze(cloneFilterValueRecord(value))}class LyraFilterBar extends LyraElement{constructor(){super(...arguments),this.label="",this.disabled=!1,this.loading=!1,this.activeFiltersDisplay="all",this.touchedFilters=new Set,this.slotPresence=new SlotPresenceController(this),this._filters=EMPTY_FILTERS,this._value=EMPTY_VALUE,this.rawValue=EMPTY_VALUE,this.debounceControllers=new Map,this.chipFocusGeneration=0,this.schemaGeneration=0,this.onControlChange=(def,e)=>{const control=e.target;if(def.type==="combobox"&&this.isDebounced(def.debounce)){this.scheduleDebounce(def.filterId,control.value,def.debounce);return}this.setFilterValue(def.filterId,control.value,control.appliedPreset)},this.stopControlAlias=event=>{event.stopPropagation()},this.onCustomControlChange=(def,generation,e)=>{e.stopPropagation();const next=def.custom.adapter.valueFromEvent(e);if(this.isDebounced(def.debounce)){this.scheduleDebounce(def.filterId,next,def.debounce,pending=>this.setCustomContextValue(def,generation,pending));return}this.setCustomContextValue(def,generation,next)}}static{this.defaultStrings={...super.defaultStrings,fieldRequired:LYRA_DEFAULT_fieldRequired,filterBarActiveFilters:LYRA_DEFAULT_filterBarActiveFilters,filterBarReset:LYRA_DEFAULT_filterBarReset}}static{this.styles=[LyraElement.styles,srOnly,styles]}static{this.immutableEventDetails=Object.freeze(["lr-validity-change"])}static{this.properties={filters:{attribute:!1,noAccessor:!0},value:{attribute:!1,noAccessor:!0}}}get filters(){return this._filters}set filters(next){const old=this._filters,widened=next;this.cancelDebounce(),this.renewSchemaContext();const seen=new Set;this._filters=Object.freeze(snapshotFilterDefinitions(widened).filter(definition=>{try{return!definition||typeof definition.filterId!="string"||definition.filterId.length===0||definition.filterId!==definition.filterId.trim()||typeof definition.label!="string"||definition.label.trim().length===0||seen.has(definition.filterId)||isChoiceDefinition(definition)&&!Array.isArray(definition.options)||definition.type==="custom"&&(!definition.custom?.adapter||typeof definition.custom.render!="function")?!1:(seen.add(definition.filterId),!0)}catch{return!1}}).map(definition=>{if(!isChoiceDefinition(definition))return definition;const options=definition.options.filter(option=>{try{return option!==null&&typeof option=="object"&&typeof Object.getOwnPropertyDescriptor(option,"value")?.value=="string"&&typeof Object.getOwnPropertyDescriptor(option,"label")?.value=="string"}catch{return!1}});return Object.freeze({...definition,options:Object.freeze(options)})}));const ids=new Set(this._filters.map(definition=>definition.filterId));this.touchedFilters=new Set([...this.touchedFilters].filter(id=>ids.has(id)));const oldValue=this._value;this._value=this.normalizeValue(this.rawValue),this.requestUpdate("filters",old),this._value!==oldValue&&this.requestUpdate("value",oldValue)}get value(){return cloneFilterValue(this._value)}set value(next){const old=this._value,widened=next;try{this.rawValue=cloneFilterValue(widened??EMPTY_VALUE)}catch{this.rawValue=EMPTY_VALUE}this._value=this.normalizeValue(widened),this.requestUpdate("value",old)}renewSchemaContext(){this.schemaAbortController?.abort();const AbortControllerCtor=this.ownerDocument.defaultView?.AbortController??AbortController;this.schemaAbortController=new AbortControllerCtor,this.schemaGeneration+=1}get schemaSignal(){return this.schemaAbortController||this.renewSchemaContext(),this.schemaAbortController.signal}isEmpty(def,value){if(def.type==="chip")return typeof def.isEmpty=="function"?def.isEmpty(value):!isBuiltInSet(value);if(def.type!=="custom")return!isBuiltInSet(value);const{adapter}=def.custom;if(adapter.isEmpty)return adapter.isEmpty(value);const clear=adapter.clearValue;return Array.isArray(value)&&Array.isArray(clear)?value.length===clear.length&&value.every((entry,index)=>entry===clear[index]):Object.is(value,clear)}valueFor(def){return Object.prototype.hasOwnProperty.call(this._value,def.filterId)?this._value[def.filterId]:def.type==="custom"?def.custom.adapter.clearValue:def.type==="chip"?def.clearValue:void 0}normalizeValue(value){const normalized={};for(const def of this._filters){let descriptor;try{descriptor=Object.getOwnPropertyDescriptor(value??{},def.filterId)}catch{continue}if(!descriptor||!("value"in descriptor))continue;const fieldValue=snapshotFilterFieldValue(descriptor.value);this.isEmpty(def,fieldValue)||defineFilterValueEntry(normalized,def.filterId,fieldValue)}return Object.freeze(normalized)}get hasActiveFilters(){return this._filters.some(def=>!this.isEmpty(def,this.valueFor(def)))}filterIsChanged(def){const value=this.valueFor(def),defaultValue=def.defaultValue;return defaultValue!==void 0&&!this.isEmpty(def,defaultValue)?!filterValueEqualsDefault(value,defaultValue):!this.isEmpty(def,value)}get hasChangedFilters(){return this._filters.some(def=>this.filterIsChanged(def))}get hasResettableFilters(){return this.activeFiltersDisplay==="changed"?this.hasChangedFilters:this.hasActiveFilters}get invalidFilterIds(){return Object.freeze(this._filters.filter(def=>def.required&&this.isEmpty(def,this.valueFor(def))).map(def=>def.filterId))}checkValidity(){return this.invalidFilterIds.length===0}reportValidity(){const invalid=this.invalidFilterIds;return invalid.length&&(this.touchedFilters=new Set([...this.touchedFilters,...invalid])),invalid.length===0}reset(){if(this.disabled)return;this.cancelDebounce(),this.touchedFilters=new Set;const self=this;self.value=self.resetValue,self.emit("lr-input",Object.freeze({value:self.value,filterId:void 0,appliedPreset:void 0})),self.emit("lr-reset",Object.freeze({value:self.value}))}get resetValue(){const out={};for(const def of this._filters)if(def.defaultValue!==void 0&&!this.isEmpty(def,def.defaultValue)){const value=Array.isArray(def.defaultValue)?Object.freeze([...def.defaultValue]):def.defaultValue;defineFilterValueEntry(out,def.filterId,value)}return Object.freeze(out)}setFilterValue(id,value,appliedPreset){const definition=this._filters.find(candidate=>candidate.filterId===id);if(this.disabled||!definition)return;const next={...this._value};this.isEmpty(definition,value)?delete next[id]:defineFilterValueEntry(next,id,value);const self=this;self.value=next,self.emit("lr-input",Object.freeze({value:self.value,filterId:id,appliedPreset}))}setCustomContextValue(definition,generation,value){generation!==this.schemaGeneration||this.schemaSignal.aborted||!this.isConnected||!this._filters.includes(definition)||this.setFilterValue(definition.filterId,value)}markTouched(id){this.disabled||this.touchedFilters.has(id)||(this.touchedFilters=new Set(this.touchedFilters).add(id))}isDebounced(delay){return typeof delay=="number"&&Number.isFinite(delay)&&delay>0}scheduleDebounce(id,value,delay,commit=pending=>this.setFilterValue(id,pending)){let controller=this.debounceControllers.get(id);if(!controller){const created=new DebounceController(delay,pending=>{this.debounceControllers.get(id)===created&&this.debounceControllers.delete(id),pending!==void 0&&commit(pending)});controller=created,this.debounceControllers.set(id,created)}controller.delayMs=delay,controller.push(value)}hasPendingDebounce(id){return this.debounceControllers.get(id)?.pending??!1}onTextInput(def,e){if(this.disabled)return;const next=e.target.value??"";if(!this.isDebounced(def.debounce)){this.cancelDebounce(def.filterId),this.setFilterValue(def.filterId,next);return}this.scheduleDebounce(def.filterId,next,def.debounce)}flushDebounce(id){this.debounceControllers.get(id)?.flush()}cancelDebounce(id){for(const[key,controller]of this.debounceControllers)id!==void 0&&key!==id||(controller.dispose(),this.debounceControllers.delete(key))}onFieldFocusout(id){this.flushDebounce(id),this.markTouched(id)}repairFocusAfterChipRemoval(index,filterId,shouldRepairFocus){const generation=++this.chipFocusGeneration;shouldRepairFocus&&this.updateComplete.then(()=>{if(!this.isConnected||this.disabled||generation!==this.chipFocusGeneration||deepActiveElement(this.ownerDocument)!==this.ownerDocument.body)return;const chips=this.renderRoot.querySelectorAll('[part="chip"]'),chip=chips[Math.min(index,chips.length-1)],target=chip?collectFocusableElements(chip)[0]:void 0;if(target){target.focus();return}for(const control of this.renderRoot.querySelectorAll("[data-filter-id]"))if(control.dataset.filterId===filterId){collectFocusableElements(control)[0]?.focus();return}})}clearFilter(id,shouldRepairFocus=!1){if(this.disabled)return;this.cancelDebounce(id);const index=this.activeEntries.findIndex(entry=>entry.def.filterId===id),def=this._filters.find(f=>f.filterId===id);if(!def)return;const clearValue=def.type==="custom"?def.custom.adapter.clearValue:def.type==="chip"?def.clearValue??"":def.type==="checkbox-menu"||def.type==="combobox"&&def.multiple?[]:"";this.setFilterValue(id,clearValue),this.repairFocusAfterChipRemoval(Math.max(0,index),id,shouldRepairFocus)}displayValueFor(def,value){if(def.type==="custom"){const formatted=def.custom?.adapter.formatValue?.(value,this.effectiveLocale);return formatted!==void 0?formatted:Array.isArray(value)?getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format(value):value===void 0?"":String(value)}if(def.type==="chip"){const formatted=typeof def.formatValue=="function"?def.formatValue(value,this.effectiveLocale):void 0;return formatted!==void 0?formatted:Array.isArray(value)?getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format(value):value===void 0?"":String(value)}if(isChoiceDefinition(def)){const labels=(Array.isArray(value)?value.filter(entry=>typeof entry=="string"):typeof value=="string"?[value]:[]).map(v=>def.options?.find(o=>o.value===v)?.label??v);return labels.length>1?getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format(labels):labels[0]??""}if(def.type==="text")return typeof value=="string"?value:"";if(typeof value!="string")return"";const formatter=getDateTimeFormat(this.effectiveLocale,{year:"numeric",month:"short",day:"numeric",timeZone:"UTC"}),parseIso=input=>{const match=/^(\d{4})-(\d{2})-(\d{2})$/.exec(input);if(!match)return;const year=Number(match[1]),month=Number(match[2]),day=Number(match[3]),date=new Date(0);return date.setUTCHours(0,0,0,0),date.setUTCFullYear(year,month-1,day),date.getUTCFullYear()===year&&date.getUTCMonth()===month-1&&date.getUTCDate()===day?date:void 0},segments=value.split("/");if(def.type==="date"&&segments.length!==1||def.type==="date-range"&&segments.length!==2)return value;const[startText,endText]=segments,start=parseIso(startText??""),end=endText===void 0?void 0:parseIso(endText);return!start||endText!==void 0&&(!end||end.getTime()<start.getTime())?value:end?formatter.formatRange(start,end):formatter.format(start)}get activeEntries(){return this.activeFiltersDisplay==="hidden"?[]:this._filters.filter(def=>!this.isEmpty(def,this.valueFor(def))).filter(def=>this.activeFiltersDisplay!=="changed"||!filterValueEqualsDefault(this.valueFor(def),def.defaultValue)).map(def=>({def,display:this.displayValueFor(def,this.valueFor(def))}))}disconnectedCallback(){super.disconnectedCallback(),this.cancelDebounce(),this.closeCheckboxMenus(),this.schemaAbortController?.abort(),this.schemaAbortController=void 0,this.schemaGeneration+=1}closeCheckboxMenus(){for(const menu of this.renderRoot?.querySelectorAll("lr-dropdown[data-filter-id]")??[])menu.open&&(menu.open=!1)}connectedCallback(){super.connectedCallback(),this.hasUpdated&&this.closeCheckboxMenus(),(!this.schemaAbortController||this.schemaAbortController.signal.aborted)&&(this.renewSchemaContext(),this.hasUpdated&&this.requestUpdate()),this.hasUpdated&&queueMicrotask(()=>{this.isConnected&&this.syncTextControls()})}syncTextControls(){if(!this._filters.some(def=>def.type==="text"))return;const fields=new Map;for(const node of this.renderRoot.querySelectorAll("lr-input[data-filter-id]")){const element=node,id=element.dataset.filterId;id!==void 0&&fields.set(id,element)}for(const def of this._filters){if(def.type!=="text"||this.hasPendingDebounce(def.filterId))continue;const field=fields.get(def.filterId);if(!field)continue;const raw=this._value[def.filterId],next=typeof raw=="string"?raw:"";field.value!==next&&(field.value=next)}}willUpdate(changed){super.willUpdate(changed),changed.has("disabled")&&this.disabled&&this.cancelDebounce()}updated(changed){if(super.updated(changed),this.syncTextControls(),changed.has("value")||changed.has("filters")){const invalidFilterIds=this.invalidFilterIds,valid=invalidFilterIds.length===0,key=JSON.stringify({valid,invalidFilterIds});key!==this.lastValidityKey&&(this.lastValidityKey=key,this.emit("lr-validity-change",Object.freeze({valid,invalidFilterIds:Object.freeze([...invalidFilterIds])})))}}renderStartAdornment(icon,slotName="start"){return icon==null?nothing:html`<span slot=${slotName} aria-hidden="true" inert>${icon}</span>`}renderOption(option){return html`<lr-option
|
|
2
2
|
value=${option.value}
|
|
3
3
|
search-text=${option.searchText??nothing}
|
|
4
4
|
?disabled=${option.disabled===!0}
|
|
5
5
|
>${this.renderStartAdornment(option.icon)}${option.label}</lr-option
|
|
6
|
-
>`}labelRouting(def){const hidden=def.labelVisibility==="hidden";return{label:hidden?"":def.label,placeholder:def.placeholder||(hidden?def.label:""),accessibleLabel:hidden?def.label:nothing}}onCheckboxMenuToggle(def,event){if(event.stopPropagation(),event.preventDefault(),this.disabled)return;const detail=event.detail,current=this.valueFor(def),selected=Array.isArray(current)?current.filter(entry=>typeof entry=="string"):[],next=detail.checked?selected.includes(detail.value)?selected:[...selected,detail.value]:selected.filter(entry=>entry!==detail.value);this.setFilterValue(def.filterId,Object.freeze(next))}renderCheckboxMenu(def,value,errorText){const selected=Array.isArray(value)?value.filter(entry=>typeof entry=="string"):[],size=def.size??"m",routing=this.labelRouting(def),summary=selected.length>0?this.displayValueFor(def,value):routing.placeholder,showLabel=def.labelVisibility!=="hidden"||summary!==def.label;return html`<div
|
|
6
|
+
>`}labelRouting(def){const hidden=def.labelVisibility==="hidden";return{label:hidden?"":def.label,placeholder:def.placeholder||(hidden?def.label:""),accessibleLabel:hidden?def.label:nothing}}labelAutoAttribute(def){return def.labelVisibility==="auto"}onCheckboxMenuToggle(def,event){if(event.stopPropagation(),event.preventDefault(),this.disabled)return;const detail=event.detail,current=this.valueFor(def),selected=Array.isArray(current)?current.filter(entry=>typeof entry=="string"):[],next=detail.checked?selected.includes(detail.value)?selected:[...selected,detail.value]:selected.filter(entry=>entry!==detail.value);this.setFilterValue(def.filterId,Object.freeze(next))}renderCheckboxMenu(def,value,errorText){const selected=Array.isArray(value)?value.filter(entry=>typeof entry=="string"):[],size=def.size??"m",routing=this.labelRouting(def),summary=selected.length>0?this.displayValueFor(def,value):routing.placeholder,showLabel=def.labelVisibility!=="hidden"||summary!==def.label;return html`<div
|
|
7
|
+
part="filter-control"
|
|
8
|
+
class="checkbox-menu"
|
|
9
|
+
?data-label-auto=${this.labelAutoAttribute(def)}
|
|
10
|
+
>
|
|
7
11
|
<lr-dropdown
|
|
8
12
|
exportparts=${CHECKBOX_MENU_EXPORT_PARTS}
|
|
9
13
|
data-filter-id=${def.filterId}
|
|
@@ -47,6 +51,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
47
51
|
part="filter-control"
|
|
48
52
|
exportparts=${COMBOBOX_EXPORT_PARTS}
|
|
49
53
|
data-filter-id=${def.filterId}
|
|
54
|
+
?data-label-auto=${this.labelAutoAttribute(def)}
|
|
50
55
|
.label=${routing.label}
|
|
51
56
|
aria-label=${routing.accessibleLabel}
|
|
52
57
|
placeholder=${routing.placeholder}
|
|
@@ -68,6 +73,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
68
73
|
part="filter-control"
|
|
69
74
|
exportparts=${INPUT_EXPORT_PARTS}
|
|
70
75
|
data-filter-id=${def.filterId}
|
|
76
|
+
?data-label-auto=${this.labelAutoAttribute(def)}
|
|
71
77
|
type=${def.inputType??"text"}
|
|
72
78
|
.label=${routing.label}
|
|
73
79
|
aria-label=${routing.accessibleLabel}
|
|
@@ -85,6 +91,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
85
91
|
part="filter-control"
|
|
86
92
|
exportparts=${DATE_INPUT_EXPORT_PARTS}
|
|
87
93
|
data-filter-id=${def.filterId}
|
|
94
|
+
?data-label-auto=${this.labelAutoAttribute(def)}
|
|
88
95
|
.label=${routing.label}
|
|
89
96
|
aria-label=${routing.accessibleLabel}
|
|
90
97
|
placeholder=${routing.placeholder}
|
|
@@ -107,6 +114,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
107
114
|
part="filter-control"
|
|
108
115
|
exportparts=${SELECT_EXPORT_PARTS}
|
|
109
116
|
data-filter-id=${def.filterId}
|
|
117
|
+
?data-label-auto=${this.labelAutoAttribute(def)}
|
|
110
118
|
.label=${routing.label}
|
|
111
119
|
aria-label=${routing.accessibleLabel}
|
|
112
120
|
placeholder=${routing.placeholder}
|
|
@@ -125,7 +133,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
125
133
|
>`}rendersValidationError(def){return!!def.required&&this.touchedFilters.has(def.filterId)&&this.isEmpty(def,this.valueFor(def))}render(){const accessibleLabel=this.hasAttribute("aria-label")?this.getAttribute("aria-label"):this.label||nothing,active=this.activeEntries;return html`
|
|
126
134
|
<div part="base" role="group" aria-label=${accessibleLabel}>
|
|
127
135
|
<div part="controls">
|
|
128
|
-
${this._filters.map(def=>html`<div part=${fieldPartNames(def.filterId)}>
|
|
136
|
+
${this._filters.filter(def=>def.type!=="chip").map(def=>html`<div part=${fieldPartNames(def.filterId)}>
|
|
129
137
|
${this.renderControl(def)}
|
|
130
138
|
<span
|
|
131
139
|
class="validation-spacer"
|
|
@@ -137,7 +145,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
137
145
|
<lr-button
|
|
138
146
|
part="reset-button"
|
|
139
147
|
appearance="quiet"
|
|
140
|
-
?disabled=${this.disabled||this.loading||!this.
|
|
148
|
+
?disabled=${this.disabled||this.loading||!this.hasResettableFilters}
|
|
141
149
|
@click=${()=>this.reset()}
|
|
142
150
|
>
|
|
143
151
|
${this.localize("filterBarReset")}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{css}from"lit";import{srOnly}from"../../../internal/a11y.js";const styles=css` ${srOnly} :host { display: block; min-inline-size: 0; max-inline-size: 100%; } [part='base'] { display: flex; flex-direction: column; gap: var(--lr-space-s); min-inline-size: 0; max-inline-size: 100%; } [part='controls'] { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--lr-filter-bar-gap, var(--lr-space-s)); min-inline-size: 0; max-inline-size: 100%; } [part~='field'] { flex: 1 1 var(--lr-filter-bar-field-basis, var(--lr-size-12rem)); min-inline-size: 0; max-inline-size: 100%; } [part='end'] { flex: 0 0 auto; } [part='filter-control'] { inline-size: 100%; min-inline-size: 0; max-inline-size: 100%; } .checkbox-menu { display: flex; flex-direction: column; min-inline-size: 0; max-inline-size: 100%; } .checkbox-menu lr-dropdown::part(trigger) { display: block; min-inline-size: 0; } .checkbox-menu lr-button { inline-size: 100%; min-inline-size: 0; } .checkbox-menu lr-button::part(label) { display: flex; align-items: baseline; gap: var(--lr-space-xs); min-inline-size: 0; } .checkbox-menu [part='filter-control-label'], .checkbox-menu [part='filter-control-input'] { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .checkbox-menu [part='filter-control-error'] { margin-block-start: var(--lr-space-xs); font-size: var(--lr-font-size-sm); color: var(--lr-color-danger); min-inline-size: 0; max-inline-size: 100%; overflow-wrap: anywhere; } .validation-spacer { display: block; block-size: var(--lr-size-1-5rem); } .validation-spacer[hidden] { display: none; } .reset-field { flex: 0 0 auto; } [part='status'] { flex: 0 0 auto; } [part='active-filters'] { display: flex; flex-wrap: wrap; align-items: center; gap: var(--lr-space-xs); min-inline-size: 0; max-inline-size: 100%; } [part='chips'] { flex: 1 1 auto; min-inline-size: 0; max-inline-size: 100%; inline-size: 100%; } [part='chip'] { min-inline-size: 0; max-inline-size: 100%; } :host([disabled]) [part='chip'] { opacity: var(--lr-opacity-disabled); } `;export{styles};
|
|
1
|
+
import{css}from"lit";import{srOnly}from"../../../internal/a11y.js";const styles=css` ${srOnly} :host { display: block; container-type: inline-size; contain-intrinsic-inline-size: var(--lr-size-20rem); min-inline-size: 0; max-inline-size: 100%; } [part='base'] { display: flex; flex-direction: column; gap: var(--lr-space-s); min-inline-size: 0; max-inline-size: 100%; } [part='controls'] { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--lr-filter-bar-gap, var(--lr-space-s)); min-inline-size: 0; max-inline-size: 100%; } [part~='field'] { flex: 1 1 var(--lr-filter-bar-field-basis, var(--lr-size-12rem)); min-inline-size: 0; max-inline-size: 100%; } [part='end'] { flex: 0 0 auto; } [part='filter-control'] { inline-size: 100%; min-inline-size: 0; max-inline-size: 100%; } .checkbox-menu { display: flex; flex-direction: column; min-inline-size: 0; max-inline-size: 100%; } .checkbox-menu lr-dropdown::part(trigger) { display: block; min-inline-size: 0; } .checkbox-menu lr-button { inline-size: 100%; min-inline-size: 0; } .checkbox-menu lr-button::part(label) { display: flex; align-items: baseline; gap: var(--lr-space-xs); min-inline-size: 0; } .checkbox-menu [part='filter-control-label'], .checkbox-menu [part='filter-control-input'] { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .checkbox-menu [part='filter-control-error'] { margin-block-start: var(--lr-space-xs); font-size: var(--lr-font-size-sm); color: var(--lr-color-danger); min-inline-size: 0; max-inline-size: 100%; overflow-wrap: anywhere; } .validation-spacer { display: block; block-size: var(--lr-size-1-5rem); } .validation-spacer[hidden] { display: none; } .reset-field { flex: 0 0 auto; } [part='status'] { flex: 0 0 auto; } [part='active-filters'] { display: flex; flex-wrap: wrap; align-items: center; gap: var(--lr-space-xs); min-inline-size: 0; max-inline-size: 100%; } [part='chips'] { flex: 1 1 auto; min-inline-size: 0; max-inline-size: 100%; inline-size: 100%; } [part='chip'] { min-inline-size: 0; max-inline-size: 100%; } :host([disabled]) [part='chip'] { opacity: var(--lr-opacity-disabled); } @container (max-inline-size: 30rem) { [data-label-auto]::part(form-control-label), [data-label-auto] [part='filter-control-label'] { position: absolute; inline-size: var(--lr-size-1px); block-size: var(--lr-size-1px); padding: 0; margin-inline: calc(-1 * var(--lr-size-1px)); margin-block: calc(-1 * var(--lr-size-1px)); overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; } } `;export{styles};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,query}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{tag}from"../../../internal/prefix.js";import{hostAriaLabel}from"../../../internal/a11y.js";import{releaseReorderOwnerState,reorderIdentityChange,updateReorderOwnerState}from"./reorder-owner.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{styles}from"./reorder-list.styles.js";import{LYRA_DEFAULT_reorderItemMoved,LYRA_DEFAULT_reorderMoveCancelled,LYRA_DEFAULT_reorderMovePending}from"../../../internal/default-strings.generated.js";class LyraReorderList extends LyraElement{constructor(){super(...arguments),this.label="",this.disabled=!1,this.controlled=!1,this.pendingFocusTarget=null,this.focusRestoreGeneration=0,this.stateItems=new Set,this.moveToken=0,this.pendingMove=null,this.pendingReconciliation=null,this.onSlotChange=()=>{this.pendingMove&&this.pendingMove.phase==="held"&&!this.pendingMembershipIsCurrent()&&this.revertPendingMove(),this.pendingReconciliation&&this.tryCompleteControlledReconciliation(),this.syncBoundaryState()},this.onMoveRequest=e=>{const item=e.target?.closest?.(tag("reorder-item"));if(!item||item.parentElement!==this)return;const{direction}=e.detail;e.stopPropagation(),this.moveItem(item,direction)},this.onKeyDown=e=>{if(!(e.ctrlKey||e.metaKey)||e.altKey||e.shiftKey||e.key!=="ArrowUp"&&e.key!=="ArrowDown")return;const path=e.composedPath(),item=path.find(target=>target instanceof Element&&target.localName===tag("reorder-item")&&target.parentElement===this);if(!item)return;const itemIndex=path.indexOf(item);if(path.slice(0,itemIndex).some(target=>{if(!(target instanceof Element)||target.getRootNode()===item.shadowRoot)return!1;const name=target.localName;return name==="a"||name==="button"||name==="input"||name==="select"||name==="textarea"||target.hasAttribute("contenteditable")||name.includes("-")&&target!==item}))return;const items=this.itemElements,fromIndex=items.indexOf(item),toIndex=e.key==="ArrowDown"?fromIndex+1:fromIndex-1;this.disabled||this.pendingMove||this.pendingReconciliation||item.disabled||fromIndex<0||toIndex<0||toIndex>=items.length||(e.preventDefault(),this.moveItem(item,e.key==="ArrowDown"?"down":"up"))}}static{this.defaultStrings={...super.defaultStrings,reorderItemMoved:LYRA_DEFAULT_reorderItemMoved,reorderMoveCancelled:LYRA_DEFAULT_reorderMoveCancelled,reorderMovePending:LYRA_DEFAULT_reorderMovePending}}static{this.styles=[LyraElement.styles,styles]}static{this.immutableEventDetails=Object.freeze(["lr-reorder"])}get directItemElements(){const itemTag=tag("reorder-item");return[...this.children].filter(element=>element.localName===itemTag)}get itemElements(){const seen=new Set;return this.directItemElements.filter(item=>{const value=item.value;return typeof value!="string"||value.trim()===""||seen.has(value)?!1:(seen.add(value),!0)})}syncBoundaryState(){const directItems=this.directItemElements,items=this.itemElements,validItems=new Set(items),heldMove=this.pendingMove?.phase==="held",reconciliation=this.pendingReconciliation,busy=heldMove||reconciliation!==null,nextStateItems=new Set(directItems);for(const item of this.stateItems)nextStateItems.has(item)||releaseReorderOwnerState(item,this);directItems.forEach(item=>{const i=items.indexOf(item);updateReorderOwnerState(item,this,{atStart:i===0,atEnd:i>=0&&i===items.length-1,listDisabled:this.disabled,pending:heldMove&&this.pendingMove?.item===item||reconciliation!==null&&item.value===reconciliation.value,busy,validIdentity:validItems.has(item)})}),this.stateItems=nextStateItems,this.requestUpdate()}tryCompleteControlledReconciliation(){const reconciliation=this.pendingReconciliation;if(!reconciliation)return;const items=this.itemElements,currentValues=items.map(entry=>entry.value);if(!(currentValues.length===reconciliation.expectedValues.length&¤tValues.every((value,index)=>value===reconciliation.expectedValues[index]))){currentValues.includes(reconciliation.value)||(this.pendingReconciliation=null);return}const movedItem=items[reconciliation.toIndex];this.pendingReconciliation=null,movedItem&&this.finishMove(movedItem,reconciliation.direction,reconciliation.toIndex)}[reorderIdentityChange](item){item.parentElement===this&&this.onSlotChange()}refreshItemObserver(){this.itemObserver?.disconnect();const Observer=this.ownerDocument.defaultView?.MutationObserver;!Observer||!this.isConnected||(this.itemObserver=new Observer(()=>this.onSlotChange()),this.itemObserver.observe(this,{attributes:!0,childList:!0,attributeFilter:["disabled","value"]}))}pendingMembershipIsCurrent(){if(!this.pendingMove)return!1;const current=this.itemElements;return!this.disabled&&!this.pendingMove.item.disabled&&!this.pendingMove.target.disabled&¤t.length===this.pendingMove.members.length&¤t.every((item,index)=>item===this.pendingMove.members[index]&&item.value===this.pendingMove.values[index])&¤t[this.pendingMove.toIndex]===this.pendingMove.target}connectedCallback(){super.connectedCallback(),this.refreshItemObserver(),this.syncBoundaryState()}willUpdate(changed){super.willUpdate(changed),changed.has("disabled")&&this.syncBoundaryState(),changed.has("controlled")&&this.pendingReconciliation&&(this.pendingReconciliation=null,this.syncBoundaryState())}disconnectedCallback(){this.itemObserver?.disconnect(),this.itemObserver=void 0,this.pendingFocusTarget=null,this.focusRestoreGeneration+=1,this.pendingMove=null,this.pendingReconciliation=null,this.moveToken+=1;for(const item of this.stateItems)releaseReorderOwnerState(item,this);this.stateItems.clear(),super.disconnectedCallback()}orderValues(items){return Object.freeze(items.map(item=>item.value))}scheduleFocusRestore(){this.scheduleAfterUpdate(()=>{const focusTarget=this.pendingFocusTarget;focusTarget&&this.restoreFocusAfterItemUpdate(focusTarget,this.focusRestoreGeneration)},"reorder-focus")}async restoreFocusAfterItemUpdate(focusTarget,generation){await focusTarget.item.updateComplete,!(!this.isConnected||generation!==this.focusRestoreGeneration||this.pendingFocusTarget!==focusTarget)&&(this.pendingFocusTarget=null,focusTarget.item.focusMoveButton(focusTarget.direction))}applyMove(item,direction,_fromIndex,toIndex){const target=this.itemElements[toIndex];direction==="up"?this.insertBefore(item,target):this.insertBefore(item,target.nextElementSibling),this.finishMove(item,direction,toIndex)}finishMove(item,direction,toIndex){this.syncBoundaryState();const focusDirection=(direction==="up"?item.atStart:item.atEnd)?direction==="up"?"down":"up":direction;this.pendingFocusTarget={item,direction:focusDirection},this.focusRestoreGeneration+=1,this.scheduleFocusRestore();const newItems=this.itemElements,number=getNumberFormat(this.effectiveLocale);this.liveRegion?.announce(this.localize("reorderItemMoved",void 0,{index:number.format(toIndex+1),total:number.format(newItems.length)}),{force:!0})}commitMove(item,direction,fromIndex,toIndex,expectedValues){this.controlled?(this.pendingReconciliation={value:item.value,direction,toIndex,expectedValues},this.syncBoundaryState()):this.applyMove(item,direction,fromIndex,toIndex)}moveItem(item,direction){if(this.disabled||item.disabled||this.pendingMove||this.pendingReconciliation)return;const items=this.itemElements,fromIndex=items.indexOf(item);if(fromIndex<0)return;const toIndex=direction==="up"?fromIndex-1:fromIndex+1;if(toIndex<0||toIndex>=items.length)return;const reordered=items.slice();reordered.splice(fromIndex,1),reordered.splice(toIndex,0,item);const expectedValues=this.orderValues(reordered),transaction={token:++this.moveToken,phase:"dispatching",resolution:null,item,target:items[toIndex],direction,fromIndex,toIndex,members:[...items],values:items.map(member=>member.value),expectedValues};this.pendingMove=transaction;const event=this.emit("lr-reorder",Object.freeze({order:expectedValues,fromIndex,toIndex}),{cancelable:!0});if(!(this.pendingMove!==transaction||transaction.token!==this.moveToken)){if(!this.pendingMembershipIsCurrent()){this.pendingMove=null,this.syncBoundaryState();return}if(event.defaultPrevented){if(transaction.resolution==="revert"){this.pendingMove=null,this.syncBoundaryState();return}if(transaction.resolution==="finalize"){this.pendingMove=null,this.syncBoundaryState(),this.commitMove(item,direction,fromIndex,toIndex,expectedValues);return}this.pendingMove={...transaction,phase:"held"},this.syncBoundaryState(),this.liveRegion?.announce(this.localize("reorderMovePending"),{force:!0});return}this.pendingMove=null,this.syncBoundaryState(),this.commitMove(item,direction,fromIndex,toIndex,expectedValues)}}finalizePendingMove(){if(!this.pendingMove)return;if(this.pendingMove.phase==="dispatching"){this.pendingMove.resolution="finalize";return}if(!this.pendingMembershipIsCurrent()){this.revertPendingMove();return}const{item,direction,fromIndex,toIndex,expectedValues}=this.pendingMove;this.pendingMove=null,this.syncBoundaryState(),this.commitMove(item,direction,fromIndex,toIndex,expectedValues)}revertPendingMove(options){if(!this.pendingMove)return;if(this.pendingMove.phase==="dispatching"){this.pendingMove.resolution="revert";return}const wasHeld=this.pendingMove.phase==="held";this.pendingMove=null,this.syncBoundaryState(),wasHeld&&!(options?.silent??!1)&&this.liveRegion?.announce(this.localize("reorderMoveCancelled"),{force:!0})}render(){return html`
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,query}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{tag}from"../../../internal/prefix.js";import{hostAriaLabel}from"../../../internal/a11y.js";import{releaseReorderOwnerState,reorderIdentityChange,updateReorderOwnerState}from"./reorder-owner.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{styles}from"./reorder-list.styles.js";import{LYRA_DEFAULT_reorderItemMoved,LYRA_DEFAULT_reorderMoveCancelled,LYRA_DEFAULT_reorderMovePending}from"../../../internal/default-strings.generated.js";function isRowOwnChrome(node,item){let root=node.getRootNode();for(;root instanceof ShadowRoot;){if(root===item.shadowRoot)return!0;root=root.host.getRootNode()}return!1}function deepActiveElement(doc){let active=doc.activeElement;for(;active?.shadowRoot?.activeElement;)active=active.shadowRoot.activeElement;return active}function composedContains(root,node){let current=node;for(;current;){if(current instanceof Element&&root.contains(current))return!0;current=current instanceof ShadowRoot?current.host:current.parentNode}return!1}class LyraReorderList extends LyraElement{constructor(){super(...arguments),this.label="",this.disabled=!1,this.controlled=!1,this.pendingFocusTarget=null,this.focusRestoreGeneration=0,this.stateItems=new Set,this.moveToken=0,this.pendingMove=null,this.pendingReconciliation=null,this.onSlotChange=()=>{this.pendingMove&&this.pendingMove.phase==="held"&&!this.pendingMembershipIsCurrent()&&this.revertPendingMove(),this.pendingReconciliation&&this.tryCompleteControlledReconciliation(),this.syncBoundaryState()},this.onMoveRequest=e=>{const item=e.target?.closest?.(tag("reorder-item"));if(!item||item.parentElement!==this)return;const{direction}=e.detail;e.stopPropagation(),this.moveItem(item,direction)},this.onKeyDown=e=>{if(!(e.ctrlKey||e.metaKey)||e.altKey||e.shiftKey||e.key!=="ArrowUp"&&e.key!=="ArrowDown")return;const path=e.composedPath(),item=path.find(target=>target instanceof Element&&target.localName===tag("reorder-item")&&target.parentElement===this);if(!item)return;const itemIndex=path.indexOf(item);if(path.slice(0,itemIndex).some(target=>{if(!(target instanceof Element)||isRowOwnChrome(target,item))return!1;const name=target.localName;return name==="a"||name==="button"||name==="input"||name==="select"||name==="textarea"||target.hasAttribute("contenteditable")||name.includes("-")&&target!==item}))return;const items=this.itemElements,fromIndex=items.indexOf(item),toIndex=e.key==="ArrowDown"?fromIndex+1:fromIndex-1;this.disabled||this.pendingMove||this.pendingReconciliation||item.disabled||fromIndex<0||toIndex<0||toIndex>=items.length||(e.preventDefault(),this.moveItem(item,e.key==="ArrowDown"?"down":"up"))}}static{this.defaultStrings={...super.defaultStrings,reorderItemMoved:LYRA_DEFAULT_reorderItemMoved,reorderMoveCancelled:LYRA_DEFAULT_reorderMoveCancelled,reorderMovePending:LYRA_DEFAULT_reorderMovePending}}static{this.styles=[LyraElement.styles,styles]}static{this.immutableEventDetails=Object.freeze(["lr-reorder"])}get directItemElements(){const itemTag=tag("reorder-item");return[...this.children].filter(element=>element.localName===itemTag)}get itemElements(){const seen=new Set;return this.directItemElements.filter(item=>{const value=item.value;return typeof value!="string"||value.trim()===""||seen.has(value)?!1:(seen.add(value),!0)})}syncBoundaryState(){const directItems=this.directItemElements,items=this.itemElements,validItems=new Set(items),heldMove=this.pendingMove?.phase==="held",reconciliation=this.pendingReconciliation,busy=heldMove||reconciliation!==null,nextStateItems=new Set(directItems);for(const item of this.stateItems)nextStateItems.has(item)||releaseReorderOwnerState(item,this);directItems.forEach(item=>{const i=items.indexOf(item);updateReorderOwnerState(item,this,{atStart:i===0,atEnd:i>=0&&i===items.length-1,listDisabled:this.disabled,pending:heldMove&&this.pendingMove?.item===item||reconciliation!==null&&item.value===reconciliation.value,busy,validIdentity:validItems.has(item)})}),this.stateItems=nextStateItems,this.requestUpdate()}tryCompleteControlledReconciliation(){const reconciliation=this.pendingReconciliation;if(!reconciliation)return;const items=this.itemElements,currentValues=items.map(entry=>entry.value);if(!(currentValues.length===reconciliation.expectedValues.length&¤tValues.every((value,index)=>value===reconciliation.expectedValues[index]))){currentValues.includes(reconciliation.value)||(this.pendingReconciliation=null);return}const movedItem=items[reconciliation.toIndex];this.pendingReconciliation=null,movedItem&&this.finishMove(movedItem,reconciliation.direction,reconciliation.toIndex)}[reorderIdentityChange](item){item.parentElement===this&&this.onSlotChange()}refreshItemObserver(){this.itemObserver?.disconnect();const Observer=this.ownerDocument.defaultView?.MutationObserver;!Observer||!this.isConnected||(this.itemObserver=new Observer(()=>this.onSlotChange()),this.itemObserver.observe(this,{attributes:!0,childList:!0,attributeFilter:["disabled","value"]}))}pendingMembershipIsCurrent(){if(!this.pendingMove)return!1;const current=this.itemElements;return!this.disabled&&!this.pendingMove.item.disabled&&!this.pendingMove.target.disabled&¤t.length===this.pendingMove.members.length&¤t.every((item,index)=>item===this.pendingMove.members[index]&&item.value===this.pendingMove.values[index])&¤t[this.pendingMove.toIndex]===this.pendingMove.target}connectedCallback(){super.connectedCallback(),this.refreshItemObserver(),this.syncBoundaryState()}willUpdate(changed){super.willUpdate(changed),changed.has("disabled")&&this.syncBoundaryState(),changed.has("controlled")&&this.pendingReconciliation&&(this.pendingReconciliation=null,this.syncBoundaryState())}disconnectedCallback(){this.itemObserver?.disconnect(),this.itemObserver=void 0,this.pendingFocusTarget=null,this.focusRestoreGeneration+=1,this.pendingMove=null,this.pendingReconciliation=null,this.moveToken+=1;for(const item of this.stateItems)releaseReorderOwnerState(item,this);this.stateItems.clear(),super.disconnectedCallback()}orderValues(items){return Object.freeze(items.map(item=>item.value))}scheduleFocusRestore(){this.scheduleAfterUpdate(()=>{const focusTarget=this.pendingFocusTarget;focusTarget&&this.restoreFocusAfterItemUpdate(focusTarget,this.focusRestoreGeneration)},"reorder-focus")}async restoreFocusAfterItemUpdate(focusTarget,generation){if(await focusTarget.item.updateComplete,!this.isConnected||generation!==this.focusRestoreGeneration||this.pendingFocusTarget!==focusTarget)return;this.pendingFocusTarget=null;const captured=focusTarget.preScheduleFocus;captured!=null&&captured!==this.ownerDocument.body&&captured.isConnected&&!composedContains(this,captured)||focusTarget.item.focusMoveButton(focusTarget.direction)}applyMove(item,direction,_fromIndex,toIndex){const target=this.itemElements[toIndex];direction==="up"?this.insertBefore(item,target):this.insertBefore(item,target.nextElementSibling),this.finishMove(item,direction,toIndex)}finishMove(item,direction,toIndex){this.syncBoundaryState();const focusDirection=(direction==="up"?item.atStart:item.atEnd)?direction==="up"?"down":"up":direction;this.pendingFocusTarget={item,direction:focusDirection,preScheduleFocus:deepActiveElement(this.ownerDocument)},this.focusRestoreGeneration+=1,this.scheduleFocusRestore();const newItems=this.itemElements,number=getNumberFormat(this.effectiveLocale);this.liveRegion?.announce(this.localize("reorderItemMoved",void 0,{index:number.format(toIndex+1),total:number.format(newItems.length)}),{force:!0})}commitMove(item,direction,fromIndex,toIndex,expectedValues){this.controlled?(this.pendingReconciliation={value:item.value,direction,toIndex,expectedValues},this.syncBoundaryState()):this.applyMove(item,direction,fromIndex,toIndex)}moveItem(item,direction){if(this.disabled||item.disabled||this.pendingMove||this.pendingReconciliation)return;const items=this.itemElements,fromIndex=items.indexOf(item);if(fromIndex<0)return;const toIndex=direction==="up"?fromIndex-1:fromIndex+1;if(toIndex<0||toIndex>=items.length)return;const reordered=items.slice();reordered.splice(fromIndex,1),reordered.splice(toIndex,0,item);const expectedValues=this.orderValues(reordered),transaction={token:++this.moveToken,phase:"dispatching",resolution:null,item,target:items[toIndex],direction,fromIndex,toIndex,members:[...items],values:items.map(member=>member.value),expectedValues};this.pendingMove=transaction;const event=this.emit("lr-reorder",Object.freeze({order:expectedValues,fromIndex,toIndex}),{cancelable:!0});if(!(this.pendingMove!==transaction||transaction.token!==this.moveToken)){if(!this.pendingMembershipIsCurrent()){this.pendingMove=null,this.syncBoundaryState();return}if(event.defaultPrevented){if(transaction.resolution==="revert"){this.pendingMove=null,this.syncBoundaryState();return}if(transaction.resolution==="finalize"){this.pendingMove=null,this.syncBoundaryState(),this.commitMove(item,direction,fromIndex,toIndex,expectedValues);return}this.pendingMove={...transaction,phase:"held"},this.syncBoundaryState(),this.liveRegion?.announce(this.localize("reorderMovePending"),{force:!0});return}this.pendingMove=null,this.syncBoundaryState(),this.commitMove(item,direction,fromIndex,toIndex,expectedValues)}}finalizePendingMove(){if(!this.pendingMove)return;if(this.pendingMove.phase==="dispatching"){this.pendingMove.resolution="finalize";return}if(!this.pendingMembershipIsCurrent()){this.revertPendingMove();return}const{item,direction,fromIndex,toIndex,expectedValues}=this.pendingMove;this.pendingMove=null,this.syncBoundaryState(),this.commitMove(item,direction,fromIndex,toIndex,expectedValues)}revertPendingMove(options){if(!this.pendingMove)return;if(this.pendingMove.phase==="dispatching"){this.pendingMove.resolution="revert";return}const wasHeld=this.pendingMove.phase==="held";this.pendingMove=null,this.syncBoundaryState(),wasHeld&&!(options?.silent??!1)&&this.liveRegion?.announce(this.localize("reorderMoveCancelled"),{force:!0})}render(){return html`
|
|
2
2
|
<div
|
|
3
3
|
part="base"
|
|
4
4
|
role="list"
|