@oicl/openbridge-webcomponents 2.1.0-next.1 → 2.1.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +1 -0
  2. package/bundle/openbridge-webcomponents.bundle.js +352 -244
  3. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  4. package/custom-elements.json +944 -90
  5. package/dist/building-blocks/alert-list/alert-list-base.d.ts +60 -0
  6. package/dist/building-blocks/alert-list/alert-list-base.d.ts.map +1 -0
  7. package/dist/building-blocks/alert-list/alert-list-base.js +191 -0
  8. package/dist/building-blocks/alert-list/alert-list-base.js.map +1 -0
  9. package/dist/building-blocks/alert-list/alert-list.css.js.map +1 -1
  10. package/dist/building-blocks/alert-list/alert-list.d.ts +13 -26
  11. package/dist/building-blocks/alert-list/alert-list.d.ts.map +1 -1
  12. package/dist/building-blocks/alert-list/alert-list.js +7 -142
  13. package/dist/building-blocks/alert-list/alert-list.js.map +1 -1
  14. package/dist/components/alert-icon/alert-icon.d.ts.map +1 -1
  15. package/dist/components/alert-icon/alert-icon.js +6 -5
  16. package/dist/components/alert-icon/alert-icon.js.map +1 -1
  17. package/dist/components/alert-list-details/alert-list-details.css.js +4 -1
  18. package/dist/components/alert-list-details/alert-list-details.css.js.map +1 -1
  19. package/dist/components/alert-menu/alert-menu.css.js +3 -42
  20. package/dist/components/alert-menu/alert-menu.css.js.map +1 -1
  21. package/dist/components/alert-menu/alert-menu.d.ts +28 -6
  22. package/dist/components/alert-menu/alert-menu.d.ts.map +1 -1
  23. package/dist/components/alert-menu/alert-menu.js +81 -60
  24. package/dist/components/alert-menu/alert-menu.js.map +1 -1
  25. package/dist/components/alert-menu-item/alert-menu-item.d.ts +16 -6
  26. package/dist/components/alert-menu-item/alert-menu-item.d.ts.map +1 -1
  27. package/dist/components/alert-menu-item/alert-menu-item.js +11 -2
  28. package/dist/components/alert-menu-item/alert-menu-item.js.map +1 -1
  29. package/dist/components/number-input-field/number-input-field.css.js +8 -2
  30. package/dist/components/number-input-field/number-input-field.css.js.map +1 -1
  31. package/dist/components/number-input-field/number-input-field.d.ts +15 -1
  32. package/dist/components/number-input-field/number-input-field.d.ts.map +1 -1
  33. package/dist/components/number-input-field/number-input-field.js +38 -44
  34. package/dist/components/number-input-field/number-input-field.js.map +1 -1
  35. package/dist/components/textbox/textbox.css.js +3 -9
  36. package/dist/components/textbox/textbox.css.js.map +1 -1
  37. package/dist/components/textbox/textbox.d.ts +3 -0
  38. package/dist/components/textbox/textbox.d.ts.map +1 -1
  39. package/dist/components/textbox/textbox.js.map +1 -1
  40. package/dist/generated/locales/es-419.d.ts +1 -1
  41. package/dist/generated/locales/es-419.js +1 -1
  42. package/dist/generated/locales/es-419.js.map +1 -1
  43. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +2 -1
  44. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
  45. package/dist/pages/alert-detail-page/alert-detail-page.js +1 -1
  46. package/dist/pages/alert-detail-page/alert-detail-page.js.map +1 -1
  47. package/dist/pages/alert-list-page-small/alert-list-page-small-base.d.ts +63 -0
  48. package/dist/pages/alert-list-page-small/alert-list-page-small-base.d.ts.map +1 -0
  49. package/dist/pages/alert-list-page-small/alert-list-page-small-base.js +126 -0
  50. package/dist/pages/alert-list-page-small/alert-list-page-small-base.js.map +1 -0
  51. package/dist/pages/alert-list-page-small/alert-list-page-small.d.ts +12 -15
  52. package/dist/pages/alert-list-page-small/alert-list-page-small.d.ts.map +1 -1
  53. package/dist/pages/alert-list-page-small/alert-list-page-small.js +41 -92
  54. package/dist/pages/alert-list-page-small/alert-list-page-small.js.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,60 @@
