@bluevolt-tech/lumen 2.2.0 → 2.3.1
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/dist/components/_shared/dropdown-controller.d.ts +16 -0
- package/dist/components/bv-date-range-input/bv-date-range-input.js +39 -2
- package/dist/components/bv-date-range-picker/bv-date-range-picker.d.ts +1 -0
- package/dist/components/bv-date-range-picker/bv-date-range-picker.js +31 -0
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +8 -2
- package/dist/components/bv-input-dropdown/bv-input-dropdown.js +8 -2
- package/dist/components/bv-pagination/bv-pagination.d.ts +3 -1
- package/dist/components/bv-pagination/bv-pagination.js +11 -3
- package/dist/components/bv-search-picker/bv-search-picker.d.ts +231 -0
- package/dist/components/bv-search-picker/bv-search-picker.js +1489 -0
- package/dist/components/bv-segmented-control/bv-segmented-control.d.ts +7 -1
- package/dist/components/bv-segmented-control/bv-segmented-control.js +21 -2
- package/dist/components/bv-select/bv-select.js +8 -2
- package/dist/components/bv-split-button/bv-split-button.js +8 -2
- package/dist/components/bv-table/bv-table.d.ts +28 -0
- package/dist/components/bv-table/bv-table.js +274 -58
- package/dist/storybook/stories/screens/cet-report.data.d.ts +0 -1
- package/dist/storybook/stories/screens/cet-report.data.js +810 -49
- package/dist/themes/base.css +1 -1
- package/package.json +5 -1
- package/themes/base.css +1 -1
|
@@ -50,6 +50,22 @@ export interface DropdownController {
|
|
|
50
50
|
* the state. The controller is the single source of truth; consuming
|
|
51
51
|
* components must NOT duplicate this sync in their own attributeChangedCallback.
|
|
52
52
|
* - `bv-open` is dispatched from the host when opening via `open()`/`toggle()`.
|
|
53
|
+
* - `bv-dropdown-close` is dispatched from the host on every successful close,
|
|
54
|
+
* with `detail: { reason }` matching the `CloseReason` union — consumers can
|
|
55
|
+
* use it to close sibling dropdowns or release focus/scroll locks. The name
|
|
56
|
+
* is prefixed to avoid colliding with `bv-modal` / `bv-course-detail-modal`,
|
|
57
|
+
* which dispatch a bare `bv-close` on dismissal — a plain `bv-close` here
|
|
58
|
+
* would bubble into ancestor `bv-close` listeners (e.g. a modal that
|
|
59
|
+
* contains a dropdown) and fire spuriously on every dropdown dismissal.
|
|
60
|
+
*
|
|
61
|
+
* **Consumers MUST NOT call `e.stopPropagation()` on the trigger click**
|
|
62
|
+
* (BTN-10408). The outside-click listener attached here on `document` uses
|
|
63
|
+
* `composedPath().includes(host)` to skip clicks that originated inside its
|
|
64
|
+
* own host — so it already ignores the trigger click without needing the
|
|
65
|
+
* event to be swallowed. Stopping propagation on the trigger prevents the
|
|
66
|
+
* `document`-level listeners attached by *sibling* controllers from
|
|
67
|
+
* receiving the click at all, which is why opening one dropdown while
|
|
68
|
+
* another is open used to leave both visible.
|
|
53
69
|
*
|
|
54
70
|
* The controller mutates the `open` attribute on the host. Consumers should
|
|
55
71
|
* drive their visual state (`.panel` visibility, focus management) from that
|
|
@@ -42,6 +42,13 @@ function bindDropdownController(host, options = {}) {
|
|
|
42
42
|
if (options.canClose && !options.canClose(reason)) return;
|
|
43
43
|
host.removeAttribute("open");
|
|
44
44
|
syncExpanded();
|
|
45
|
+
host.dispatchEvent(
|
|
46
|
+
new CustomEvent("bv-dropdown-close", {
|
|
47
|
+
bubbles: true,
|
|
48
|
+
composed: true,
|
|
49
|
+
detail: { reason }
|
|
50
|
+
})
|
|
51
|
+
);
|
|
45
52
|
(_a = options.onAfterClose) == null ? void 0 : _a.call(options);
|
|
46
53
|
};
|
|
47
54
|
const close = () => closeWithReason("programmatic");
|
|
@@ -549,12 +556,43 @@ var BvDateRangePicker = class extends HTMLElement {
|
|
|
549
556
|
if (name === "preset") this._preset = val ?? "";
|
|
550
557
|
if (!this._rendered) return;
|
|
551
558
|
if (name === "start" || name === "end" || name === "preset") {
|
|
559
|
+
this._maybeRepositionView();
|
|
552
560
|
this._syncCalendars();
|
|
553
561
|
this._syncInputs();
|
|
554
562
|
this._syncPresets();
|
|
555
563
|
}
|
|
556
564
|
this._syncValidity();
|
|
557
565
|
}
|
|
566
|
+
// Hoist the left panel to the anchor's month, but ONLY when *neither*
|
|
567
|
+
// endpoint of the current start/end pair is already in the visible pair.
|
|
568
|
+
// Checking both endpoints matters after manual navigation: if the user
|
|
569
|
+
// scrolled far from `_start` and the consumer only touches `_end`, the
|
|
570
|
+
// change may land inside the visible pair even though `_start` is well
|
|
571
|
+
// out of view — the guard must keep the user's navigation intact in
|
|
572
|
+
// that case. The anchor for the actual reposition still prefers
|
|
573
|
+
// `_start` (fallback to `_end`) so common consumer updates that write
|
|
574
|
+
// both fields converge to the start's month. See BTN-10755 in
|
|
575
|
+
// `attributeChangedCallback` for the flow context. Returns silently on
|
|
576
|
+
// empty / malformed values — the sync pass afterwards can still render
|
|
577
|
+
// the cleared selection over the current view without a jump.
|
|
578
|
+
_maybeRepositionView() {
|
|
579
|
+
const anchor = this._start || this._end;
|
|
580
|
+
if (!anchor) return;
|
|
581
|
+
const parseYearMonth = (s2) => {
|
|
582
|
+
const dt = parseIso(s2);
|
|
583
|
+
if (!dt) return null;
|
|
584
|
+
return { y: dt.getFullYear(), m: dt.getMonth() };
|
|
585
|
+
};
|
|
586
|
+
const right = this._getRightMonth();
|
|
587
|
+
const isVisible = (y, m) => y === this._leftYear && m === this._leftMonth || y === right.year && m === right.month;
|
|
588
|
+
const s = this._start ? parseYearMonth(this._start) : null;
|
|
589
|
+
const e = this._end ? parseYearMonth(this._end) : null;
|
|
590
|
+
if (s && isVisible(s.y, s.m) || e && isVisible(e.y, e.m)) return;
|
|
591
|
+
const target = parseYearMonth(anchor);
|
|
592
|
+
if (!target) return;
|
|
593
|
+
this._leftYear = target.y;
|
|
594
|
+
this._leftMonth = target.m;
|
|
595
|
+
}
|
|
558
596
|
/**
|
|
559
597
|
* BTN-10312 — public reset of the picker's internal draft state to the
|
|
560
598
|
* currently committed `start` / `end` / `preset` attributes. Called by
|
|
@@ -1303,9 +1341,8 @@ var BvDateRangeInput = class extends HTMLElement {
|
|
|
1303
1341
|
icon.className = "trigger-icon";
|
|
1304
1342
|
icon.innerHTML = CALENDAR_ICON;
|
|
1305
1343
|
trigger.append(display, icon);
|
|
1306
|
-
trigger.addEventListener("click", (
|
|
1344
|
+
trigger.addEventListener("click", () => {
|
|
1307
1345
|
var _a;
|
|
1308
|
-
e.stopPropagation();
|
|
1309
1346
|
(_a = this._dropdown) == null ? void 0 : _a.toggle();
|
|
1310
1347
|
});
|
|
1311
1348
|
const popup = document.createElement("div");
|
|
@@ -51,6 +51,7 @@ export declare class BvDateRangePicker extends HTMLElement {
|
|
|
51
51
|
set preset(v: string);
|
|
52
52
|
connectedCallback(): void;
|
|
53
53
|
attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
|
|
54
|
+
private _maybeRepositionView;
|
|
54
55
|
/**
|
|
55
56
|
* BTN-10312 — public reset of the picker's internal draft state to the
|
|
56
57
|
* currently committed `start` / `end` / `preset` attributes. Called by
|
|
@@ -495,12 +495,43 @@ var BvDateRangePicker = class extends HTMLElement {
|
|
|
495
495
|
if (name === "preset") this._preset = val ?? "";
|
|
496
496
|
if (!this._rendered) return;
|
|
497
497
|
if (name === "start" || name === "end" || name === "preset") {
|
|
498
|
+
this._maybeRepositionView();
|
|
498
499
|
this._syncCalendars();
|
|
499
500
|
this._syncInputs();
|
|
500
501
|
this._syncPresets();
|
|
501
502
|
}
|
|
502
503
|
this._syncValidity();
|
|
503
504
|
}
|
|
505
|
+
// Hoist the left panel to the anchor's month, but ONLY when *neither*
|
|
506
|
+
// endpoint of the current start/end pair is already in the visible pair.
|
|
507
|
+
// Checking both endpoints matters after manual navigation: if the user
|
|
508
|
+
// scrolled far from `_start` and the consumer only touches `_end`, the
|
|
509
|
+
// change may land inside the visible pair even though `_start` is well
|
|
510
|
+
// out of view — the guard must keep the user's navigation intact in
|
|
511
|
+
// that case. The anchor for the actual reposition still prefers
|
|
512
|
+
// `_start` (fallback to `_end`) so common consumer updates that write
|
|
513
|
+
// both fields converge to the start's month. See BTN-10755 in
|
|
514
|
+
// `attributeChangedCallback` for the flow context. Returns silently on
|
|
515
|
+
// empty / malformed values — the sync pass afterwards can still render
|
|
516
|
+
// the cleared selection over the current view without a jump.
|
|
517
|
+
_maybeRepositionView() {
|
|
518
|
+
const anchor = this._start || this._end;
|
|
519
|
+
if (!anchor) return;
|
|
520
|
+
const parseYearMonth = (s2) => {
|
|
521
|
+
const dt = parseIso(s2);
|
|
522
|
+
if (!dt) return null;
|
|
523
|
+
return { y: dt.getFullYear(), m: dt.getMonth() };
|
|
524
|
+
};
|
|
525
|
+
const right = this._getRightMonth();
|
|
526
|
+
const isVisible = (y, m) => y === this._leftYear && m === this._leftMonth || y === right.year && m === right.month;
|
|
527
|
+
const s = this._start ? parseYearMonth(this._start) : null;
|
|
528
|
+
const e = this._end ? parseYearMonth(this._end) : null;
|
|
529
|
+
if (s && isVisible(s.y, s.m) || e && isVisible(e.y, e.m)) return;
|
|
530
|
+
const target = parseYearMonth(anchor);
|
|
531
|
+
if (!target) return;
|
|
532
|
+
this._leftYear = target.y;
|
|
533
|
+
this._leftMonth = target.m;
|
|
534
|
+
}
|
|
504
535
|
/**
|
|
505
536
|
* BTN-10312 — public reset of the picker's internal draft state to the
|
|
506
537
|
* currently committed `start` / `end` / `preset` attributes. Called by
|
|
@@ -42,6 +42,13 @@ function bindDropdownController(host, options = {}) {
|
|
|
42
42
|
if (options.canClose && !options.canClose(reason)) return;
|
|
43
43
|
host.removeAttribute("open");
|
|
44
44
|
syncExpanded();
|
|
45
|
+
host.dispatchEvent(
|
|
46
|
+
new CustomEvent("bv-dropdown-close", {
|
|
47
|
+
bubbles: true,
|
|
48
|
+
composed: true,
|
|
49
|
+
detail: { reason }
|
|
50
|
+
})
|
|
51
|
+
);
|
|
45
52
|
(_a = options.onAfterClose) == null ? void 0 : _a.call(options);
|
|
46
53
|
};
|
|
47
54
|
const close = () => closeWithReason("programmatic");
|
|
@@ -187,9 +194,8 @@ var BvFilterDropdown = class extends HTMLElement {
|
|
|
187
194
|
chevron.className = "trigger-chevron";
|
|
188
195
|
chevron.innerHTML = CHEVRON_DOWN;
|
|
189
196
|
trigger.append(label, chevron);
|
|
190
|
-
trigger.addEventListener("click", (
|
|
197
|
+
trigger.addEventListener("click", () => {
|
|
191
198
|
var _a;
|
|
192
|
-
e.stopPropagation();
|
|
193
199
|
if (this.disabled) return;
|
|
194
200
|
(_a = this._dropdown) == null ? void 0 : _a.toggle();
|
|
195
201
|
});
|
|
@@ -42,6 +42,13 @@ function bindDropdownController(host, options = {}) {
|
|
|
42
42
|
if (options.canClose && !options.canClose(reason)) return;
|
|
43
43
|
host.removeAttribute("open");
|
|
44
44
|
syncExpanded();
|
|
45
|
+
host.dispatchEvent(
|
|
46
|
+
new CustomEvent("bv-dropdown-close", {
|
|
47
|
+
bubbles: true,
|
|
48
|
+
composed: true,
|
|
49
|
+
detail: { reason }
|
|
50
|
+
})
|
|
51
|
+
);
|
|
45
52
|
(_a = options.onAfterClose) == null ? void 0 : _a.call(options);
|
|
46
53
|
};
|
|
47
54
|
const close = () => closeWithReason("programmatic");
|
|
@@ -343,9 +350,8 @@ var BvInputDropdown = class extends HTMLElement {
|
|
|
343
350
|
trigger.setAttribute("aria-haspopup", "listbox");
|
|
344
351
|
trigger.setAttribute("aria-expanded", "false");
|
|
345
352
|
trigger.setAttribute("part", "trigger");
|
|
346
|
-
trigger.addEventListener("click", (
|
|
353
|
+
trigger.addEventListener("click", () => {
|
|
347
354
|
var _a;
|
|
348
|
-
e.stopPropagation();
|
|
349
355
|
if (!this.disabled) (_a = this._dropdown) == null ? void 0 : _a.toggle();
|
|
350
356
|
});
|
|
351
357
|
const triggerLabel = document.createElement("span");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare class BvPagination extends HTMLElement {
|
|
2
|
-
static readonly observedAttributes: readonly ["page", "total-pages", "total", "page-size", "siblings", "show-results", "show-page-size", "page-size-options", "compact"];
|
|
2
|
+
static readonly observedAttributes: readonly ["page", "total-pages", "total", "page-size", "siblings", "show-results", "show-page-size", "page-size-options", "compact", "hide-range"];
|
|
3
3
|
private _rendered;
|
|
4
4
|
private _metaEl;
|
|
5
5
|
private _pagesEl;
|
|
@@ -24,6 +24,8 @@ export declare class BvPagination extends HTMLElement {
|
|
|
24
24
|
set showPageSize(v: boolean);
|
|
25
25
|
get compact(): boolean;
|
|
26
26
|
set compact(v: boolean);
|
|
27
|
+
get hideRange(): boolean;
|
|
28
|
+
set hideRange(v: boolean);
|
|
27
29
|
get pageSizeOptions(): number[];
|
|
28
30
|
private _go;
|
|
29
31
|
private _render;
|
|
@@ -32,7 +32,8 @@ var BvPagination = class extends HTMLElement {
|
|
|
32
32
|
"show-results",
|
|
33
33
|
"show-page-size",
|
|
34
34
|
"page-size-options",
|
|
35
|
-
"compact"
|
|
35
|
+
"compact",
|
|
36
|
+
"hide-range"
|
|
36
37
|
];
|
|
37
38
|
_rendered = false;
|
|
38
39
|
_metaEl = null;
|
|
@@ -90,6 +91,13 @@ var BvPagination = class extends HTMLElement {
|
|
|
90
91
|
if (v) this.setAttribute("compact", "");
|
|
91
92
|
else this.removeAttribute("compact");
|
|
92
93
|
}
|
|
94
|
+
get hideRange() {
|
|
95
|
+
return this.hasAttribute("hide-range");
|
|
96
|
+
}
|
|
97
|
+
set hideRange(v) {
|
|
98
|
+
if (v) this.setAttribute("hide-range", "");
|
|
99
|
+
else this.removeAttribute("hide-range");
|
|
100
|
+
}
|
|
93
101
|
get pageSizeOptions() {
|
|
94
102
|
const raw = this.getAttribute("page-size-options") ?? "10,25,50,100";
|
|
95
103
|
return raw.split(",").map((v) => parseInt(v.trim(), 10)).filter((v) => !isNaN(v));
|
|
@@ -169,7 +177,7 @@ var BvPagination = class extends HTMLElement {
|
|
|
169
177
|
this._update();
|
|
170
178
|
}
|
|
171
179
|
_update() {
|
|
172
|
-
const { page, totalPages, total, pageSize, siblings, compact } = this;
|
|
180
|
+
const { page, totalPages, total, pageSize, siblings, compact, hideRange } = this;
|
|
173
181
|
if (this._prevBtn) this._prevBtn.disabled = page <= 1;
|
|
174
182
|
if (this._nextBtn) this._nextBtn.disabled = page >= totalPages;
|
|
175
183
|
if (this._pageLabelEl) {
|
|
@@ -180,7 +188,7 @@ var BvPagination = class extends HTMLElement {
|
|
|
180
188
|
this._pagesEl.hidden = compact;
|
|
181
189
|
}
|
|
182
190
|
if (this._rangeEl) {
|
|
183
|
-
if (compact) {
|
|
191
|
+
if (compact || hideRange) {
|
|
184
192
|
this._rangeEl.hidden = true;
|
|
185
193
|
} else if (total > 0) {
|
|
186
194
|
const start = (page - 1) * pageSize + 1;
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import '../bv-searchbox/bv-searchbox.ts';
|
|
2
|
+
import '../bv-segmented-control/bv-segmented-control.ts';
|
|
3
|
+
import '../bv-toggle/bv-toggle.ts';
|
|
4
|
+
import '../bv-button/bv-button.ts';
|
|
5
|
+
export type SearchPickerMode = 'include' | 'exclude';
|
|
6
|
+
export interface SearchPickerItem {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
inactive?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detail on the `bv-search` event.
|
|
13
|
+
*
|
|
14
|
+
* Note: `showInactive` is intentionally NOT on this payload — read it directly
|
|
15
|
+
* off the picker (`picker.showInactive`) inside the handler. It changes via its
|
|
16
|
+
* own event (`bv-show-inactive-change`), so mixing it into `bv-search` would
|
|
17
|
+
* emit an update on every keystroke rather than only when it actually changes.
|
|
18
|
+
*/
|
|
19
|
+
export interface SearchPickerSearchDetail {
|
|
20
|
+
/** Trimmed user query. Only emitted past `min-query-length`. */
|
|
21
|
+
query: string;
|
|
22
|
+
/** Monotonic id the consumer echoes back via `results-request-id` so the picker can drop stale responses. */
|
|
23
|
+
requestId: number;
|
|
24
|
+
}
|
|
25
|
+
export interface SearchPickerBasketChangeDetail {
|
|
26
|
+
/** Staged mode at the moment of the change (before Apply). */
|
|
27
|
+
mode: SearchPickerMode;
|
|
28
|
+
/** Staged basket at the moment of the change (before Apply). Consumer sees every add/remove/clear. */
|
|
29
|
+
basket: SearchPickerItem[];
|
|
30
|
+
}
|
|
31
|
+
export interface SearchPickerModeChangeDetail {
|
|
32
|
+
/** Staged mode after the toggle (before Apply). */
|
|
33
|
+
mode: SearchPickerMode;
|
|
34
|
+
}
|
|
35
|
+
export interface SearchPickerShowInactiveChangeDetail {
|
|
36
|
+
showInactive: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface SearchPickerApplyDetail {
|
|
39
|
+
/** Committed mode. */
|
|
40
|
+
mode: SearchPickerMode;
|
|
41
|
+
/** Committed basket. */
|
|
42
|
+
basket: SearchPickerItem[];
|
|
43
|
+
}
|
|
44
|
+
export interface SearchPickerClearedDetail {
|
|
45
|
+
/** Consumer-supplied string identifying why the basket was cleared (e.g. `'category-changed'`, `'group-changed'`). */
|
|
46
|
+
reason: string;
|
|
47
|
+
}
|
|
48
|
+
export declare class BvSearchPicker extends HTMLElement {
|
|
49
|
+
static readonly observedAttributes: readonly ["label", "entity-label", "search-placeholder", "inactive-toggle-label", "mode", "min-query-length", "debounce-ms", "disabled", "loading", "show-inactive", "open", "results", "results-total", "results-request-id", "basket", "label-all", "label-count", "label-except", "label-only-these", "label-all-except", "label-empty-basket", "label-clear-all", "label-min-chars", "label-no-results", "label-results-cap", "label-cleared"];
|
|
50
|
+
private _rendered;
|
|
51
|
+
private _query;
|
|
52
|
+
/**
|
|
53
|
+
* BTN-10322 — staged basket edited inside the panel. Kept separate from the
|
|
54
|
+
* committed `basket` attribute so the trigger pill doesn't flicker mid-edit
|
|
55
|
+
* (add/remove doesn't touch it) and so a cascade reset (`reset()`) has a
|
|
56
|
+
* clean staged copy to reseed from. Committed on Apply, AND automatically
|
|
57
|
+
* whenever the panel closes any other way (Escape / outside-click / trigger
|
|
58
|
+
* toggle) — see `onAfterClose` in `_render()`. Closing is what "confirms"
|
|
59
|
+
* the edit; Apply is just the explicit, no-need-to-move-your-mouse way to
|
|
60
|
+
* do the same thing.
|
|
61
|
+
*/
|
|
62
|
+
private _stagedBasket;
|
|
63
|
+
/** BTN-10322 — staged mode edited inside the panel. Committed on close, same as `_stagedBasket`. */
|
|
64
|
+
private _stagedMode;
|
|
65
|
+
/** BTN-10322 — monotonic id emitted with `bv-search`. The consumer echoes it via `results-request-id`; stale responses drop silently. */
|
|
66
|
+
private _searchRequestId;
|
|
67
|
+
/** BTN-10322 — timer handle for the internal debounce on `bv-search`. */
|
|
68
|
+
private _searchDebounceHandle;
|
|
69
|
+
/**
|
|
70
|
+
* BTN-10755 — set synchronously the moment a keystroke enters over-threshold
|
|
71
|
+
* territory and the debounce is armed; cleared when the debounce fires (or
|
|
72
|
+
* on any reset / clear path). `_syncResultsEmptyText` treats it the same as
|
|
73
|
+
* `loading`, so the "No X found." copy can't flash in the ~300ms gap
|
|
74
|
+
* between the keystroke and the dispatched `bv-search`.
|
|
75
|
+
*/
|
|
76
|
+
private _searchPending;
|
|
77
|
+
/**
|
|
78
|
+
* BTN-10322 — the reason to display in the cascade cleared affordance,
|
|
79
|
+
* or `null` when the banner is hidden. Set by `reset({ reason })`,
|
|
80
|
+
* cleared when the user next opens the panel or explicitly dismisses.
|
|
81
|
+
*/
|
|
82
|
+
private _clearedReason;
|
|
83
|
+
private _labelEl;
|
|
84
|
+
private _triggerEl;
|
|
85
|
+
private _panelEl;
|
|
86
|
+
private _pillEl;
|
|
87
|
+
private _pillTextEl;
|
|
88
|
+
private _pillClearEl;
|
|
89
|
+
private _modeControlEl;
|
|
90
|
+
private _inactiveToggleEl;
|
|
91
|
+
private _searchEl;
|
|
92
|
+
private _resultsRowsEl;
|
|
93
|
+
private _resultsEmptyEl;
|
|
94
|
+
private _resultsLimitNoteEl;
|
|
95
|
+
private _basketHeaderLabelEl;
|
|
96
|
+
private _basketClearAllEl;
|
|
97
|
+
private _basketListEl;
|
|
98
|
+
private _basketEmptyEl;
|
|
99
|
+
private _resultsListEl;
|
|
100
|
+
private _clearedAffordanceEl;
|
|
101
|
+
private _clearedAffordanceMsgEl;
|
|
102
|
+
private _dropdown;
|
|
103
|
+
constructor();
|
|
104
|
+
get mode(): SearchPickerMode;
|
|
105
|
+
/**
|
|
106
|
+
* Setting `mode` from outside is treated as a commit — it aligns the staged
|
|
107
|
+
* mode inside the panel with the new committed value. Useful for initialising
|
|
108
|
+
* from URL params or reverting from a saved report configuration. If the panel
|
|
109
|
+
* is currently open, the segmented control snaps to the new mode immediately;
|
|
110
|
+
* the user is expected to see this as an intentional external change, not an
|
|
111
|
+
* accidental override of their in-flight edit.
|
|
112
|
+
*/
|
|
113
|
+
set mode(v: SearchPickerMode);
|
|
114
|
+
get entityLabel(): string;
|
|
115
|
+
set entityLabel(v: string);
|
|
116
|
+
get minQueryLength(): number;
|
|
117
|
+
set minQueryLength(v: number);
|
|
118
|
+
get disabled(): boolean;
|
|
119
|
+
set disabled(v: boolean);
|
|
120
|
+
get loading(): boolean;
|
|
121
|
+
set loading(v: boolean);
|
|
122
|
+
get showInactive(): boolean;
|
|
123
|
+
set showInactive(v: boolean);
|
|
124
|
+
get results(): SearchPickerItem[];
|
|
125
|
+
set results(v: SearchPickerItem[]);
|
|
126
|
+
get resultsTotal(): number | null;
|
|
127
|
+
set resultsTotal(v: number | null);
|
|
128
|
+
get debounceMs(): number;
|
|
129
|
+
set debounceMs(v: number);
|
|
130
|
+
get basket(): SearchPickerItem[];
|
|
131
|
+
set basket(v: SearchPickerItem[]);
|
|
132
|
+
connectedCallback(): void;
|
|
133
|
+
disconnectedCallback(): void;
|
|
134
|
+
attributeChangedCallback(name: string, _old: string | null, _val: string | null): void;
|
|
135
|
+
/**
|
|
136
|
+
* BTN-10322 — request-id guard. When `results` (or friends) are set from
|
|
137
|
+
* the consumer's async search, `results-request-id` must match the most
|
|
138
|
+
* recent id emitted by our own `bv-search`. Any mismatch means the
|
|
139
|
+
* response arrived out of order (user typed faster than the network) and
|
|
140
|
+
* we drop it silently to avoid rendering stale rows.
|
|
141
|
+
*
|
|
142
|
+
* `results-request-id` unset entirely is fine — consumers that don't
|
|
143
|
+
* bother with the guard behave as before (no correlation).
|
|
144
|
+
*/
|
|
145
|
+
private _syncResultsWithGuard;
|
|
146
|
+
private _render;
|
|
147
|
+
private _positionPanel;
|
|
148
|
+
private _syncLabel;
|
|
149
|
+
private _syncModeOptions;
|
|
150
|
+
private _syncSearchPlaceholder;
|
|
151
|
+
private _syncInactiveToggleLabel;
|
|
152
|
+
private _syncMode;
|
|
153
|
+
private _syncDisabled;
|
|
154
|
+
private _syncShowInactive;
|
|
155
|
+
private _syncResults;
|
|
156
|
+
private _effectiveQueryLength;
|
|
157
|
+
private _syncResultsEmptyText;
|
|
158
|
+
private _syncResultsLimitNote;
|
|
159
|
+
private _syncBasket;
|
|
160
|
+
private _syncBasketHeaderLabel;
|
|
161
|
+
private _syncBasketRowColors;
|
|
162
|
+
private _syncBasketEmptyText;
|
|
163
|
+
private _syncTriggerSummary;
|
|
164
|
+
private _interp;
|
|
165
|
+
private _addBasket;
|
|
166
|
+
private _removeBasket;
|
|
167
|
+
private _clearAllStaged;
|
|
168
|
+
/**
|
|
169
|
+
* The trigger's pill-clear (`x`) is an explicit user action that means "back
|
|
170
|
+
* to the neutral state". Unlike the basket's "Clear all" (which only touches
|
|
171
|
+
* staged), this commits immediately — the pill lives on the trigger, which
|
|
172
|
+
* only reflects committed state. Dispatches `bv-apply` because a commit
|
|
173
|
+
* happened.
|
|
174
|
+
*/
|
|
175
|
+
private _clearCommitted;
|
|
176
|
+
private _stagedDiffersFromCommitted;
|
|
177
|
+
private _commitStaged;
|
|
178
|
+
private _apply;
|
|
179
|
+
private _dispatchBasketChange;
|
|
180
|
+
private _dispatchModeChange;
|
|
181
|
+
private _dispatchShowInactiveChange;
|
|
182
|
+
private _dispatchApply;
|
|
183
|
+
private _dispatchSearch;
|
|
184
|
+
private _scheduleSearchDispatch;
|
|
185
|
+
/**
|
|
186
|
+
* BTN-10322 — Arrow Up/Down navigation between result rows; Enter or Space
|
|
187
|
+
* adds the currently-focused row to the staged basket. Home/End jump to
|
|
188
|
+
* first/last. Escape delegates to the shared dropdown-controller (already
|
|
189
|
+
* wired on the host).
|
|
190
|
+
*
|
|
191
|
+
* `role="option"` rows use `aria-selected` only to communicate focus
|
|
192
|
+
* position to assistive tech — clicking / Enter also fires the add flow,
|
|
193
|
+
* which then removes the row from the results list.
|
|
194
|
+
*/
|
|
195
|
+
private _onResultsKeyDown;
|
|
196
|
+
/**
|
|
197
|
+
* BTN-10322 — count of the currently committed basket. Consumers can read
|
|
198
|
+
* this to render an external counter badge without duplicating state.
|
|
199
|
+
*/
|
|
200
|
+
get count(): number;
|
|
201
|
+
/**
|
|
202
|
+
* BTN-10322 — cascade reset from outside the panel. This is THE canonical
|
|
203
|
+
* way for a consumer to clear the picker in response to an upstream filter
|
|
204
|
+
* change (e.g. CET Report when Categories or Groups change). It:
|
|
205
|
+
*
|
|
206
|
+
* - clears the committed `basket` and the staged edit,
|
|
207
|
+
* - clears `results` + `resultsTotal` (post-cascade the last search's
|
|
208
|
+
* rows are stale — leaving them visible next to the cleared banner
|
|
209
|
+
* is confusing),
|
|
210
|
+
* - clears the internal search query,
|
|
211
|
+
* - surfaces the "cleared" affordance banner with `{ reason }` interpolated
|
|
212
|
+
* into the copy,
|
|
213
|
+
* - dispatches `bv-cleared` with `{ reason }`.
|
|
214
|
+
*
|
|
215
|
+
* Does NOT dispatch `bv-apply` — this is not a user commit, it's an
|
|
216
|
+
* out-of-band cascade. The consumer that triggered it already knows the
|
|
217
|
+
* basket was cleared.
|
|
218
|
+
*
|
|
219
|
+
* The affordance auto-hides the next time the user opens the panel or
|
|
220
|
+
* dismisses it explicitly via the banner's close button.
|
|
221
|
+
*
|
|
222
|
+
* **Prefer this over `element.basket = []`** — the setter is silent (no
|
|
223
|
+
* bv-cleared, no visible affordance) and is intended for state restoration
|
|
224
|
+
* from URL/deep-link, not for cascade reset.
|
|
225
|
+
*/
|
|
226
|
+
reset({ reason }: {
|
|
227
|
+
reason: string;
|
|
228
|
+
}): void;
|
|
229
|
+
private _syncClearedAffordance;
|
|
230
|
+
private _dismissClearedAffordance;
|
|
231
|
+
}
|