1
+ import { CSSResultGroup, LitElement, PropertyValues } from 'lit';
2
+ import '../../components/scrollbar/scrollbar.js';
3
+ /** What an empty alert list shows where its `empty-*` slots are left unfilled. */
4
+ export interface AlertListEmptyFallback {
5
+ icon?: unknown;
6
+ title?: unknown;
7
+ }
8
+ /**
9
+ * `ObcAlertListBase` – Scrolling list of slotted alert items that animates items
10
+ * into place and shows an empty state when no item passes its filter.
11
+ *
12
+ * Not registered as an element: the subclasses decide which items pass.
13
+ * `obc-alert-list` runs a predicate the consumer sets.
14
+ *
15
+ * ### Features
16
+ * - **Filter:** `matchesFilter()` decides which items count; the list re-reads
17
+ * it when items are added or removed, when an item attribute named by
18
+ * `observedItemAttributes` changes, and when `filterChanged()` reports a
19
+ * change of the subclass's filter inputs.
20
+ * - **Motion:** items that move slide to their new place; new items play
21
+ * their intro animation once the list has been seen.
22
+ * - **Empty state:** icon, title and description slots, with fallback content
23
+ * from `emptyFallback`.
24
+ * - **Visible items:** `getVisibleElements()` returns the items that pass the
25
+ * filter and sit inside the scroll viewport.
26
+ */
27
+ export declare class ObcAlertListBase extends LitElement {
28
+ private oldElementTop;
29
+ private mutationObserver;
30
+ private intersectionObserver;
31
+ private hasRenderedPanel;
32
+ _empty: boolean;
33
+ protected alertItems: HTMLElement[];
34
+ private scrollbar;
35
+ /** Whether the list counts an item as one it shows. */
36
+ protected matchesFilter(_item: HTMLElement): boolean;
37
+ /** Whether this update changed what `matchesFilter` decides. */
38
+ protected filterChanged(_changed: PropertyValues): boolean;
39
+ /** Item attributes whose changes can change what `matchesFilter` decides. */
40
+ protected get observedItemAttributes(): string[];
41
+ protected get emptyFallback(): AlertListEmptyFallback;
42
+ firstUpdated(): void;
43
+ connectedCallback(): void;
44
+ disconnectedCallback(): void;
45
+ protected willUpdate(_changedProperties: PropertyValues): void;
46
+ /** Runs whenever the items or the filter change; a subclass extends it to act on each item. */
47
+ protected applyFilter(): void;
48
+ private getAlertItems;
49
+ private updateOldElementTop;
50
+ private setupMutationObserver;
51
+ private handleSlotChange;
52
+ private handleElementsChange;
53
+ getVisibleElements(): {
54
+ element: HTMLElement;
55
+ index: number;
56
+ }[];
57
+ render(): import('lit-html').TemplateResult<1>;
58
+ static styles: CSSResultGroup;
59
+ }
60
+ //# sourceMappingURL=alert-list-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert-list-base.d.ts","sourceRoot":"","sources":["../../../src/building-blocks/alert-list/alert-list-base.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,UAAU,EACV,cAAc,EAIf,MAAM,KAAK,CAAC;AAGb,OAAO,yCAAyC,CAAC;AAIjD,kFAAkF;AAClF,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;IAC9C,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,gBAAgB,CAAS;IACxB,MAAM,UAAS;IAGxB,SAAS,CAAC,UAAU,EAAG,WAAW,EAAE,CAAC;IAGrC,OAAO,CAAC,SAAS,CAAgB;IAEjC,uDAAuD;IACvD,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAIpD,gEAAgE;IAChE,SAAS,CAAC,aAAa,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO;IAI1D,6EAA6E;IAC7E,SAAS,KAAK,sBAAsB,IAAI,MAAM,EAAE,CAE/C;IAED,SAAS,KAAK,aAAa,IAAI,sBAAsB,CAEpD;IAEQ,YAAY;IAKZ,iBAAiB;IAcjB,oBAAoB;cAYV,UAAU,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAOvE,+FAA+F;IAC/F,SAAS,CAAC,WAAW;IAIrB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,oBAAoB;IAgDrB,kBAAkB,IAAI;QAAC,OAAO,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE;IA4B3D,MAAM;IAsBf,OAAgB,MAAM,EAAE,cAAc,CAA2B;CAClE"}
@@ -0,0 +1,191 @@
1
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
2
+ import alert_list_default from "./alert-list.css.js";
3
+ import "../../components/scrollbar/scrollbar.js";
4
+ import { LitElement, html, nothing, unsafeCSS } from "lit";
5
+ import { query, queryAssignedElements, state } from "lit/decorators.js";
6
+ //#region src/building-blocks/alert-list/alert-list-base.ts
7
+ /**
8
+ * `ObcAlertListBase` – Scrolling list of slotted alert items that animates items
9
+ * into place and shows an empty state when no item passes its filter.
10
+ *
11
+ * Not registered as an element: the subclasses decide which items pass.
12
+ * `obc-alert-list` runs a predicate the consumer sets.
13
+ *
14
+ * ### Features
15
+ * - **Filter:** `matchesFilter()` decides which items count; the list re-reads
16
+ * it when items are added or removed, when an item attribute named by
17
+ * `observedItemAttributes` changes, and when `filterChanged()` reports a
18
+ * change of the subclass's filter inputs.
19
+ * - **Motion:** items that move slide to their new place; new items play
20
+ * their intro animation once the list has been seen.
21
+ * - **Empty state:** icon, title and description slots, with fallback content
22
+ * from `emptyFallback`.
23
+ * - **Visible items:** `getVisibleElements()` returns the items that pass the
24
+ * filter and sit inside the scroll viewport.
25
+ */
26
+ var ObcAlertListBase = class extends LitElement {
27
+ constructor(..._args) {
28
+ super(..._args);
29
+ this.oldElementTop = /* @__PURE__ */ new Map();
30
+ this.mutationObserver = null;
31
+ this.intersectionObserver = null;
32
+ this.hasRenderedPanel = false;
33
+ this._empty = false;
34
+ }
35
+ /** Whether the list counts an item as one it shows. */
36
+ matchesFilter(_item) {
37
+ return true;
38
+ }
39
+ /** Whether this update changed what `matchesFilter` decides. */
40
+ filterChanged(_changed) {
41
+ return false;
42
+ }
43
+ /** Item attributes whose changes can change what `matchesFilter` decides. */
44
+ get observedItemAttributes() {
45
+ return ["status", "shelved"];
46
+ }
47
+ get emptyFallback() {
48
+ return {};
49
+ }
50
+ firstUpdated() {
51
+ this.applyFilter();
52
+ this.setupMutationObserver();
53
+ }
54
+ connectedCallback() {
55
+ super.connectedCallback();
56
+ const intersectionObserver = new IntersectionObserver((entries) => {
57
+ if (entries[0].intersectionRatio === 0) this.hasRenderedPanel = false;
58
+ });
59
+ intersectionObserver.observe(this);
60
+ this.intersectionObserver = intersectionObserver;
61
+ this.setupMutationObserver();
62
+ }
63
+ disconnectedCallback() {
64
+ super.disconnectedCallback();
65
+ if (this.mutationObserver) {
66
+ this.mutationObserver.disconnect();
67
+ this.mutationObserver = null;
68
+ }
69
+ if (this.intersectionObserver) {
70
+ this.intersectionObserver.disconnect();
71
+ this.intersectionObserver = null;
72
+ }
73
+ }
74
+ willUpdate(_changedProperties) {
75
+ if (this.filterChanged(_changedProperties)) {
76
+ this.applyFilter();
77
+ this.updateOldElementTop();
78
+ }
79
+ }
80
+ /** Runs whenever the items or the filter change; a subclass extends it to act on each item. */
81
+ applyFilter() {
82
+ this._empty = this.getAlertItems().length === 0;
83
+ }
84
+ getAlertItems() {
85
+ return this.alertItems.filter((item) => this.matchesFilter(item));
86
+ }
87
+ updateOldElementTop() {
88
+ const elements = this.getAlertItems();
89
+ if (elements.length === 0) return;
90
+ let top = elements[0].getBoundingClientRect().top;
91
+ this.oldElementTop.clear();
92
+ elements.forEach((element) => {
93
+ const elementRect = element.getBoundingClientRect();
94
+ if (elementRect.height === 0) return;
95
+ this.oldElementTop.set(element, top);
96
+ top += elementRect.height;
97
+ });
98
+ }
99
+ setupMutationObserver() {
100
+ if (this.mutationObserver) {
101
+ this.mutationObserver.disconnect();
102
+ this.mutationObserver = null;
103
+ }
104
+ this.mutationObserver = new MutationObserver(() => {
105
+ this.handleElementsChange();
106
+ });
107
+ this.alertItems.forEach((element) => {
108
+ this.mutationObserver?.observe(element, {
109
+ attributes: true,
110
+ attributeFilter: this.observedItemAttributes
111
+ });
112
+ });
113
+ }
114
+ handleSlotChange() {
115
+ this.handleElementsChange();
116
+ this.setupMutationObserver();
117
+ }
118
+ handleElementsChange() {
119
+ this.mutationObserver?.takeRecords();
120
+ this.applyFilter();
121
+ if (!this.checkVisibility()) return;
122
+ const elements = this.getAlertItems();
123
+ const oldElementTop = new Map(this.oldElementTop);
124
+ requestAnimationFrame(() => {
125
+ this.updateOldElementTop();
126
+ let hasNewElements = false;
127
+ elements.forEach((element) => {
128
+ const elementRect = element.getBoundingClientRect();
129
+ const oldTop = oldElementTop.get(element);
130
+ if (oldTop === void 0) {
131
+ element.animateIntro = this.hasRenderedPanel;
132
+ hasNewElements = true;
133
+ setTimeout(() => {
134
+ element.animateIntro = false;
135
+ }, 101);
136
+ return;
137
+ }
138
+ const diff = oldTop - elementRect.top;
139
+ if (diff === 0) return;
140
+ element.style.transform = `translateY(${diff}px)`;
141
+ element.style.transition = "none";
142
+ element.offsetHeight;
143
+ element.style.transition = "transform 100ms ease-in-out";
144
+ element.style.transform = "translateY(0px)";
145
+ });
146
+ this.hasRenderedPanel = true;
147
+ if (hasNewElements) setTimeout(() => {
148
+ this.updateOldElementTop();
149
+ }, 101);
150
+ });
151
+ }
152
+ getVisibleElements() {
153
+ const scrollbarRect = this.scrollbar.getBoundingClientRect();
154
+ return this.getAlertItems().map((element, index) => ({
155
+ element,
156
+ index
157
+ })).filter(({ element }) => {
158
+ const style = window.getComputedStyle(element);
159
+ if (style.display === "none" || style.visibility === "hidden") return false;
160
+ const elementRect = element.getBoundingClientRect();
161
+ return !(elementRect.top < scrollbarRect.top || elementRect.bottom > scrollbarRect.bottom);
162
+ });
163
+ }
164
+ render() {
165
+ const fallback = this.emptyFallback;
166
+ return html` <obc-scrollbar class="alert-list" id="scrollbar">
167
+ <slot @slotchange=${this.handleSlotChange}></slot>
168
+ ${this._empty ? html` <div class="empty-list">
169
+ <div class="icon">
170
+ <slot name="empty-icon">${fallback.icon}</slot>
171
+ </div>
172
+ <div class="empty-title">
173
+ <slot name="empty-title">${fallback.title}</slot>
174
+ </div>
175
+ <div class="empty-description">
176
+ <slot name="empty-description"></slot>
177
+ </div>
178
+ </div>` : nothing}
179
+ </obc-scrollbar>`;
180
+ }
181
+ static {
182
+ this.styles = unsafeCSS(alert_list_default);
183
+ }
184
+ };
185
+ __decorate([state()], ObcAlertListBase.prototype, "_empty", void 0);
186
+ __decorate([queryAssignedElements({ flatten: true })], ObcAlertListBase.prototype, "alertItems", void 0);
187
+ __decorate([query("#scrollbar", true)], ObcAlertListBase.prototype, "scrollbar", void 0);
188
+ //#endregion
189
+ export { ObcAlertListBase };
190
+
191
+ //# sourceMappingURL=alert-list-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert-list-base.js","names":[],"sources":["../../../src/building-blocks/alert-list/alert-list-base.ts"],"sourcesContent":["import {\n CSSResultGroup,\n LitElement,\n PropertyValues,\n html,\n nothing,\n unsafeCSS,\n} from 'lit';\nimport {queryAssignedElements, query, state} from 'lit/decorators.js';\nimport compentStyle from './alert-list.css?inline';\nimport '../../components/scrollbar/scrollbar.js';\nimport {ObcScrollbar} from '../../components/scrollbar/scrollbar.js';\nimport {ObcAlertMenuItem} from '../../components/alert-menu-item/alert-menu-item.js';\n\n/** What an empty alert list shows where its `empty-*` slots are left unfilled. */\nexport interface AlertListEmptyFallback {\n icon?: unknown;\n title?: unknown;\n}\n\n/**\n * `ObcAlertListBase` – Scrolling list of slotted alert items that animates items\n * into place and shows an empty state when no item passes its filter.\n *\n * Not registered as an element: the subclasses decide which items pass.\n * `obc-alert-list` runs a predicate the consumer sets.\n *\n * ### Features\n * - **Filter:** `matchesFilter()` decides which items count; the list re-reads\n * it when items are added or removed, when an item attribute named by\n * `observedItemAttributes` changes, and when `filterChanged()` reports a\n * change of the subclass's filter inputs.\n * - **Motion:** items that move slide to their new place; new items play\n * their intro animation once the list has been seen.\n * - **Empty state:** icon, title and description slots, with fallback content\n * from `emptyFallback`.\n * - **Visible items:** `getVisibleElements()` returns the items that pass the\n * filter and sit inside the scroll viewport.\n */\nexport class ObcAlertListBase extends LitElement {\n private oldElementTop: Map<HTMLElement, number> = new Map();\n private mutationObserver: MutationObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private hasRenderedPanel = false;\n @state() _empty = false;\n\n @queryAssignedElements({flatten: true})\n protected alertItems!: HTMLElement[];\n\n @query('#scrollbar', true)\n private scrollbar!: ObcScrollbar;\n\n /** Whether the list counts an item as one it shows. */\n protected matchesFilter(_item: HTMLElement): boolean {\n return true;\n }\n\n /** Whether this update changed what `matchesFilter` decides. */\n protected filterChanged(_changed: PropertyValues): boolean {\n return false;\n }\n\n /** Item attributes whose changes can change what `matchesFilter` decides. */\n protected get observedItemAttributes(): string[] {\n return ['status', 'shelved'];\n }\n\n protected get emptyFallback(): AlertListEmptyFallback {\n return {};\n }\n\n override firstUpdated() {\n this.applyFilter();\n this.setupMutationObserver();\n }\n\n override connectedCallback() {\n super.connectedCallback();\n const intersectionObserver = new IntersectionObserver((entries) => {\n // If intersectionRatio is 0, the target is out of view\n if (entries[0].intersectionRatio === 0) {\n this.hasRenderedPanel = false;\n }\n });\n intersectionObserver.observe(this);\n this.intersectionObserver = intersectionObserver;\n\n this.setupMutationObserver();\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect();\n this.intersectionObserver = null;\n }\n }\n\n protected override willUpdate(_changedProperties: PropertyValues): void {\n if (this.filterChanged(_changedProperties)) {\n this.applyFilter();\n this.updateOldElementTop();\n }\n }\n\n /** Runs whenever the items or the filter change; a subclass extends it to act on each item. */\n protected applyFilter() {\n this._empty = this.getAlertItems().length === 0;\n }\n\n private getAlertItems() {\n return this.alertItems.filter((item) => this.matchesFilter(item));\n }\n\n private updateOldElementTop() {\n const elements = this.getAlertItems();\n if (elements.length === 0) {\n return;\n }\n\n // Get the top of the element,\n // the element may be in an animation\n // we therefor sum the height of each element\n const firstElement = elements[0];\n const firstElementRect = firstElement.getBoundingClientRect();\n let top = firstElementRect.top;\n this.oldElementTop.clear();\n elements.forEach((element) => {\n const elementRect = element.getBoundingClientRect();\n if (elementRect.height === 0) {\n return;\n }\n this.oldElementTop.set(element, top);\n top += elementRect.height;\n });\n }\n\n private setupMutationObserver() {\n if (this.mutationObserver) {\n // Make a new observer to avoid memory leaks\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n this.mutationObserver = new MutationObserver(() => {\n this.handleElementsChange();\n });\n\n const slotElements = this.alertItems;\n slotElements.forEach((element) => {\n // Earlier observed elements are just updated, and not registered twice.\n this.mutationObserver?.observe(element, {\n attributes: true,\n attributeFilter: this.observedItemAttributes,\n });\n });\n }\n\n private handleSlotChange() {\n this.handleElementsChange();\n this.setupMutationObserver();\n }\n\n private handleElementsChange() {\n // Take records to ensure the observer is not triggered again\n this.mutationObserver?.takeRecords();\n this.applyFilter();\n if (!this.checkVisibility()) {\n return;\n }\n\n const elements = this.getAlertItems();\n // Animate the elements to their new positions\n const oldElementTop: Map<HTMLElement, number> = new Map(this.oldElementTop);\n\n requestAnimationFrame(() => {\n this.updateOldElementTop();\n let hasNewElements = false;\n elements.forEach((element) => {\n const elementRect = element.getBoundingClientRect();\n const oldTop = oldElementTop.get(element);\n if (oldTop === undefined) {\n // New element\n (element as ObcAlertMenuItem).animateIntro = this.hasRenderedPanel;\n hasNewElements = true;\n setTimeout(() => {\n (element as ObcAlertMenuItem).animateIntro = false;\n }, 101);\n return;\n }\n const diff = oldTop - elementRect.top;\n if (diff === 0) return;\n element.style.transform = `translateY(${diff}px)`;\n element.style.transition = 'none';\n\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- the read forces the reflow that restarts the transition\n element.offsetHeight;\n\n // Remove the transition after the animation is complete\n element.style.transition = 'transform 100ms ease-in-out';\n element.style.transform = 'translateY(0px)';\n });\n this.hasRenderedPanel = true;\n if (hasNewElements) {\n setTimeout(() => {\n this.updateOldElementTop();\n }, 101);\n }\n });\n }\n\n public getVisibleElements(): {element: HTMLElement; index: number}[] {\n // Get all slotted elements in the visible tab's scrollbar\n\n const scrollbarRect = this.scrollbar.getBoundingClientRect();\n const slottedElements = this.getAlertItems();\n\n // Filter for only visible elements that are within the scrollbar viewport\n return slottedElements\n .map((element, index) => ({element, index}))\n .filter(({element}) => {\n const style = window.getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden') {\n return false;\n }\n\n // Check if the element is within the scrollbar's viewport\n const elementRect = element.getBoundingClientRect();\n\n // Check if element overlaps with scrollbar viewport\n const isVisible = !(\n elementRect.top < scrollbarRect.top ||\n elementRect.bottom > scrollbarRect.bottom\n );\n\n return isVisible;\n });\n }\n\n override render() {\n const fallback = this.emptyFallback;\n return html` <obc-scrollbar class=\"alert-list\" id=\"scrollbar\">\n <slot @slotchange=${this.handleSlotChange}></slot>\n ${\n this._empty\n ? html` <div class=\"empty-list\">\n <div class=\"icon\">\n <slot name=\"empty-icon\">${fallback.icon}</slot>\n </div>\n <div class=\"empty-title\">\n <slot name=\"empty-title\">${fallback.title}</slot>\n </div>\n <div class=\"empty-description\">\n <slot name=\"empty-description\"></slot>\n </div>\n </div>`\n : nothing\n }\n </obc-scrollbar>`;\n }\n\n static override styles: CSSResultGroup = unsafeCSS(compentStyle);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,IAAa,mBAAb,cAAsC,WAAW;;;EACG,KAAA,gCAAA,IAAI,IAAI;EACN,KAAA,mBAAA;EACQ,KAAA,uBAAA;EACjC,KAAA,mBAAA;EACT,KAAA,SAAA;;;CASlB,cAAwB,OAA6B;EACnD,OAAO;CACT;;CAGA,cAAwB,UAAmC;EACzD,OAAO;CACT;;CAGA,IAAc,yBAAmC;EAC/C,OAAO,CAAC,UAAU,SAAS;CAC7B;CAEA,IAAc,gBAAwC;EACpD,OAAO,CAAC;CACV;CAEA,eAAwB;EACtB,KAAK,YAAY;EACjB,KAAK,sBAAsB;CAC7B;CAEA,oBAA6B;EAC3B,MAAM,kBAAkB;EACxB,MAAM,uBAAuB,IAAI,sBAAsB,YAAY;GAEjE,IAAI,QAAQ,EAAE,CAAC,sBAAsB,GACnC,KAAK,mBAAmB;EAE5B,CAAC;EACD,qBAAqB,QAAQ,IAAI;EACjC,KAAK,uBAAuB;EAE5B,KAAK,sBAAsB;CAC7B;CAEA,uBAAgC;EAC9B,MAAM,qBAAqB;EAC3B,IAAI,KAAK,kBAAkB;GACzB,KAAK,iBAAiB,WAAW;GACjC,KAAK,mBAAmB;EAC1B;EACA,IAAI,KAAK,sBAAsB;GAC7B,KAAK,qBAAqB,WAAW;GACrC,KAAK,uBAAuB;EAC9B;CACF;CAEA,WAA8B,oBAA0C;EACtE,IAAI,KAAK,cAAc,kBAAkB,GAAG;GAC1C,KAAK,YAAY;GACjB,KAAK,oBAAoB;EAC3B;CACF;;CAGA,cAAwB;EACtB,KAAK,SAAS,KAAK,cAAc,CAAC,CAAC,WAAW;CAChD;CAEA,gBAAwB;EACtB,OAAO,KAAK,WAAW,QAAQ,SAAS,KAAK,cAAc,IAAI,CAAC;CAClE;CAEA,sBAA8B;EAC5B,MAAM,WAAW,KAAK,cAAc;EACpC,IAAI,SAAS,WAAW,GACtB;EAQF,IAAI,MAFiB,SAAS,EACL,CAAa,sBAC5B,CAAA,CAAiB;EAC3B,KAAK,cAAc,MAAM;EACzB,SAAS,SAAS,YAAY;GAC5B,MAAM,cAAc,QAAQ,sBAAsB;GAClD,IAAI,YAAY,WAAW,GACzB;GAEF,KAAK,cAAc,IAAI,SAAS,GAAG;GACnC,OAAO,YAAY;EACrB,CAAC;CACH;CAEA,wBAAgC;EAC9B,IAAI,KAAK,kBAAkB;GAEzB,KAAK,iBAAiB,WAAW;GACjC,KAAK,mBAAmB;EAC1B;EACA,KAAK,mBAAmB,IAAI,uBAAuB;GACjD,KAAK,qBAAqB;EAC5B,CAAC;EAGD,KAD0B,WACb,SAAS,YAAY;GAEhC,KAAK,kBAAkB,QAAQ,SAAS;IACtC,YAAY;IACZ,iBAAiB,KAAK;GACxB,CAAC;EACH,CAAC;CACH;CAEA,mBAA2B;EACzB,KAAK,qBAAqB;EAC1B,KAAK,sBAAsB;CAC7B;CAEA,uBAA+B;EAE7B,KAAK,kBAAkB,YAAY;EACnC,KAAK,YAAY;EACjB,IAAI,CAAC,KAAK,gBAAgB,GACxB;EAGF,MAAM,WAAW,KAAK,cAAc;EAEpC,MAAM,gBAA0C,IAAI,IAAI,KAAK,aAAa;EAE1E,4BAA4B;GAC1B,KAAK,oBAAoB;GACzB,IAAI,iBAAiB;GACrB,SAAS,SAAS,YAAY;IAC5B,MAAM,cAAc,QAAQ,sBAAsB;IAClD,MAAM,SAAS,cAAc,IAAI,OAAO;IACxC,IAAI,WAAW,KAAA,GAAW;KAExB,QAA8B,eAAe,KAAK;KAClD,iBAAiB;KACjB,iBAAiB;MACf,QAA8B,eAAe;KAC/C,GAAG,GAAG;KACN;IACF;IACA,MAAM,OAAO,SAAS,YAAY;IAClC,IAAI,SAAS,GAAG;IAChB,QAAQ,MAAM,YAAY,cAAc,KAAK;IAC7C,QAAQ,MAAM,aAAa;IAG3B,QAAQ;IAGR,QAAQ,MAAM,aAAa;IAC3B,QAAQ,MAAM,YAAY;GAC5B,CAAC;GACD,KAAK,mBAAmB;GACxB,IAAI,gBACF,iBAAiB;IACf,KAAK,oBAAoB;GAC3B,GAAG,GAAG;EAEV,CAAC;CACH;CAEA,qBAAqE;EAGnE,MAAM,gBAAgB,KAAK,UAAU,sBAAsB;EAI3D,OAHwB,KAAK,cAGtB,CAAA,CACJ,KAAK,SAAS,WAAW;GAAC;GAAS;EAAK,EAAE,CAAC,CAC3C,QAAQ,EAAC,cAAa;GACrB,MAAM,QAAQ,OAAO,iBAAiB,OAAO;GAC7C,IAAI,MAAM,YAAY,UAAU,MAAM,eAAe,UACnD,OAAO;GAIT,MAAM,cAAc,QAAQ,sBAAsB;GAQlD,OAAO,EAJL,YAAY,MAAM,cAAc,OAChC,YAAY,SAAS,cAAc;EAIvC,CAAC;CACL;CAEA,SAAkB;EAChB,MAAM,WAAW,KAAK;EACtB,OAAO,IAAI;0BACW,KAAK,iBAAiB;QAExC,KAAK,SACD,IAAI;;0CAE0B,SAAS,KAAK;;;2CAGb,SAAS,MAAM;;;;;sBAM9C,QACL;;CAEL;;EAEyC,KAAA,SAAA,UAAU,kBAAY;;AACjE;AA7NG,WAAA,CAAA,MAAM,CAAA,GAAA,iBAAA,WAAA,UAAA,KAAA,CAAA;AAEN,WAAA,CAAA,sBAAsB,EAAC,SAAS,KAAI,CAAC,CAAA,GAAA,iBAAA,WAAA,cAAA,KAAA,CAAA;AAGrC,WAAA,CAAA,MAAM,cAAc,IAAI,CAAA,GAAA,iBAAA,WAAA,aAAA,KAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"alert-list.css.js","names":[],"sources":["../../../src/building-blocks/alert-list/alert-list.css?inline"],"sourcesContent":["* {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n.alert-list {\n height: 100%;\n}\n\n.empty-list {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: var(--app-components-alert-menu-button-spacing);\n\n .icon {\n height: 96px;\n width: 96px;\n }\n\n .empty-title {\n color: var(--element-active-color);\n @mixin font-body-active;\n }\n\n .empty-description {\n color: var(--element-neutral-color);\n @mixin font-body;\n max-width: 344px;\n text-align: center;\n }\n}\n\n::slotted(*) {\n display: block;\n will-change: transform;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"alert-list.css.js","names":[],"sources":["../../../src/building-blocks/alert-list/alert-list.css?inline"],"sourcesContent":["* {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n.alert-list {\n height: 100%;\n}\n\n.empty-list {\n @mixin alert-list-empty;\n}\n\n::slotted(*) {\n display: block;\n will-change: transform;\n}\n"],"mappings":""}
@@ -1,37 +1,24 @@
1
- import { LitElement, PropertyValues } from 'lit';
2
- import '../../components/scrollbar/scrollbar.js';
1
+ import { PropertyValues } from 'lit';
2
+ import { ObcAlertListBase } from './alert-list-base.js';
3
3
  /**
4
+ * `<obc-alert-list>` – Scrolling list of alert items with an empty state.
5
+ *
6
+ * `filter` decides which items count: the empty state shows when none does,
7
+ * and `getVisibleElements()` returns only those. Hiding the other items is
8
+ * left to the consumer's CSS.
9
+ *
10
+ * @property filter - Predicate that picks the items the list counts as shown.
4
11
  * @slot - Default slot for the alert list items.
5
12
  * @slot empty-icon - Icon shown when the list is empty.
6
13
  * @slot empty-title - Title shown when the list is empty.
7
14
  * @slot empty-description - Description shown when the list is empty.
8
15
  * @stable
9
16
  */
10
- export declare class ObcAlertList extends LitElement {
17
+ export declare class ObcAlertList extends ObcAlertListBase {
18
+ /** Predicate that picks the items the list counts as shown. */
11
19
  filter: (item: HTMLElement) => boolean;
12
- private oldElementTop;
13
- private mutationObserver;
14
- private intersectionObserver;
15
- private hasRenderedPanel;
16
- _empty: boolean;
17
- private alertItems;
18
- private scrollbar;
19
- firstUpdated(): void;
20
- connectedCallback(): void;
21
- disconnectedCallback(): void;
22
- protected willUpdate(_changedProperties: PropertyValues): void;
23
- private updateEmpty;
24
- private getAlertItems;
25
- private updateOldElementTop;
26
- private setupMutationObserver;
27
- private handleSlotChange;
28
- private handleElementsChange;
29
- getVisibleElements(): {
30
- element: HTMLElement;
31
- index: number;
32
- }[];
33
- render(): import('lit-html').TemplateResult<1>;
34
- static styles: import('lit').CSSResult;
20
+ protected matchesFilter(item: HTMLElement): boolean;
21
+ protected filterChanged(changed: PropertyValues): boolean;
35
22
  }
36
23
  declare global {
37
24
  interface HTMLElementTagNameMap {
@@ -1 +1 @@
1
- {"version":3,"file":"alert-list.d.ts","sourceRoot":"","sources":["../../../src/building-blocks/alert-list/alert-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAA2B,MAAM,KAAK,CAAC;AAIzE,OAAO,yCAAyC,CAAC;AAIjD;;;;;;GAMG;AACH,qBACa,YAAa,SAAQ,UAAU;IACZ,MAAM,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAC7D;IAEP,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,gBAAgB,CAAS;IACxB,MAAM,UAAS;IAGxB,OAAO,CAAC,UAAU,CAAiB;IAGnC,OAAO,CAAC,SAAS,CAAgB;IAExB,YAAY;IAKZ,iBAAiB;IAcjB,oBAAoB;cAWV,UAAU,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAOvE,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,oBAAoB;IAgDrB,kBAAkB,IAAI;QAAC,OAAO,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE;IA4B3D,MAAM;IAqBf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
1
+ {"version":3,"file":"alert-list.d.ts","sourceRoot":"","sources":["../../../src/building-blocks/alert-list/alert-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,KAAK,CAAC;AAGnC,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AACH,qBACa,YAAa,SAAQ,gBAAgB;IAClB,MAAM,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAC7D;cAEY,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;cAIzC,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO;CAGnE;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
@@ -1,156 +1,21 @@
1
1
  import { customElement } from "../../decorator.js";
2
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
3
- import alert_list_default from "./alert-list.css.js";
4
- import "../../components/scrollbar/scrollbar.js";
5
- import { LitElement, html, nothing, unsafeCSS } from "lit";
6
- import { property, query, queryAssignedElements, state } from "lit/decorators.js";
3
+ import { ObcAlertListBase } from "./alert-list-base.js";
4
+ import { property } from "lit/decorators.js";
7
5
  //#region src/building-blocks/alert-list/alert-list.ts
8
- var ObcAlertList = class ObcAlertList extends LitElement {
6
+ var ObcAlertList = class ObcAlertList extends ObcAlertListBase {
9
7
  constructor(..._args) {
10
8
  super(..._args);
11
9
  this.filter = () => true;
12
- this.oldElementTop = /* @__PURE__ */ new Map();
13
- this.mutationObserver = null;
14
- this.intersectionObserver = null;
15
- this.hasRenderedPanel = false;
16
- this._empty = false;
17
10
  }
18
- firstUpdated() {
19
- this.updateEmpty();
20
- this.setupMutationObserver();
11
+ matchesFilter(item) {
12
+ return this.filter(item);
21
13
  }
22
- connectedCallback() {
23
- super.connectedCallback();
24
- const intersectionObserver = new IntersectionObserver((entries) => {
25
- if (entries[0].intersectionRatio === 0) this.hasRenderedPanel = false;
26
- });
27
- intersectionObserver.observe(this);
28
- this.intersectionObserver = intersectionObserver;
29
- this.setupMutationObserver();
30
- }
31
- disconnectedCallback() {
32
- if (this.mutationObserver) {
33
- this.mutationObserver.disconnect();
34
- this.mutationObserver = null;
35
- }
36
- if (this.intersectionObserver) {
37
- this.intersectionObserver.disconnect();
38
- this.intersectionObserver = null;
39
- }
40
- }
41
- willUpdate(_changedProperties) {
42
- if (_changedProperties.has("filter")) {
43
- this.updateEmpty();
44
- this.updateOldElementTop();
45
- }
46
- }
47
- updateEmpty() {
48
- this._empty = this.getAlertItems().length === 0;
49
- }
50
- getAlertItems() {
51
- return this.alertItems.filter(this.filter);
52
- }
53
- updateOldElementTop() {
54
- const elements = this.getAlertItems();
55
- if (elements.length === 0) return;
56
- let top = elements[0].getBoundingClientRect().top;
57
- this.oldElementTop.clear();
58
- elements.forEach((element) => {
59
- const elementRect = element.getBoundingClientRect();
60
- if (elementRect.height === 0) return;
61
- this.oldElementTop.set(element, top);
62
- top += elementRect.height;
63
- });
64
- }
65
- setupMutationObserver() {
66
- if (this.mutationObserver) {
67
- this.mutationObserver.disconnect();
68
- this.mutationObserver = null;
69
- }
70
- this.mutationObserver = new MutationObserver(() => {
71
- this.handleElementsChange();
72
- });
73
- this.alertItems.forEach((element) => {
74
- this.mutationObserver?.observe(element, {
75
- attributes: true,
76
- attributeFilter: ["status", "shelved"]
77
- });
78
- });
79
- }
80
- handleSlotChange() {
81
- this.handleElementsChange();
82
- this.setupMutationObserver();
83
- }
84
- handleElementsChange() {
85
- this.mutationObserver?.takeRecords();
86
- this.updateEmpty();
87
- if (!this.checkVisibility()) return;
88
- const elements = this.getAlertItems();
89
- const oldElementTop = new Map(this.oldElementTop);
90
- requestAnimationFrame(() => {
91
- this.updateOldElementTop();
92
- let hasNewElements = false;
93
- elements.forEach((element) => {
94
- const elementRect = element.getBoundingClientRect();
95
- const oldTop = oldElementTop.get(element);
96
- if (oldTop === void 0) {
97
- element.animateIntro = this.hasRenderedPanel;
98
- hasNewElements = true;
99
- setTimeout(() => {
100
- element.animateIntro = false;
101
- }, 101);
102
- return;
103
- }
104
- const diff = oldTop - elementRect.top;
105
- if (diff === 0) return;
106
- element.style.transform = `translateY(${diff}px)`;
107
- element.style.transition = "none";
108
- element.offsetHeight;
109
- element.style.transition = "transform 100ms ease-in-out";
110
- element.style.transform = "translateY(0px)";
111
- });
112
- this.hasRenderedPanel = true;
113
- if (hasNewElements) setTimeout(() => {
114
- this.updateOldElementTop();
115
- }, 101);
116
- });
117
- }
118
- getVisibleElements() {
119
- const scrollbarRect = this.scrollbar.getBoundingClientRect();
120
- return this.getAlertItems().map((element, index) => ({
121
- element,
122
- index
123
- })).filter(({ element }) => {
124
- const style = window.getComputedStyle(element);
125
- if (style.display === "none" || style.visibility === "hidden") return false;
126
- const elementRect = element.getBoundingClientRect();
127
- return !(elementRect.top < scrollbarRect.top || elementRect.bottom > scrollbarRect.bottom);
128
- });
129
- }
130
- render() {
131
- return html` <obc-scrollbar class="alert-list" id="scrollbar">
132
- <slot @slotchange=${this.handleSlotChange}></slot>
133
- ${this._empty ? html` <div class="empty-list">
134
- <div class="icon">
135
- <slot name="empty-icon"></slot>
136
- </div>
137
- <div class="empty-title">
138
- <slot name="empty-title"></slot>
139
- </div>
140
- <div class="empty-description">
141
- <slot name="empty-description"></slot>
142
- </div>
143
- </div>` : nothing}
144
- </obc-scrollbar>`;
145
- }
146
- static {
147
- this.styles = unsafeCSS(alert_list_default);
14
+ filterChanged(changed) {
15
+ return changed.has("filter");
148
16
  }
149
17
  };
150
18
  __decorate([property({ attribute: false })], ObcAlertList.prototype, "filter", void 0);
151
- __decorate([state()], ObcAlertList.prototype, "_empty", void 0);
152
- __decorate([queryAssignedElements({ flatten: true })], ObcAlertList.prototype, "alertItems", void 0);
153
- __decorate([query("#scrollbar", true)], ObcAlertList.prototype, "scrollbar", void 0);
154
19
  ObcAlertList = __decorate([customElement("obc-alert-list")], ObcAlertList);
155
20
  //#endregion
156
21
  export { ObcAlertList };
@@ -1 +1 @@
1
- {"version":3,"file":"alert-list.js","names":[],"sources":["../../../src/building-blocks/alert-list/alert-list.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, nothing, unsafeCSS} from 'lit';\nimport {queryAssignedElements, query, property, state} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport compentStyle from './alert-list.css?inline';\nimport '../../components/scrollbar/scrollbar.js';\nimport {ObcScrollbar} from '../../components/scrollbar/scrollbar.js';\nimport {ObcAlertMenuItem} from '../../components/alert-menu-item/alert-menu-item.js';\n\n/**\n * @slot - Default slot for the alert list items.\n * @slot empty-icon - Icon shown when the list is empty.\n * @slot empty-title - Title shown when the list is empty.\n * @slot empty-description - Description shown when the list is empty.\n * @stable\n */\n@customElement('obc-alert-list')\nexport class ObcAlertList extends LitElement {\n @property({attribute: false}) filter: (item: HTMLElement) => boolean = () =>\n true;\n\n private oldElementTop: Map<HTMLElement, number> = new Map();\n private mutationObserver: MutationObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private hasRenderedPanel = false;\n @state() _empty = false;\n\n @queryAssignedElements({flatten: true})\n private alertItems!: HTMLElement[];\n\n @query('#scrollbar', true)\n private scrollbar!: ObcScrollbar;\n\n override firstUpdated() {\n this.updateEmpty();\n this.setupMutationObserver();\n }\n\n override connectedCallback() {\n super.connectedCallback();\n const intersectionObserver = new IntersectionObserver((entries) => {\n // If intersectionRatio is 0, the target is out of view\n if (entries[0].intersectionRatio === 0) {\n this.hasRenderedPanel = false;\n }\n });\n intersectionObserver.observe(this);\n this.intersectionObserver = intersectionObserver;\n\n this.setupMutationObserver();\n }\n\n override disconnectedCallback() {\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect();\n this.intersectionObserver = null;\n }\n }\n\n protected override willUpdate(_changedProperties: PropertyValues): void {\n if (_changedProperties.has('filter')) {\n this.updateEmpty();\n this.updateOldElementTop();\n }\n }\n\n private updateEmpty() {\n this._empty = this.getAlertItems().length === 0;\n }\n\n private getAlertItems() {\n return this.alertItems.filter(this.filter);\n }\n\n private updateOldElementTop() {\n const elements = this.getAlertItems();\n if (elements.length === 0) {\n return;\n }\n\n // Get the top of the element,\n // the element may be in an animation\n // we therefor sum the height of each element\n const firstElement = elements[0];\n const firstElementRect = firstElement.getBoundingClientRect();\n let top = firstElementRect.top;\n this.oldElementTop.clear();\n elements.forEach((element) => {\n const elementRect = element.getBoundingClientRect();\n if (elementRect.height === 0) {\n return;\n }\n this.oldElementTop.set(element, top);\n top += elementRect.height;\n });\n }\n\n private setupMutationObserver() {\n if (this.mutationObserver) {\n // Make a new observer to avoid memory leaks\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n this.mutationObserver = new MutationObserver(() => {\n this.handleElementsChange();\n });\n\n const slotElements = this.alertItems;\n slotElements.forEach((element) => {\n // Earlier observed elements are just updated, and not registered twice.\n this.mutationObserver?.observe(element, {\n attributes: true,\n attributeFilter: ['status', 'shelved'],\n });\n });\n }\n\n private handleSlotChange() {\n this.handleElementsChange();\n this.setupMutationObserver();\n }\n\n private handleElementsChange() {\n // Take records to ensure the observer is not triggered again\n this.mutationObserver?.takeRecords();\n this.updateEmpty();\n if (!this.checkVisibility()) {\n return;\n }\n\n const elements = this.getAlertItems();\n // Animate the elements to their new positions\n const oldElementTop: Map<HTMLElement, number> = new Map(this.oldElementTop);\n\n requestAnimationFrame(() => {\n this.updateOldElementTop();\n let hasNewElements = false;\n elements.forEach((element) => {\n const elementRect = element.getBoundingClientRect();\n const oldTop = oldElementTop.get(element);\n if (oldTop === undefined) {\n // New element\n (element as ObcAlertMenuItem).animateIntro = this.hasRenderedPanel;\n hasNewElements = true;\n setTimeout(() => {\n (element as ObcAlertMenuItem).animateIntro = false;\n }, 101);\n return;\n }\n const diff = oldTop - elementRect.top;\n if (diff === 0) return;\n element.style.transform = `translateY(${diff}px)`;\n element.style.transition = 'none';\n\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- the read forces the reflow that restarts the transition\n element.offsetHeight;\n\n // Remove the transition after the animation is complete\n element.style.transition = 'transform 100ms ease-in-out';\n element.style.transform = 'translateY(0px)';\n });\n this.hasRenderedPanel = true;\n if (hasNewElements) {\n setTimeout(() => {\n this.updateOldElementTop();\n }, 101);\n }\n });\n }\n\n public getVisibleElements(): {element: HTMLElement; index: number}[] {\n // Get all slotted elements in the visible tab's scrollbar\n\n const scrollbarRect = this.scrollbar.getBoundingClientRect();\n const slottedElements = this.getAlertItems();\n\n // Filter for only visible elements that are within the scrollbar viewport\n return slottedElements\n .map((element, index) => ({element, index}))\n .filter(({element}) => {\n const style = window.getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden') {\n return false;\n }\n\n // Check if the element is within the scrollbar's viewport\n const elementRect = element.getBoundingClientRect();\n\n // Check if element overlaps with scrollbar viewport\n const isVisible = !(\n elementRect.top < scrollbarRect.top ||\n elementRect.bottom > scrollbarRect.bottom\n );\n\n return isVisible;\n });\n }\n\n override render() {\n return html` <obc-scrollbar class=\"alert-list\" id=\"scrollbar\">\n <slot @slotchange=${this.handleSlotChange}></slot>\n ${\n this._empty\n ? html` <div class=\"empty-list\">\n <div class=\"icon\">\n <slot name=\"empty-icon\"></slot>\n </div>\n <div class=\"empty-title\">\n <slot name=\"empty-title\"></slot>\n </div>\n <div class=\"empty-description\">\n <slot name=\"empty-description\"></slot>\n </div>\n </div>`\n : nothing\n }\n </obc-scrollbar>`;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-list': ObcAlertList;\n }\n}\n"],"mappings":";;;;;;;AAgBO,IAAM,eAAN,MAAM,qBAAqB,WAAW;;;EAEzC,KAAA,eAAA;EAEgD,KAAA,gCAAA,IAAI,IAAI;EACN,KAAA,mBAAA;EACQ,KAAA,uBAAA;EACjC,KAAA,mBAAA;EACT,KAAA,SAAA;;CAQlB,eAAwB;EACtB,KAAK,YAAY;EACjB,KAAK,sBAAsB;CAC7B;CAEA,oBAA6B;EAC3B,MAAM,kBAAkB;EACxB,MAAM,uBAAuB,IAAI,sBAAsB,YAAY;GAEjE,IAAI,QAAQ,EAAE,CAAC,sBAAsB,GACnC,KAAK,mBAAmB;EAE5B,CAAC;EACD,qBAAqB,QAAQ,IAAI;EACjC,KAAK,uBAAuB;EAE5B,KAAK,sBAAsB;CAC7B;CAEA,uBAAgC;EAC9B,IAAI,KAAK,kBAAkB;GACzB,KAAK,iBAAiB,WAAW;GACjC,KAAK,mBAAmB;EAC1B;EACA,IAAI,KAAK,sBAAsB;GAC7B,KAAK,qBAAqB,WAAW;GACrC,KAAK,uBAAuB;EAC9B;CACF;CAEA,WAA8B,oBAA0C;EACtE,IAAI,mBAAmB,IAAI,QAAQ,GAAG;GACpC,KAAK,YAAY;GACjB,KAAK,oBAAoB;EAC3B;CACF;CAEA,cAAsB;EACpB,KAAK,SAAS,KAAK,cAAc,CAAC,CAAC,WAAW;CAChD;CAEA,gBAAwB;EACtB,OAAO,KAAK,WAAW,OAAO,KAAK,MAAM;CAC3C;CAEA,sBAA8B;EAC5B,MAAM,WAAW,KAAK,cAAc;EACpC,IAAI,SAAS,WAAW,GACtB;EAQF,IAAI,MAFiB,SAAS,EACL,CAAa,sBAC5B,CAAA,CAAiB;EAC3B,KAAK,cAAc,MAAM;EACzB,SAAS,SAAS,YAAY;GAC5B,MAAM,cAAc,QAAQ,sBAAsB;GAClD,IAAI,YAAY,WAAW,GACzB;GAEF,KAAK,cAAc,IAAI,SAAS,GAAG;GACnC,OAAO,YAAY;EACrB,CAAC;CACH;CAEA,wBAAgC;EAC9B,IAAI,KAAK,kBAAkB;GAEzB,KAAK,iBAAiB,WAAW;GACjC,KAAK,mBAAmB;EAC1B;EACA,KAAK,mBAAmB,IAAI,uBAAuB;GACjD,KAAK,qBAAqB;EAC5B,CAAC;EAGD,KAD0B,WACb,SAAS,YAAY;GAEhC,KAAK,kBAAkB,QAAQ,SAAS;IACtC,YAAY;IACZ,iBAAiB,CAAC,UAAU,SAAS;GACvC,CAAC;EACH,CAAC;CACH;CAEA,mBAA2B;EACzB,KAAK,qBAAqB;EAC1B,KAAK,sBAAsB;CAC7B;CAEA,uBAA+B;EAE7B,KAAK,kBAAkB,YAAY;EACnC,KAAK,YAAY;EACjB,IAAI,CAAC,KAAK,gBAAgB,GACxB;EAGF,MAAM,WAAW,KAAK,cAAc;EAEpC,MAAM,gBAA0C,IAAI,IAAI,KAAK,aAAa;EAE1E,4BAA4B;GAC1B,KAAK,oBAAoB;GACzB,IAAI,iBAAiB;GACrB,SAAS,SAAS,YAAY;IAC5B,MAAM,cAAc,QAAQ,sBAAsB;IAClD,MAAM,SAAS,cAAc,IAAI,OAAO;IACxC,IAAI,WAAW,KAAA,GAAW;KAExB,QAA8B,eAAe,KAAK;KAClD,iBAAiB;KACjB,iBAAiB;MACf,QAA8B,eAAe;KAC/C,GAAG,GAAG;KACN;IACF;IACA,MAAM,OAAO,SAAS,YAAY;IAClC,IAAI,SAAS,GAAG;IAChB,QAAQ,MAAM,YAAY,cAAc,KAAK;IAC7C,QAAQ,MAAM,aAAa;IAG3B,QAAQ;IAGR,QAAQ,MAAM,aAAa;IAC3B,QAAQ,MAAM,YAAY;GAC5B,CAAC;GACD,KAAK,mBAAmB;GACxB,IAAI,gBACF,iBAAiB;IACf,KAAK,oBAAoB;GAC3B,GAAG,GAAG;EAEV,CAAC;CACH;CAEA,qBAAqE;EAGnE,MAAM,gBAAgB,KAAK,UAAU,sBAAsB;EAI3D,OAHwB,KAAK,cAGtB,CAAA,CACJ,KAAK,SAAS,WAAW;GAAC;GAAS;EAAK,EAAE,CAAC,CAC3C,QAAQ,EAAC,cAAa;GACrB,MAAM,QAAQ,OAAO,iBAAiB,OAAO;GAC7C,IAAI,MAAM,YAAY,UAAU,MAAM,eAAe,UACnD,OAAO;GAIT,MAAM,cAAc,QAAQ,sBAAsB;GAQlD,OAAO,EAJL,YAAY,MAAM,cAAc,OAChC,YAAY,SAAS,cAAc;EAIvC,CAAC;CACL;CAEA,SAAkB;EAChB,OAAO,IAAI;0BACW,KAAK,iBAAiB;QAExC,KAAK,SACD,IAAI;;;;;;;;;;sBAWJ,QACL;;CAEL;;EAEyB,KAAA,SAAA,UAAU,kBAAY;;AACjD;AA9MG,WAAA,CAAA,SAAS,EAAC,WAAW,MAAK,CAAC,CAAA,GAAA,aAAA,WAAA,UAAA,KAAA,CAAA;AAO3B,WAAA,CAAA,MAAM,CAAA,GAAA,aAAA,WAAA,UAAA,KAAA,CAAA;AAEN,WAAA,CAAA,sBAAsB,EAAC,SAAS,KAAI,CAAC,CAAA,GAAA,aAAA,WAAA,cAAA,KAAA,CAAA;AAGrC,WAAA,CAAA,MAAM,cAAc,IAAI,CAAA,GAAA,aAAA,WAAA,aAAA,KAAA,CAAA;AAd1B,eAAA,WAAA,CAAA,cAAc,gBAAgB,CAAA,GAAA,YAAA"}
1
+ {"version":3,"file":"alert-list.js","names":[],"sources":["../../../src/building-blocks/alert-list/alert-list.ts"],"sourcesContent":["import {PropertyValues} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport {ObcAlertListBase} from './alert-list-base.js';\n\n/**\n * `<obc-alert-list>` – Scrolling list of alert items with an empty state.\n *\n * `filter` decides which items count: the empty state shows when none does,\n * and `getVisibleElements()` returns only those. Hiding the other items is\n * left to the consumer's CSS.\n *\n * @property filter - Predicate that picks the items the list counts as shown.\n * @slot - Default slot for the alert list items.\n * @slot empty-icon - Icon shown when the list is empty.\n * @slot empty-title - Title shown when the list is empty.\n * @slot empty-description - Description shown when the list is empty.\n * @stable\n */\n@customElement('obc-alert-list')\nexport class ObcAlertList extends ObcAlertListBase {\n @property({attribute: false}) filter: (item: HTMLElement) => boolean = () =>\n true;\n\n protected override matchesFilter(item: HTMLElement): boolean {\n return this.filter(item);\n }\n\n protected override filterChanged(changed: PropertyValues): boolean {\n return changed.has('filter');\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-list': ObcAlertList;\n }\n}\n"],"mappings":";;;;;AAoBO,IAAM,eAAN,MAAM,qBAAqB,iBAAiB;;;EAE/C,KAAA,eAAA;;CAEF,cAAiC,MAA4B;EAC3D,OAAO,KAAK,OAAO,IAAI;CACzB;CAEA,cAAiC,SAAkC;EACjE,OAAO,QAAQ,IAAI,QAAQ;CAC7B;AACF;AAVG,WAAA,CAAA,SAAS,EAAC,WAAW,MAAK,CAAC,CAAA,GAAA,aAAA,WAAA,UAAA,KAAA,CAAA;AAF7B,eAAA,WAAA,CAAA,cAAc,gBAAgB,CAAA,GAAA,YAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"alert-icon.d.ts","sourceRoot":"","sources":["../../../src/components/alert-icon/alert-icon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAa,cAAc,EAAU,MAAM,KAAK,CAAC;AAGnE,OAAO,uCAAuC,CAAC;AAE/C,OAAO,EACL,SAAS,EACT,aAAa,EACb,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AAMxB,OAAO,yCAAyC,CAAC;AACjD,OAAO,2CAA2C,CAAC;AACnD,OAAO,2CAA2C,CAAC;AACnD,OAAO,4CAA4C,CAAC;AACpD,OAAO,8CAA8C,CAAC;AACtD,OAAO,yCAAyC,CAAC;AACjD,OAAO,2CAA2C,CAAC;AACnD,OAAO,8CAA8C,CAAC;AACtD,OAAO,gDAAgD,CAAC;AACxD,OAAO,wCAAwC,CAAC;AAChD,OAAO,6CAA6C,CAAC;AACrD,OAAO,0CAA0C,CAAC;AAClD,OAAO,+CAA+C,CAAC;AACvD,OAAO,8CAA8C,CAAC;AACtD,OAAO,iDAAiD,CAAC;AACzD,OAAO,gDAAgD,CAAC;AACxD,OAAO,qDAAqD,CAAC;AAE7D,OAAO,oCAAoC,CAAC;AAC5C,OAAO,oCAAoC,CAAC;AAsB5C,OAAO,EAAC,kBAAkB,EAAC,MAAM,uCAAuC,CAAC;AAiGzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBACa,YAAa,SAAQ,UAAU;IAChB,SAAS,EAAE,SAAS,CAAmB;IAEvC,IAAI,CAAC,EAAE,SAAS,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEpB,aAAa,EAAE,aAAa,CAC9B;IAExB,SAAS,CAAC,QAAQ,CAAC,QAAQ,qBAGzB;IAEF,IAAI,qBAAqB,IAAI,qBAAqB,CAUjD;IAED,OAAO,KAAK,cAAc,GAKzB;IAED,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,KAAK,eAAe,GAW1B;IAED,IAAI,IAAI;;;;;;aA6CP;IAED,OAAO,CAAC,gBAAgB;IAoDf,MAAM;IAiBf,OAAgB,MAAM,0BAiDpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
1
+ {"version":3,"file":"alert-icon.d.ts","sourceRoot":"","sources":["../../../src/components/alert-icon/alert-icon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAa,cAAc,EAAU,MAAM,KAAK,CAAC;AAGnE,OAAO,uCAAuC,CAAC;AAE/C,OAAO,EACL,SAAS,EACT,aAAa,EACb,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AAMxB,OAAO,yCAAyC,CAAC;AACjD,OAAO,2CAA2C,CAAC;AACnD,OAAO,2CAA2C,CAAC;AACnD,OAAO,4CAA4C,CAAC;AACpD,OAAO,8CAA8C,CAAC;AACtD,OAAO,yCAAyC,CAAC;AACjD,OAAO,2CAA2C,CAAC;AACnD,OAAO,8CAA8C,CAAC;AACtD,OAAO,gDAAgD,CAAC;AACxD,OAAO,wCAAwC,CAAC;AAChD,OAAO,6CAA6C,CAAC;AACrD,OAAO,0CAA0C,CAAC;AAClD,OAAO,+CAA+C,CAAC;AACvD,OAAO,8CAA8C,CAAC;AACtD,OAAO,iDAAiD,CAAC;AACzD,OAAO,gDAAgD,CAAC;AACxD,OAAO,qDAAqD,CAAC;AAE7D,OAAO,oCAAoC,CAAC;AAC5C,OAAO,oCAAoC,CAAC;AAsB5C,OAAO,EAAC,kBAAkB,EAAC,MAAM,uCAAuC,CAAC;AAiGzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBACa,YAAa,SAAQ,UAAU;IAChB,SAAS,EAAE,SAAS,CAAmB;IAEvC,IAAI,CAAC,EAAE,SAAS,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEpB,aAAa,EAAE,aAAa,CAC9B;IAExB,SAAS,CAAC,QAAQ,CAAC,QAAQ,qBAGzB;IAEF,IAAI,qBAAqB,IAAI,qBAAqB,CAUjD;IAED,OAAO,KAAK,cAAc,GAKzB;IAED,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,KAAK,eAAe,GAW1B;IAED,IAAI,IAAI;;;;;;aAgDP;IAED,OAAO,CAAC,gBAAgB;IAqDf,MAAM;IAiBf,OAAgB,MAAM,0BAiDpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
@@ -152,10 +152,11 @@ var ObcAlertIcon = class ObcAlertIcon extends LitElement {
152
152
  case "unacknowledged": return mapping["alarm-unack"];
153
153
  default: return null;
154
154
  }
155
- else if (this.bamType === AlertType.Warning) {
156
- if (this.active === false) return mapping["warning-rectified"];
157
- else if (this.acknowledged) return mapping["warning-silenced"];
158
- else return mapping["warning-unack"];
155
+ else if (this.bamType === AlertType.Warning) switch (this._effectiveState) {
156
+ case "rectified": return mapping["warning-rectified"];
157
+ case "silenced": return mapping["warning-silenced"];
158
+ case "unacknowledged": return mapping["warning-unack"];
159
+ default: return null;
159
160
  }
160
161
  return null;
161
162
  }
@@ -189,7 +190,7 @@ var ObcAlertIcon = class ObcAlertIcon extends LitElement {
189
190
  default: return nothing;
190
191
  }
191
192
  }
192
- return nothing;
193
+ return this.icon ? html`${this.icon.a}` : nothing;
193
194
  }
194
195
  render() {
195
196
  if (!this._effectiveType) return html`<div>No alarm</div>`;