@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.153 → 2.0.0-next.155

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 (46) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +438 -238
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +295 -37
  4. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.css.js +3 -7
  5. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.css.js.map +1 -1
  6. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.d.ts +133 -13
  7. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.d.ts.map +1 -1
  8. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.js +330 -233
  9. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.js.map +1 -1
  10. package/dist/components/table/table.d.ts.map +1 -1
  11. package/dist/components/table/table.js +10 -2
  12. package/dist/components/table/table.js.map +1 -1
  13. package/dist/components/user-button/user-button.css.js +68 -1
  14. package/dist/components/user-button/user-button.css.js.map +1 -1
  15. package/dist/components/user-button/user-button.d.ts +8 -1
  16. package/dist/components/user-button/user-button.d.ts.map +1 -1
  17. package/dist/components/user-button/user-button.js +12 -3
  18. package/dist/components/user-button/user-button.js.map +1 -1
  19. package/dist/components/user-menu/user-menu.css.js +15 -0
  20. package/dist/components/user-menu/user-menu.css.js.map +1 -1
  21. package/dist/components/user-menu/user-menu.d.ts +22 -2
  22. package/dist/components/user-menu/user-menu.d.ts.map +1 -1
  23. package/dist/components/user-menu/user-menu.js +34 -2
  24. package/dist/components/user-menu/user-menu.js.map +1 -1
  25. package/dist/generated/locales/es-419.d.ts +1 -0
  26. package/dist/generated/locales/es-419.d.ts.map +1 -1
  27. package/dist/generated/locales/es-419.js +1 -0
  28. package/dist/generated/locales/es-419.js.map +1 -1
  29. package/dist/generated/locales/fi-FI.d.ts +1 -0
  30. package/dist/generated/locales/fi-FI.d.ts.map +1 -1
  31. package/dist/generated/locales/fi-FI.js +1 -0
  32. package/dist/generated/locales/fi-FI.js.map +1 -1
  33. package/package.json +2 -2
  34. package/src/components/alert-list-details-experimental/alert-list-details-experimental.css +3 -7
  35. package/src/components/alert-list-details-experimental/alert-list-details-experimental.spec.ts +188 -0
  36. package/src/components/alert-list-details-experimental/alert-list-details-experimental.stories.ts +142 -33
  37. package/src/components/alert-list-details-experimental/alert-list-details-experimental.ts +490 -252
  38. package/src/components/table/table.ts +15 -2
  39. package/src/components/user-button/user-button.css +27 -1
  40. package/src/components/user-button/user-button.stories.ts +29 -0
  41. package/src/components/user-button/user-button.ts +22 -3
  42. package/src/components/user-menu/user-menu.css +8 -0
  43. package/src/components/user-menu/user-menu.stories.ts +53 -0
  44. package/src/components/user-menu/user-menu.ts +55 -4
  45. package/src/generated/locales/es-419.ts +1 -0
  46. package/src/generated/locales/fi-FI.ts +1 -0
@@ -4989,15 +4989,15 @@
4989
4989
  {
4990
4990
  "kind": "variable",
4991
4991
  "name": "ObcAlertListDetailsExperimental",
4992
- "default": "class extends LitElement { constructor() { super(...arguments); this.selectedMode = \"all\"; this.alerts = []; this.showTime = false; this.timeFormatter = (time) => time.toLocaleTimeString(void 0, { hour12: false }); this.small = false; this.defaultExpanded = true; this.expansionOverrides = /* @__PURE__ */ new Map(); this.alertByRowId = /* @__PURE__ */ new Map(); } getVisibleAlerts() { const seen = /* @__PURE__ */ new Set(); return this.alertList.getAllVisibleRows().map((rowId) => this.alertByRowId.get(rowId)).filter((alert) => alert !== void 0).filter((alert) => { if (seen.has(alert.id)) { return false; } seen.add(alert.id); return true; }); } onRowClick(e) { const row = this.alertByRowId.get(e.detail.row.id); if (row) { this.dispatchEvent( new CustomEvent(\"row-click\", { detail: { alert: row } }) ); } } onCellButtonClick(e) { const row = this.alertByRowId.get(e.detail.rowId); if (row) { this.dispatchEvent( new CustomEvent(\"ack-click\", { detail: { alert: row }, bubbles: false }) ); } } onExpandToggle(e) { const overrides = new Map(this.expansionOverrides); overrides.set(e.detail.rowId, e.detail.expanded); this.expansionOverrides = overrides; } isExpanded(rowId) { return this.expansionOverrides.get(rowId) ?? this.defaultExpanded; } get columns() { if (this.small) { const columns = [ { label: \"Status\", key: \"status\", sortDirection: \"desc\", sortable: true, compareFunction: (_a, _b, aRow, bRow) => { const aAlert = this.alertByRowId.get(aRow.id); const bAlert = this.alertByRowId.get(bRow.id); if (aAlert && bAlert) { return comparePriorityAlerts(aAlert, bAlert); } return 0; } } ]; if (this.showTime) { columns.push({ label: \"Activated\", key: \"time\" }); } columns.push({ label: \"ACK-status\", key: \"action\" }); return columns; } else { const columns = [ { label: \"Status\", key: \"status\", sortDirection: \"desc\", sortable: true, compareFunction: (_a, _b, aRow, bRow) => { const aAlert = this.alertByRowId.get(aRow.id); const bAlert = this.alertByRowId.get(bRow.id); if (aAlert && bAlert) { return comparePriorityAlerts(aAlert, bAlert); } return 0; } }, { label: \"ACK-status\", key: \"action\", dividerRight: true } ]; if (this.showTime) { columns.push({ label: \"Activated\", key: \"time\", sortable: true, compareFunction: (_a, _b, aRow, bRow) => { const aAlert = this.alertByRowId.get(aRow.id); const bAlert = this.alertByRowId.get(bRow.id); if (aAlert && bAlert) { const aTime = new Date(aAlert.time); const bTime = new Date(bAlert.time); return aTime.getTime() - bTime.getTime(); } return 0; } }); } columns.push({ label: \"Tag ID\", key: \"tagId\", sortable: true, compareFunction: (a, b) => { const aText = a?.type === ObcTableCellType.Regular ? String(a.text ?? \"\") : \"\"; const bText = b?.type === ObcTableCellType.Regular ? String(b.text ?? \"\") : \"\"; return aText.localeCompare(bText); } }); return columns; } } get metadata() { return getAlertListModeData(this.selectedMode); } get filteredAlerts() { return this.alerts.filter(this.metadata.filter); } buildVisibleRows() { const alerts = this.filteredAlerts; const alertIds = new Set(alerts.map((alert) => alert.id)); const membersByGroupId = /* @__PURE__ */ new Map(); const roots = []; for (const alert of alerts) { const groupIds = (alert.memberOf ?? []).filter( (groupId) => groupId !== alert.id && alertIds.has(groupId) ); if (groupIds.length === 0) { roots.push(alert); continue; } for (const groupId of groupIds) { const members = membersByGroupId.get(groupId) ?? []; members.push(alert); membersByGroupId.set(groupId, members); } } const reachable = /* @__PURE__ */ new Set(); const markReachable = (alert) => { if (reachable.has(alert.id)) { return; } reachable.add(alert.id); for (const member of membersByGroupId.get(alert.id) ?? []) { markReachable(member); } }; roots.forEach(markReachable); for (const alert of alerts) { if (!reachable.has(alert.id)) { roots.push(alert); markReachable(alert); } } const rows = []; this.alertByRowId = /* @__PURE__ */ new Map(); const visit = (alert, level, parentRowId, ancestors) => { const segment = encodeURIComponent(alert.id); const rowId = parentRowId === void 0 ? segment : `${parentRowId}/${segment}`; const members = membersByGroupId.get(alert.id) ?? []; const expandableMembers = members.filter( (member) => !ancestors.has(member.id) ); const expanded = this.isExpanded(rowId); this.alertByRowId.set(rowId, alert); rows.push({ ...this.buildRowCells(alert), id: rowId, parentId: parentRowId, level, expandable: expandableMembers.length > 0, expanded }); if (!expanded) { return; } const nextAncestors = new Set(ancestors).add(alert.id); for (const member of expandableMembers) { visit(member, level + 1, rowId, nextAncestors); } }; for (const alert of roots) { visit(alert, 0, void 0, /* @__PURE__ */ new Set()); } return rows; } buildRowCells(alert) { let action = { type: ObcTableCellType.Regular }; if (!isAcknowledged(alert) && isActive(alert) && requiresAcknowledgement(alert.type)) { if (alert.noAck) { const icon = usesAlarmNoAckIcon(alert.type) ? html`<obi-alarm-noack-iec usecsscolor></obi-alarm-noack-iec>` : html`<obi-warning-noack-iec usecsscolor></obi-warning-noack-iec>`; action = { type: ObcTableCellType.Regular, largeIcon: true, icon, align: \"center\" }; } else { action = { type: ObcTableCellType.Button, text: msg(\"ACK\") }; } } const status = { type: ObcTableCellType.Regular, largeIcon: true, text: alert.text, title: alert.source, noWrap: true, icon: html`<obc-alert-icon .type=${alert.type} .acknowledged=${isAcknowledged(alert)} .active=${isActive(alert)} ></obc-alert-icon>` }; const time = this.showTime ? { type: ObcTableCellType.Regular, text: this.timeFormatter(alert.time), align: \"center\", neutral: true } : void 0; const tagId = this.small ? void 0 : { type: ObcTableCellType.Regular, text: \"#\" + alert.id, align: \"right\" }; return { status, time, action, tagId }; } render() { const selectedList = this.metadata; const data = this.buildVisibleRows(); return html` <div class=\"wrapper ${this.small ? \"small\" : \"\"}\"> ${data.length > 0 ? html` <obc-table class=\"alert-list\" .data=${data} .columns=${this.columns} .striped=${true} .showHeader=${!this.small} @row-click=${this.onRowClick} @cell-button-click=${this.onCellButtonClick} @expand-toggle=${this.onExpandToggle} ></obc-table> <div class=\"spacer\"></div>` : html` <div class=\"empty-list\"> <div class=\"icon\">${selectedList.emptyIcon}</div> <div class=\"empty-title\">${selectedList.emptyTitle}</div> </div>`} </div> `; } }"
4992
+ "default": "class extends LitElement { constructor() { super(...arguments); this.filterMode = \"all\"; this.alerts = []; this.columns = [ statusColumn(), ackColumn({ dividerRight: true }), tagIdColumn() ]; this.showHeader = true; this.defaultExpanded = true; this.expansionOverrides = /* @__PURE__ */ new Map(); this.alertByRowId = /* @__PURE__ */ new Map(); this.allRowIds = /* @__PURE__ */ new Set(); this._cellSlots = []; this.cellSlotsChanged = false; } /** Slot of every cell in a slot column, rows in collapsed groups included. */ get cellSlots() { return this._cellSlots; } willUpdate(changed) { if (!changed.has(\"alerts\") && !changed.has(\"columns\") && !changed.has(\"filterMode\")) { return; } const rows = getAlertRows(this.alerts, this.filterMode); this.allRowIds = new Set(rows.map((row) => row.rowId)); const slotColumns = this.columns.filter(isSlotColumn); const next = getAlertRows(this.alerts, this.filterMode).flatMap( (row) => slotColumns.map((column) => ({ name: alertListCellSlotName(column.key, row.rowId), alert: row.alert, rowId: row.rowId, columnKey: column.key })) ); const unchanged = next.length === this._cellSlots.length && next.every( (slot, index) => slot.name === this._cellSlots[index].name && slot.alert === this._cellSlots[index].alert ); if (!unchanged) { this._cellSlots = next; this.cellSlotsChanged = true; } } updated() { if (this.cellSlotsChanged) { this.cellSlotsChanged = false; this.dispatchEvent( new CustomEvent(\"cell-slots-change\", { detail: this._cellSlots }) ); } } getVisibleAlerts() { const seen = /* @__PURE__ */ new Set(); return this.alertList.getAllVisibleRows().map((rowId) => this.alertByRowId.get(rowId)).filter((alert) => alert !== void 0).filter((alert) => { if (seen.has(alert.id)) { return false; } seen.add(alert.id); return true; }); } onRowClick(e) { const rowId = e.detail.row.id; const alert = this.alertByRowId.get(rowId); if (alert) { this.dispatchEvent( new CustomEvent(\"row-click\", { detail: { alert, rowId } }) ); } } onCellButtonClick(e) { const { rowId, columnKey } = e.detail; const alert = this.alertByRowId.get(rowId); if (alert) { this.dispatchEvent( new CustomEvent(\"cell-click\", { detail: { alert, columnKey: columnKey.slice(TABLE_KEY_PREFIX.length), rowId }, bubbles: false }) ); } } onExpandToggle(e) { const overrides = new Map(this.expansionOverrides); overrides.set(e.detail.rowId, e.detail.expanded); this.expansionOverrides = overrides; } isExpanded(rowId) { return this.expansionOverrides.get(rowId) ?? this.defaultExpanded; } compareRows(compare, aRow, bRow) { const aAlert = this.alertByRowId.get(aRow.id); const bAlert = this.alertByRowId.get(bRow.id); return aAlert && bAlert ? compare(aAlert, bAlert) : 0; } get tableColumns() { return this.columns.map((column) => { const base = { label: column.label, key: TABLE_KEY_PREFIX + column.key, dividerRight: column.dividerRight }; if (isSlotColumn(column)) { return { ...base, renderCell: (_value, row) => html`<slot name=${alertListCellSlotName(column.key, row.id)} ></slot>` }; } const { compare } = column; if (compare) { return { ...base, sortable: true, sortDirection: column.sortDirection, compareFunction: (_a, _b, aRow, bRow) => this.compareRows(compare, aRow, bRow) }; } return base; }); } get gridColumns() { const columnTracks = this.columns.map( (column, index) => column.width ?? (index === 0 ? \"1fr\" : \"min-content\") ); return [...columnTracks, \"min-content\"].join(\" \"); } get metadata() { return getFilterModeData(this.filterMode); } buildVisibleRows() { const rows = walkAlertRows( this.alerts.filter(this.metadata.filter), (rowId) => this.isExpanded(rowId) ); this.alertByRowId = new Map(rows.map((row) => [row.rowId, row.alert])); const highlightedRowId = this.highlightedRowId(); return rows.map((row) => ({ ...this.buildRowCells(row.alert), id: row.rowId, parentId: row.parentRowId, level: row.level, expandable: row.expandable, expanded: this.isExpanded(row.rowId), selected: row.rowId === highlightedRowId })); } /** The selected row, or the nearest visible group row when a collapsed group hides it. */ highlightedRowId() { if (this.selectedRowId === void 0 || !this.allRowIds.has(this.selectedRowId)) { return void 0; } let rowId = this.selectedRowId; while (rowId !== void 0 && !this.alertByRowId.has(rowId)) { rowId = parentRowIdOf(rowId); } return rowId; } buildRowCells(alert) { const cells = {}; for (const column of this.columns) { cells[TABLE_KEY_PREFIX + column.key] = isSlotColumn(column) ? ( // obc-table skips renderCell for an undefined value. { type: ObcTableCellType.Regular } ) : column.cell(alert); } return cells; } slotNames(rows) { const slotColumns = this.columns.filter(isSlotColumn); return rows.flatMap( (row) => slotColumns.map((column) => alertListCellSlotName(column.key, row.id)) ); } render() { const selectedList = this.metadata; const data = this.buildVisibleRows(); return html` <div class=\"wrapper\"> ${data.length > 0 ? html` <obc-table class=\"alert-list\" style=\"--alert-list-grid-columns: ${this.gridColumns}\" .data=${data} .columns=${this.tableColumns} .striped=${true} .showHeader=${this.showHeader} @row-click=${this.onRowClick} @cell-button-click=${this.onCellButtonClick} @expand-toggle=${this.onExpandToggle} > ${repeat( this.slotNames(data), (name) => name, // Forwards the host's slot into the one obc-table renders in the cell. (name) => html`<slot name=${name} slot=${name}></slot>` )} </obc-table> <div class=\"spacer\"></div>` : html` <div class=\"empty-list\"> <div class=\"icon\">${selectedList.emptyIcon}</div> <div class=\"empty-title\">${selectedList.emptyTitle}</div> </div>`} </div> `; } }"
4993
4993
  }
4994
4994
  ],
4995
4995
  "exports": [
4996
4996
  {
4997
4997
  "kind": "js",
4998
- "name": "AlertListMode",
4998
+ "name": "FilterModes",
4999
4999
  "declaration": {
5000
- "name": "AlertListMode",
5000
+ "name": "FilterModes",
5001
5001
  "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5002
5002
  }
5003
5003
  },
@@ -5009,6 +5009,22 @@
5009
5009
  "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5010
5010
  }
5011
5011
  },
5012
+ {
5013
+ "kind": "js",
5014
+ "name": "ackColumn",
5015
+ "declaration": {
5016
+ "name": "ackColumn",
5017
+ "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5018
+ }
5019
+ },
5020
+ {
5021
+ "kind": "js",
5022
+ "name": "alertListCellSlotName",
5023
+ "declaration": {
5024
+ "name": "alertListCellSlotName",
5025
+ "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5026
+ }
5027
+ },
5012
5028
  {
5013
5029
  "kind": "js",
5014
5030
  "name": "canAckFilter",
@@ -5019,9 +5035,41 @@
5019
5035
  },
5020
5036
  {
5021
5037
  "kind": "js",
5022
- "name": "getAlertListModeData",
5038
+ "name": "getAlertRows",
5023
5039
  "declaration": {
5024
- "name": "getAlertListModeData",
5040
+ "name": "getAlertRows",
5041
+ "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5042
+ }
5043
+ },
5044
+ {
5045
+ "kind": "js",
5046
+ "name": "getFilterModeData",
5047
+ "declaration": {
5048
+ "name": "getFilterModeData",
5049
+ "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5050
+ }
5051
+ },
5052
+ {
5053
+ "kind": "js",
5054
+ "name": "statusColumn",
5055
+ "declaration": {
5056
+ "name": "statusColumn",
5057
+ "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5058
+ }
5059
+ },
5060
+ {
5061
+ "kind": "js",
5062
+ "name": "tagIdColumn",
5063
+ "declaration": {
5064
+ "name": "tagIdColumn",
5065
+ "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5066
+ }
5067
+ },
5068
+ {
5069
+ "kind": "js",
5070
+ "name": "timeColumn",
5071
+ "declaration": {
5072
+ "name": "timeColumn",
5025
5073
  "module": "dist/components/alert-list-details-experimental/alert-list-details-experimental.js"
5026
5074
  }
5027
5075
  }
@@ -7833,7 +7881,7 @@
7833
7881
  {
7834
7882
  "kind": "variable",
7835
7883
  "name": "ObcTable",
7836
- "default": "class extends LitElement { constructor() { super(...arguments); this.data = []; this.columns = []; this.rowDivider = false; this.narrowHeader = false; this.showHeader = true; this.striped = false; this.selectable = false; this.selectAllAriaLabel = \"Select all rows\"; this._sortByColumnIdx = void 0; this._sortDirection = \"asc\"; this._selectedRowIds = /* @__PURE__ */ new Set(); this._previousPositions = []; this._hasRenderedRows = false; } get hasHierarchy() { return this.data.some( (row) => row.parentId !== void 0 || (row.level ?? 0) > 0 || row.expandable === true ); } sortWithinSiblings(rows, compare) { const ids = new Set(rows.map((row) => row.id)); const childrenByParent = /* @__PURE__ */ new Map(); const roots = []; for (const row of rows) { const parentId = row.parentId; if (parentId !== void 0 && parentId !== row.id && ids.has(parentId)) { const siblings = childrenByParent.get(parentId) ?? []; siblings.push(row); childrenByParent.set(parentId, siblings); } else { roots.push(row); } } const sorted = []; const visited = /* @__PURE__ */ new Set(); const visit = (siblings) => { for (const row of [...siblings].sort(compare)) { if (visited.has(row.id)) { continue; } visited.add(row.id); sorted.push(row); visit(childrenByParent.get(row.id) ?? []); } }; visit(roots); visit(rows.filter((row) => !visited.has(row.id))); return sorted; } get sortedData() { if (this._sortByColumnIdx === void 0) { return this.data; } const sortByColumn = this.columns[this._sortByColumnIdx]; if (sortByColumn === void 0) { console.warn(\"Sort by column is undefined\"); return this.data; } const sortDirection = this._sortDirection; const compare = (a, b) => { const aValue = a[sortByColumn.key]; const bValue = b[sortByColumn.key]; if (sortDirection === \"asc\") { return sortByColumn.compareFunction( aValue, bValue, a, b ); } else { return sortByColumn.compareFunction( bValue, aValue, b, a ); } }; if (this.hasHierarchy) { return this.sortWithinSiblings(this.data, compare); } const sortedData = [...this.data]; sortedData.sort(compare); return sortedData; } _handleSortClick(column) { if (!column.sortable) { return; } const newSortColumnIdx = this.columns.indexOf(column); if (newSortColumnIdx === this._sortByColumnIdx) { this._sortDirection = this._sortDirection === \"asc\" ? \"desc\" : \"asc\"; } else { this._sortByColumnIdx = newSortColumnIdx; this._sortDirection = \"asc\"; } } _handleRowClick(row) { this.dispatchEvent( new CustomEvent(\"row-click\", { detail: { row } }) ); } _handleExpandToggle(row, expanded) { if (!row.expandable) { return; } this.dispatchEvent( new CustomEvent(\"expand-toggle\", { detail: { rowId: row.id, expanded } }) ); } _renderRowExpander(row) { if (!this.hasHierarchy) { return nothing; } const level = row.level ?? 0; return html`<span class=\"row-expander\" style=\"--row-level: ${level}\" aria-hidden=\"true\" > ${row.expandable ? html`<span class=${classMap({ chevron: true, expanded: row.expanded ?? false })} @click=${(event) => { event.preventDefault(); event.stopPropagation(); this._handleExpandToggle(row, !(row.expanded ?? false)); }} > <obi-chevron-right-google></obi-chevron-right-google> </span>` : nothing} </span>`; } _focusFirstRow() { const firstRow = this.renderRoot.querySelector( 'button[role=\"row\"].grid-row' ); firstRow?.focus(); } _focusLeftHeaderItem() { this._focusHeaderByIndex(0); } _focusHeaderByIndex(index) { const headers = Array.from( this.renderRoot.querySelectorAll( '.grid-header [role=\"columnheader\"]' ) ); if (headers.length === 0) return; const clampedIndex = Math.max(0, Math.min(index, headers.length - 1)); const headerItem = headers[clampedIndex]; const innerButton = headerItem.shadowRoot?.querySelector(\"button\") ?? null; (innerButton ?? headerItem).focus(); } _handleHeaderKeyDown(event) { const key = event.key; if (key === \"ArrowDown\") { this._focusFirstRow(); event.preventDefault(); event.stopPropagation(); return; } if (key !== \"ArrowLeft\" && key !== \"ArrowRight\") { return; } const headers = Array.from( this.renderRoot.querySelectorAll( '.grid-header [role=\"columnheader\"]' ) ); if (headers.length === 0) return; const currentHeaderEl = event.currentTarget; const currentIndex = currentHeaderEl ? headers.indexOf(currentHeaderEl) : -1; if (currentIndex === -1) return; const nextIndex = key === \"ArrowRight\" ? Math.min(currentIndex + 1, headers.length - 1) : Math.max(currentIndex - 1, 0); if (nextIndex !== currentIndex) { this._focusHeaderByIndex(nextIndex); event.preventDefault(); event.stopPropagation(); } } _handleRowKeyDown(event) { const key = event.key; if (this.hasHierarchy && (key === \"ArrowRight\" || key === \"ArrowLeft\") && this._handleRowExpandKey(event, key)) { return; } if (key !== \"ArrowDown\" && key !== \"ArrowUp\" && key !== \"Home\" && key !== \"End\") { return; } const target = event.currentTarget; if (!target) return; const rows = Array.from( this.renderRoot.querySelectorAll( 'button[role=\"row\"].grid-row' ) ); const currentIndex = rows.indexOf(target); if (currentIndex === -1) return; let nextIndex = currentIndex; switch (key) { case \"ArrowDown\": nextIndex = Math.min(currentIndex + 1, rows.length - 1); break; case \"ArrowUp\": if (currentIndex === 0) { this._focusLeftHeaderItem(); event.preventDefault(); event.stopPropagation(); return; } nextIndex = Math.max(currentIndex - 1, 0); break; case \"Home\": nextIndex = 0; break; case \"End\": nextIndex = rows.length - 1; break; } if (nextIndex !== currentIndex) { rows[nextIndex]?.focus(); event.preventDefault(); event.stopPropagation(); } else if (key === \"Home\" || key === \"End\") { event.preventDefault(); event.stopPropagation(); } } _handleRowExpandKey(event, key) { const target = event.currentTarget; const rowId = target?.dataset.rowId; const row = this.sortedData.find((candidate) => candidate.id === rowId); if (!row) return false; const expanded = row.expanded ?? false; if (key === \"ArrowRight\" && row.expandable && !expanded) { this._handleExpandToggle(row, true); } else if (key === \"ArrowLeft\" && row.expandable && expanded) { this._handleExpandToggle(row, false); } else if (key === \"ArrowLeft\") { const parent = this.renderRoot.querySelector( `button[role=\"row\"].grid-row[data-row-id=\"${CSS.escape( row.parentId ?? \"\" )}\"]` ); if (!parent) return false; parent.focus(); } else { return false; } event.preventDefault(); event.stopPropagation(); return true; } _getAllPositions() { const rows = Array.from( this.renderRoot.querySelectorAll( 'button[role=\"row\"].grid-row' ) ); const firstRow = rows[0]; if (!firstRow) { return []; } const firstRowRect = firstRow.getBoundingClientRect(); const firstRowHeight = firstRowRect.height; const computedStyle = getComputedStyle(firstRow); const computedHeight = parseFloat(computedStyle.height); const zoomFactor = computedHeight / firstRowHeight; return rows.map((row) => { const rect = row.getBoundingClientRect(); return { top: rect.top * zoomFactor, height: rect.height * zoomFactor, index: row.getAttribute(\"data-row-id\") ?? \"\", element: row }; }); } _animateRowChanges() { const previousPositions = this._previousPositions; const currentPositions = this._getAllPositions(); currentPositions.forEach((el) => { const previousPosition = previousPositions.find( (p) => p.index === el.index ); if (!previousPosition) { el.element.style.transform = `translateY(-${el.height}px)`; el.element.style.opacity = \"0\"; } else { el.element.style.transform = `translateY(${previousPosition.top - el.top}px)`; } el.element.style.transition = \"none\"; el.element.offsetHeight; el.element.style.transition = \"transform 100ms ease-in-out, opacity 100ms ease-in-out\"; el.element.style.transform = \"translateY(0px)\"; el.element.style.opacity = \"1\"; }); this._previousPositions = currentPositions; } willUpdate(changedProperties) { if (changedProperties.has(\"defaultSelectedRowIds\")) { if (this.selectedRowIds === void 0 && this._selectedRowIds.size === 0) { this._selectedRowIds = new Set(this.defaultSelectedRowIds ?? []); } } if (changedProperties.has(\"selectedRowIds\")) { if (this.selectedRowIds !== void 0) { this._selectedRowIds = new Set(this.selectedRowIds); } } if (changedProperties.has(\"data\")) { const availableIds = new Set(this.data.map((row) => row.id)); this._selectedRowIds.forEach((id) => { if (!availableIds.has(id)) { this._selectedRowIds.delete(id); } }); } if (changedProperties.has(\"data\") || changedProperties.has(\"_sortByColumnIdx\") || changedProperties.has(\"_sortDirection\")) { if (this._hasRenderedRows) { this._updatePositions(); } else { this.updateComplete.then(() => { this._hasRenderedRows = true; }); } } } updated(changedProperties) { if (changedProperties.has(\"columns\")) { this._sortByColumnIdx = this.columns.findIndex( (col) => \"sortDirection\" in col && col.sortDirection !== void 0 ); if (this._sortByColumnIdx === -1) { this._sortByColumnIdx = void 0; this._sortDirection = \"asc\"; } else { this._sortDirection = this.columns[this._sortByColumnIdx]?.sortDirection ?? \"asc\"; } } if (changedProperties.has(\"data\") || changedProperties.has(\"_sortByColumnIdx\") || changedProperties.has(\"_sortDirection\")) { if (this._hasRenderedRows) { this._animateRowChanges(); } } } _updatePositions() { const positions = this._getAllPositions(); this._previousPositions = positions; } render() { const effectiveColumns = this.selectable ? [ { label: \"\", key: \"__selection__\" }, ...this.columns ] : this.columns; const selectionColumnCount = this.selectable ? Math.max(0, effectiveColumns.length - 1) : effectiveColumns.length; return html` <div class=${classMap({ \"grid-container\": true, \"has-selection-column\": this.selectable })} part=\"grid\" style=\" --grid-columns: ${effectiveColumns.length}; --grid-columns-rest: ${selectionColumnCount}; --selection-column-width: var(--menu-navigation-components-table-item-touch-target-size); \" role=${this.hasHierarchy ? \"treegrid\" : \"table\"} > ${this.showHeader ? html` <div class=\"grid-header\" role=\"row\"> ${effectiveColumns.map((col) => { const isSelectionColumn = this.selectable && col.key === \"__selection__\"; const isNotLast = effectiveColumns.indexOf(col) !== effectiveColumns.length - 1; const icon = col.renderHeaderIcon ? html`<span slot=\"leading-icon\" >${col.renderHeaderIcon()}</span >` : nothing; const columnIndex = this.columns.findIndex( (column) => column.key === col.key ); const sorted = \"sortable\" in col && col.sortable && this._sortByColumnIdx === columnIndex; const sortDirection = sorted ? this._sortDirection : \"none\"; const headerType = col.headerType ?? (this.narrowHeader ? ObcTableHeaderItemType.Narrow : ObcTableHeaderItemType.Regular); if (\"sortable\" in col && col.sortable && !isSelectionColumn) { return html`<obc-table-header-item role=\"columnheader\" class=${isSelectionColumn ? \"selection-header\" : \"\"} .showDivider=${isNotLast} ?hasLeadingIcon=${icon !== nothing} .sortDirection=${sortDirection} .sortable=${true} type=${headerType} @click=${() => this._handleSortClick( col )} @keydown=${this._handleHeaderKeyDown} >${icon}${col.label}</obc-table-header-item > `; } else { if (isSelectionColumn) { return html`<div role=\"columnheader\" class=${classMap({ \"selection-header\": true })} tabindex=\"0\" @keydown=${this._handleHeaderKeyDown} > <obc-checkbox .status=${this._getSelectionStatus()} .disabled=${false} aria-label=${this.selectAllAriaLabel} @click=${(event) => { event.preventDefault(); event.stopPropagation(); }} @change=${() => this._toggleAllSelection()} ></obc-checkbox> </div>`; } return html`<obc-table-header-item role=\"columnheader\" class=${isSelectionColumn ? \"selection-header\" : \"\"} .showDivider=${isNotLast} ?hasLeadingIcon=${icon !== nothing} type=${headerType} >${icon}${col.label}</obc-table-header-item >`; } })} </div> <div class=\"grid-header-divider\"></div> ` : nothing} <div class=\"grid-body\" part=\"body\" style=\"grid-template-rows: repeat(${this.sortedData.length}, min-content)\" > ${repeat( this.sortedData, (row) => row.id, (row, rowIndex) => { const hasDivider = this.rowDivider && this.data.length - 1 !== rowIndex; const isStriped = this.striped && rowIndex % 2 === 1; const isRowSelected = (row.selected ?? false) || this.selectable && this._selectedRowIds.has(row.id); const previousRow = rowIndex > 0 ? this.sortedData[rowIndex - 1] : void 0; const nextRow = rowIndex < this.sortedData.length - 1 ? this.sortedData[rowIndex + 1] : void 0; const hasSelectedPreviousRow = previousRow !== void 0 && ((previousRow.selected ?? false) || this.selectable && this._selectedRowIds.has(previousRow.id)); const hasSelectedNextRow = nextRow !== void 0 && ((nextRow.selected ?? false) || this.selectable && this._selectedRowIds.has(nextRow.id)); return html` <button role=\"row\" class=${classMap({ \"grid-row\": true, selected: isRowSelected, \"selected-with-prev\": isRowSelected && hasSelectedPreviousRow, \"selected-with-next\": isRowSelected && hasSelectedNextRow, striped: isStriped })} @click=${() => this._handleRowClick(row)} @keydown=${this._handleRowKeyDown} data-row-id=${row.id} style=\"grid-row: ${rowIndex + 1}\" part=\"row\" aria-level=${ifDefined( this.hasHierarchy ? (row.level ?? 0) + 1 : void 0 )} aria-expanded=${ifDefined( row.expandable ? row.expanded ?? false : void 0 )} > ${map(effectiveColumns, (col, colIndex) => { const expander = colIndex === (this.selectable ? 1 : 0) ? this._renderRowExpander(row) : nothing; if (this.selectable && col.key === \"__selection__\") { const checked = this._selectedRowIds.has(row.id); return html`<div class=\"grid-cell checkbox align-center selection\" role=\"cell\" > <obc-checkbox .status=${checked ? CheckboxStatus.checked : CheckboxStatus.unchecked} .disabled=${false} aria-label=${`Select row ${row.id}`} @click=${(event) => { event.preventDefault(); event.stopPropagation(); }} @change=${() => this._toggleRowSelection(row.id)} ></obc-checkbox> </div>`; } const value = row[col.key]; if (value === void 0) { return html`<div class=\"grid-cell\" role=\"cell\"> ${expander} </div>`; } if (col.renderCell) { return html`<div class=\"grid-cell ${col.dividerRight ? \"divider-right\" : \"\"}\" role=\"cell\" part=${ifDefined(value.cssPart)} > ${expander}${col.renderCell( value, row, row.id )} </div>`; } else { return this._renderCell( value, row, col, expander ); } })} ${hasDivider ? html`<div class=\"grid-row-divider\"></div>` : nothing} </button> `; } )} ${repeat( effectiveColumns, (col) => col.key, (col, colIndex) => col.dividerRight ? html`<div class=\"grid-column-divider\" style=\"grid-column: ${colIndex + 1}; grid-row: 1/${this.sortedData.length + 1}\" ></div>` : nothing )} </div> </div> `; } getAllVisibleRows() { const rows = Array.from( this.renderRoot.querySelectorAll( 'button[role=\"row\"].grid-row' ) ); const bodyRect = this.renderRoot.querySelector(\".grid-body\")?.getBoundingClientRect(); if (!bodyRect) { return []; } const scrollTop = bodyRect.top; const scrollHeight = bodyRect.height; const scrollBottom = scrollTop + scrollHeight; return rows.filter((el) => el.checkVisibility()).filter( (el) => el.getBoundingClientRect().top >= scrollTop && el.getBoundingClientRect().bottom <= scrollBottom ).map((row) => row.getAttribute(\"data-row-id\")).filter((id) => id !== null); } _handleCellButtonClick(event, row, columnKey) { event.preventDefault(); event.stopPropagation(); const e = new CustomEvent(\"cell-button-click\", { detail: { rowId: row.id, columnKey } }); this.dispatchEvent(e); } _handleCellTagClick(event, row, columnKey, tagId) { event.preventDefault(); event.stopPropagation(); const e = new CustomEvent(\"cell-tag-click\", { detail: { rowId: row.id, columnKey, tagId } }); this.dispatchEvent(e); } _handleCellCheckboxChange(event, row, columnKey) { event.preventDefault(); event.stopPropagation(); const e = new CustomEvent( \"cell-checkbox-change\", { detail: { rowId: row.id, columnKey, status: event.detail.status, disabled: event.detail.disabled } } ); this.dispatchEvent(e); } _getSelectableRowIds() { return this.data.map((row) => row.id); } _getSelectionStatus() { const rowIds = this._getSelectableRowIds(); if (rowIds.length === 0) return CheckboxStatus.unchecked; const selectedCount = rowIds.filter( (id) => this._selectedRowIds.has(id) ).length; if (selectedCount === 0) return CheckboxStatus.unchecked; if (selectedCount === rowIds.length) return CheckboxStatus.checked; return CheckboxStatus.mixed; } _emitSelectionChange(selectedRowIds, source) { const selectedRows = this.data.filter( (row) => selectedRowIds.includes(row.id) ); const e = new CustomEvent( \"selection-change\", { detail: { selectedRowIds, selectedRows, source } } ); this.dispatchEvent(e); } _applySelectionChange(nextSelection, source) { const selectedRowIds = Array.from(nextSelection); this._emitSelectionChange(selectedRowIds, source); if (this.selectedRowIds === void 0) { this._selectedRowIds = nextSelection; this.requestUpdate(); } } _toggleRowSelection(rowId) { const nextSelection = new Set(this._selectedRowIds); if (nextSelection.has(rowId)) { nextSelection.delete(rowId); } else { nextSelection.add(rowId); } this._applySelectionChange(nextSelection, \"row\"); } _toggleAllSelection() { const rowIds = this._getSelectableRowIds(); const status = this._getSelectionStatus(); const nextSelection = status === CheckboxStatus.checked ? /* @__PURE__ */ new Set() : new Set(rowIds); this._applySelectionChange(nextSelection, \"header\"); } _renderCell(value, row, column, expander = nothing) { if (value.type === \"regular\") { return html`<div class=${classMap({ \"grid-cell\": true, regular: true, neutral: value.neutral ?? false, \"large-icon\": value.largeIcon ?? false, \"no-wrap\": value.noWrap ?? false, [`align-${value.align ?? \"left\"}`]: true, \"divider-right\": column.dividerRight ?? false, vertical: value.vertical ?? false })} role=\"cell\" part=${ifDefined(cssPart(value, \"cell\"))} > ${expander}${value.icon3 ? html`<span class=\"icon\" part=${ifDefined(cssPart(value, \"icon3\"))} >${value.icon3}</span >` : nothing} ${value.icon2 ? html`<span class=\"icon\" part=${ifDefined(cssPart(value, \"icon2\"))} >${value.icon2}</span >` : nothing} ${value.icon ? html`<span class=\"icon\" part=${ifDefined(cssPart(value, \"icon\"))} >${value.icon}</span >` : nothing} ${value.title ? html`<span class=\"title\" part=${ifDefined(cssPart(value, \"title\"))} >${value.title}</span >` : nothing} ${value.text ? html`<span part=${ifDefined(cssPart(value, \"text\"))} >${value.text}</span >` : nothing} </div>`; } else if (value.type === \"button\") { return html`<div class=\"grid-cell button ${column.dividerRight ? \"divider-right\" : \"\"}\" role=\"cell\" > ${expander} <obc-button variant=\"normal\" fullWidth .disabled=${value.disabled ?? false} ?showLeadingIcon=${value.icon !== void 0} part=${ifDefined(cssPart(value, \"button\"))} @click=${(event) => this._handleCellButtonClick(event, row, column.key)} > ${value.icon ? html`<span slot=\"leading-icon\" part=${ifDefined(cssPart(value, \"icon\"))} >${value.icon}</span >` : nothing} ${value.text ? html`<span part=${ifDefined(cssPart(value, \"text\"))} >${value.text}</span >` : nothing} </obc-button> </div>`; } else if (value.type === \"checkbox\") { const checkboxLabel = value.label ?? value.text ?? \"\"; const ariaLabel = checkboxLabel.trim() || column.label?.trim() || \"Checkbox\"; return html`<div class=${classMap({ \"grid-cell\": true, checkbox: true, [`align-${value.align ?? \"center\"}`]: true, \"divider-right\": column.dividerRight ?? false })} role=\"cell\" part=${ifDefined(cssPart(value, \"cell\"))} > ${expander} <obc-checkbox .status=${value.status ?? CheckboxStatus.unchecked} .disabled=${value.disabled ?? false} aria-describedby=${ifDefined(value.ariaDescribedBy)} aria-label=${ariaLabel} part=${ifDefined(cssPart(value, \"checkbox\"))} @click=${(event) => { event.preventDefault(); event.stopPropagation(); }} @change=${(event) => this._handleCellCheckboxChange(event, row, column.key)} ></obc-checkbox> </div>`; } else if (value.type === \"tag\") { const tags = value.tags ?? (value.tag ? [value.tag] : void 0) ?? [ { id: value.tagId ?? \"tag\", label: value.label ?? value.text ?? \"Label\", color: value.color, hasIcon: value.hasIcon, icon: value.icon } ]; const wrap = value.wrap ?? value.tags !== void 0; const defaultMaxTags = value.tags ? 2 : void 0; const maxTags = (value.maxTags ?? defaultMaxTags) !== void 0 ? Math.max(0, Math.floor(value.maxTags ?? defaultMaxTags ?? 0)) : void 0; const visibleTags = maxTags !== void 0 ? tags.slice(0, maxTags) : tags; const overflowCount = maxTags !== void 0 ? Math.max(0, tags.length - maxTags) : 0; const overflowLabel = value.overflowLabel ?? `+${overflowCount.toString()}`; return html`<div class=${classMap({ \"grid-cell\": true, tags: tags.length > 1, wrap, [`align-${value.align ?? \"left\"}`]: true, \"divider-right\": column.dividerRight ?? false })} role=\"cell\" part=${ifDefined(cssPart(value, \"cell\"))} > ${expander}${visibleTags.map((tag) => { const hasIcon = tag.hasIcon ?? tag.icon !== void 0; return html`<obc-tag .label=${tag.label} color=${tag.color ?? TagColor.gray} ?hasIcon=${hasIcon} part=${ifDefined( [cssPart(value, \"tag\"), tag.cssPart].filter(Boolean).join(\" \") || void 0 )} @click=${(event) => this._handleCellTagClick(event, row, column.key, tag.id)} > ${hasIcon && tag.icon ? tag.icon : nothing} </obc-tag>`; })} ${overflowCount > 0 ? html`<span class=\"tag-overflow\" part=${ifDefined(cssPart(value, \"tag-overflow\"))} >${overflowLabel}</span >` : nothing} </div>`; } else if (value.type === \"horizontal-bar\") { const hasBar = value.hasBar ?? true; const hasScale = value.hasScale ?? false; const showLabels = !(value.hideLabels ?? true); const fixedAspectRatio = value.fixedAspectRatio ?? true; return html`<div class=${classMap({ \"grid-cell\": true, \"horizontal-bar\": true, [`align-${value.align ?? \"left\"}`]: true, \"divider-right\": column.dividerRight ?? false })} role=\"cell\" part=${ifDefined(cssPart(value, \"cell\"))} > ${expander} <obc-bar-horizontal .minValue=${value.minValue ?? 0} .maxValue=${value.maxValue ?? 100} .value=${value.value} .setpoint=${value.setpoint} .hasBar=${hasBar} .hasScale=${hasScale} .showLabels=${showLabels} .priority=${value.priority ?? Priority.regular} .fillMode=${value.fillMode ?? FillMode.fill} .fillMin=${value.fillMin} .fillMax=${value.fillMax} .barThickness=${value.barThickness ?? 24} .scaleType=${value.scaleType ?? ScaleType.regular} .frameStyle=${value.frameStyle ?? FrameStyle.regular} .side=${value.side ?? ExternalScaleSide.bottom} .state=${value.state ?? InstrumentState.active} .fixedAspectRatio=${fixedAspectRatio} .scaleReferenceSize=${value.scaleReferenceSize ?? 384} part=${ifDefined(cssPart(value, \"bar\"))} ></obc-bar-horizontal> </div>`; } else { return nothing; } } }"
7884
+ "default": "class extends LitElement { constructor() { super(...arguments); this.data = []; this.columns = []; this.rowDivider = false; this.narrowHeader = false; this.showHeader = true; this.striped = false; this.selectable = false; this.selectAllAriaLabel = \"Select all rows\"; this._sortByColumnIdx = void 0; this._sortDirection = \"asc\"; this._selectedRowIds = /* @__PURE__ */ new Set(); this._previousPositions = []; this._hasRenderedRows = false; } get hasHierarchy() { return this.data.some( (row) => row.parentId !== void 0 || (row.level ?? 0) > 0 || row.expandable === true ); } sortWithinSiblings(rows, compare) { const ids = new Set(rows.map((row) => row.id)); const childrenByParent = /* @__PURE__ */ new Map(); const roots = []; for (const row of rows) { const parentId = row.parentId; if (parentId !== void 0 && parentId !== row.id && ids.has(parentId)) { const siblings = childrenByParent.get(parentId) ?? []; siblings.push(row); childrenByParent.set(parentId, siblings); } else { roots.push(row); } } const sorted = []; const visited = /* @__PURE__ */ new Set(); const visit = (siblings) => { for (const row of [...siblings].sort(compare)) { if (visited.has(row.id)) { continue; } visited.add(row.id); sorted.push(row); visit(childrenByParent.get(row.id) ?? []); } }; visit(roots); visit(rows.filter((row) => !visited.has(row.id))); return sorted; } get sortedData() { if (this._sortByColumnIdx === void 0) { return this.data; } const sortByColumn = this.columns[this._sortByColumnIdx]; if (sortByColumn === void 0) { console.warn(\"Sort by column is undefined\"); return this.data; } const sortDirection = this._sortDirection; const compare = (a, b) => { const aValue = a[sortByColumn.key]; const bValue = b[sortByColumn.key]; if (sortDirection === \"asc\") { return sortByColumn.compareFunction( aValue, bValue, a, b ); } else { return sortByColumn.compareFunction( bValue, aValue, b, a ); } }; if (this.hasHierarchy) { return this.sortWithinSiblings(this.data, compare); } const sortedData = [...this.data]; sortedData.sort(compare); return sortedData; } _handleSortClick(column) { if (!column.sortable) { return; } const newSortColumnIdx = this.columns.indexOf(column); if (newSortColumnIdx === this._sortByColumnIdx) { this._sortDirection = this._sortDirection === \"asc\" ? \"desc\" : \"asc\"; } else { this._sortByColumnIdx = newSortColumnIdx; this._sortDirection = \"asc\"; } } _handleRowClick(event, row) { const rowElement = event.currentTarget; for (const node of event.composedPath()) { if (node === rowElement) break; if (node instanceof Element && node.matches(INTERACTIVE_SELECTOR)) { return; } } this.dispatchEvent( new CustomEvent(\"row-click\", { detail: { row } }) ); } _handleExpandToggle(row, expanded) { if (!row.expandable) { return; } this.dispatchEvent( new CustomEvent(\"expand-toggle\", { detail: { rowId: row.id, expanded } }) ); } _renderRowExpander(row) { if (!this.hasHierarchy) { return nothing; } const level = row.level ?? 0; return html`<span class=\"row-expander\" style=\"--row-level: ${level}\" aria-hidden=\"true\" > ${row.expandable ? html`<span class=${classMap({ chevron: true, expanded: row.expanded ?? false })} @click=${(event) => { event.preventDefault(); event.stopPropagation(); this._handleExpandToggle(row, !(row.expanded ?? false)); }} > <obi-chevron-right-google></obi-chevron-right-google> </span>` : nothing} </span>`; } _focusFirstRow() { const firstRow = this.renderRoot.querySelector( 'button[role=\"row\"].grid-row' ); firstRow?.focus(); } _focusLeftHeaderItem() { this._focusHeaderByIndex(0); } _focusHeaderByIndex(index) { const headers = Array.from( this.renderRoot.querySelectorAll( '.grid-header [role=\"columnheader\"]' ) ); if (headers.length === 0) return; const clampedIndex = Math.max(0, Math.min(index, headers.length - 1)); const headerItem = headers[clampedIndex]; const innerButton = headerItem.shadowRoot?.querySelector(\"button\") ?? null; (innerButton ?? headerItem).focus(); } _handleHeaderKeyDown(event) { const key = event.key; if (key === \"ArrowDown\") { this._focusFirstRow(); event.preventDefault(); event.stopPropagation(); return; } if (key !== \"ArrowLeft\" && key !== \"ArrowRight\") { return; } const headers = Array.from( this.renderRoot.querySelectorAll( '.grid-header [role=\"columnheader\"]' ) ); if (headers.length === 0) return; const currentHeaderEl = event.currentTarget; const currentIndex = currentHeaderEl ? headers.indexOf(currentHeaderEl) : -1; if (currentIndex === -1) return; const nextIndex = key === \"ArrowRight\" ? Math.min(currentIndex + 1, headers.length - 1) : Math.max(currentIndex - 1, 0); if (nextIndex !== currentIndex) { this._focusHeaderByIndex(nextIndex); event.preventDefault(); event.stopPropagation(); } } _handleRowKeyDown(event) { const key = event.key; if (this.hasHierarchy && (key === \"ArrowRight\" || key === \"ArrowLeft\") && this._handleRowExpandKey(event, key)) { return; } if (key !== \"ArrowDown\" && key !== \"ArrowUp\" && key !== \"Home\" && key !== \"End\") { return; } const target = event.currentTarget; if (!target) return; const rows = Array.from( this.renderRoot.querySelectorAll( 'button[role=\"row\"].grid-row' ) ); const currentIndex = rows.indexOf(target); if (currentIndex === -1) return; let nextIndex = currentIndex; switch (key) { case \"ArrowDown\": nextIndex = Math.min(currentIndex + 1, rows.length - 1); break; case \"ArrowUp\": if (currentIndex === 0) { this._focusLeftHeaderItem(); event.preventDefault(); event.stopPropagation(); return; } nextIndex = Math.max(currentIndex - 1, 0); break; case \"Home\": nextIndex = 0; break; case \"End\": nextIndex = rows.length - 1; break; } if (nextIndex !== currentIndex) { rows[nextIndex]?.focus(); event.preventDefault(); event.stopPropagation(); } else if (key === \"Home\" || key === \"End\") { event.preventDefault(); event.stopPropagation(); } } _handleRowExpandKey(event, key) { const target = event.currentTarget; const rowId = target?.dataset.rowId; const row = this.sortedData.find((candidate) => candidate.id === rowId); if (!row) return false; const expanded = row.expanded ?? false; if (key === \"ArrowRight\" && row.expandable && !expanded) { this._handleExpandToggle(row, true); } else if (key === \"ArrowLeft\" && row.expandable && expanded) { this._handleExpandToggle(row, false); } else if (key === \"ArrowLeft\") { const parent = this.renderRoot.querySelector( `button[role=\"row\"].grid-row[data-row-id=\"${CSS.escape( row.parentId ?? \"\" )}\"]` ); if (!parent) return false; parent.focus(); } else { return false; } event.preventDefault(); event.stopPropagation(); return true; } _getAllPositions() { const rows = Array.from( this.renderRoot.querySelectorAll( 'button[role=\"row\"].grid-row' ) ); const firstRow = rows[0]; if (!firstRow) { return []; } const firstRowRect = firstRow.getBoundingClientRect(); const firstRowHeight = firstRowRect.height; const computedStyle = getComputedStyle(firstRow); const computedHeight = parseFloat(computedStyle.height); const zoomFactor = computedHeight / firstRowHeight; return rows.map((row) => { const rect = row.getBoundingClientRect(); return { top: rect.top * zoomFactor, height: rect.height * zoomFactor, index: row.getAttribute(\"data-row-id\") ?? \"\", element: row }; }); } _animateRowChanges() { const previousPositions = this._previousPositions; const currentPositions = this._getAllPositions(); currentPositions.forEach((el) => { const previousPosition = previousPositions.find( (p) => p.index === el.index ); if (!previousPosition) { el.element.style.transform = `translateY(-${el.height}px)`; el.element.style.opacity = \"0\"; } else { el.element.style.transform = `translateY(${previousPosition.top - el.top}px)`; } el.element.style.transition = \"none\"; el.element.offsetHeight; el.element.style.transition = \"transform 100ms ease-in-out, opacity 100ms ease-in-out\"; el.element.style.transform = \"translateY(0px)\"; el.element.style.opacity = \"1\"; }); this._previousPositions = currentPositions; } willUpdate(changedProperties) { if (changedProperties.has(\"defaultSelectedRowIds\")) { if (this.selectedRowIds === void 0 && this._selectedRowIds.size === 0) { this._selectedRowIds = new Set(this.defaultSelectedRowIds ?? []); } } if (changedProperties.has(\"selectedRowIds\")) { if (this.selectedRowIds !== void 0) { this._selectedRowIds = new Set(this.selectedRowIds); } } if (changedProperties.has(\"data\")) { const availableIds = new Set(this.data.map((row) => row.id)); this._selectedRowIds.forEach((id) => { if (!availableIds.has(id)) { this._selectedRowIds.delete(id); } }); } if (changedProperties.has(\"data\") || changedProperties.has(\"_sortByColumnIdx\") || changedProperties.has(\"_sortDirection\")) { if (this._hasRenderedRows) { this._updatePositions(); } else { this.updateComplete.then(() => { this._hasRenderedRows = true; }); } } } updated(changedProperties) { if (changedProperties.has(\"columns\")) { this._sortByColumnIdx = this.columns.findIndex( (col) => \"sortDirection\" in col && col.sortDirection !== void 0 ); if (this._sortByColumnIdx === -1) { this._sortByColumnIdx = void 0; this._sortDirection = \"asc\"; } else { this._sortDirection = this.columns[this._sortByColumnIdx]?.sortDirection ?? \"asc\"; } } if (changedProperties.has(\"data\") || changedProperties.has(\"_sortByColumnIdx\") || changedProperties.has(\"_sortDirection\")) { if (this._hasRenderedRows) { this._animateRowChanges(); } } } _updatePositions() { const positions = this._getAllPositions(); this._previousPositions = positions; } render() { const effectiveColumns = this.selectable ? [ { label: \"\", key: \"__selection__\" }, ...this.columns ] : this.columns; const selectionColumnCount = this.selectable ? Math.max(0, effectiveColumns.length - 1) : effectiveColumns.length; return html` <div class=${classMap({ \"grid-container\": true, \"has-selection-column\": this.selectable })} part=\"grid\" style=\" --grid-columns: ${effectiveColumns.length}; --grid-columns-rest: ${selectionColumnCount}; --selection-column-width: var(--menu-navigation-components-table-item-touch-target-size); \" role=${this.hasHierarchy ? \"treegrid\" : \"table\"} > ${this.showHeader ? html` <div class=\"grid-header\" role=\"row\"> ${effectiveColumns.map((col) => { const isSelectionColumn = this.selectable && col.key === \"__selection__\"; const isNotLast = effectiveColumns.indexOf(col) !== effectiveColumns.length - 1; const icon = col.renderHeaderIcon ? html`<span slot=\"leading-icon\" >${col.renderHeaderIcon()}</span >` : nothing; const columnIndex = this.columns.findIndex( (column) => column.key === col.key ); const sorted = \"sortable\" in col && col.sortable && this._sortByColumnIdx === columnIndex; const sortDirection = sorted ? this._sortDirection : \"none\"; const headerType = col.headerType ?? (this.narrowHeader ? ObcTableHeaderItemType.Narrow : ObcTableHeaderItemType.Regular); if (\"sortable\" in col && col.sortable && !isSelectionColumn) { return html`<obc-table-header-item role=\"columnheader\" class=${isSelectionColumn ? \"selection-header\" : \"\"} .showDivider=${isNotLast} ?hasLeadingIcon=${icon !== nothing} .sortDirection=${sortDirection} .sortable=${true} type=${headerType} @click=${() => this._handleSortClick( col )} @keydown=${this._handleHeaderKeyDown} >${icon}${col.label}</obc-table-header-item > `; } else { if (isSelectionColumn) { return html`<div role=\"columnheader\" class=${classMap({ \"selection-header\": true })} tabindex=\"0\" @keydown=${this._handleHeaderKeyDown} > <obc-checkbox .status=${this._getSelectionStatus()} .disabled=${false} aria-label=${this.selectAllAriaLabel} @click=${(event) => { event.preventDefault(); event.stopPropagation(); }} @change=${() => this._toggleAllSelection()} ></obc-checkbox> </div>`; } return html`<obc-table-header-item role=\"columnheader\" class=${isSelectionColumn ? \"selection-header\" : \"\"} .showDivider=${isNotLast} ?hasLeadingIcon=${icon !== nothing} type=${headerType} >${icon}${col.label}</obc-table-header-item >`; } })} </div> <div class=\"grid-header-divider\"></div> ` : nothing} <div class=\"grid-body\" part=\"body\" style=\"grid-template-rows: repeat(${this.sortedData.length}, min-content)\" > ${repeat( this.sortedData, (row) => row.id, (row, rowIndex) => { const hasDivider = this.rowDivider && this.data.length - 1 !== rowIndex; const isStriped = this.striped && rowIndex % 2 === 1; const isRowSelected = (row.selected ?? false) || this.selectable && this._selectedRowIds.has(row.id); const previousRow = rowIndex > 0 ? this.sortedData[rowIndex - 1] : void 0; const nextRow = rowIndex < this.sortedData.length - 1 ? this.sortedData[rowIndex + 1] : void 0; const hasSelectedPreviousRow = previousRow !== void 0 && ((previousRow.selected ?? false) || this.selectable && this._selectedRowIds.has(previousRow.id)); const hasSelectedNextRow = nextRow !== void 0 && ((nextRow.selected ?? false) || this.selectable && this._selectedRowIds.has(nextRow.id)); return html` <button role=\"row\" class=${classMap({ \"grid-row\": true, selected: isRowSelected, \"selected-with-prev\": isRowSelected && hasSelectedPreviousRow, \"selected-with-next\": isRowSelected && hasSelectedNextRow, striped: isStriped })} @click=${(event) => this._handleRowClick(event, row)} @keydown=${this._handleRowKeyDown} data-row-id=${row.id} style=\"grid-row: ${rowIndex + 1}\" part=\"row\" aria-level=${ifDefined( this.hasHierarchy ? (row.level ?? 0) + 1 : void 0 )} aria-expanded=${ifDefined( row.expandable ? row.expanded ?? false : void 0 )} > ${map(effectiveColumns, (col, colIndex) => { const expander = colIndex === (this.selectable ? 1 : 0) ? this._renderRowExpander(row) : nothing; if (this.selectable && col.key === \"__selection__\") { const checked = this._selectedRowIds.has(row.id); return html`<div class=\"grid-cell checkbox align-center selection\" role=\"cell\" > <obc-checkbox .status=${checked ? CheckboxStatus.checked : CheckboxStatus.unchecked} .disabled=${false} aria-label=${`Select row ${row.id}`} @click=${(event) => { event.preventDefault(); event.stopPropagation(); }} @change=${() => this._toggleRowSelection(row.id)} ></obc-checkbox> </div>`; } const value = row[col.key]; if (value === void 0) { return html`<div class=\"grid-cell\" role=\"cell\"> ${expander} </div>`; } if (col.renderCell) { return html`<div class=\"grid-cell ${col.dividerRight ? \"divider-right\" : \"\"}\" role=\"cell\" part=${ifDefined(value.cssPart)} > ${expander}${col.renderCell( value, row, row.id )} </div>`; } else { return this._renderCell( value, row, col, expander ); } })} ${hasDivider ? html`<div class=\"grid-row-divider\"></div>` : nothing} </button> `; } )} ${repeat( effectiveColumns, (col) => col.key, (col, colIndex) => col.dividerRight ? html`<div class=\"grid-column-divider\" style=\"grid-column: ${colIndex + 1}; grid-row: 1/${this.sortedData.length + 1}\" ></div>` : nothing )} </div> </div> `; } getAllVisibleRows() { const rows = Array.from( this.renderRoot.querySelectorAll( 'button[role=\"row\"].grid-row' ) ); const bodyRect = this.renderRoot.querySelector(\".grid-body\")?.getBoundingClientRect(); if (!bodyRect) { return []; } const scrollTop = bodyRect.top; const scrollHeight = bodyRect.height; const scrollBottom = scrollTop + scrollHeight; return rows.filter((el) => el.checkVisibility()).filter( (el) => el.getBoundingClientRect().top >= scrollTop && el.getBoundingClientRect().bottom <= scrollBottom ).map((row) => row.getAttribute(\"data-row-id\")).filter((id) => id !== null); } _handleCellButtonClick(event, row, columnKey) { event.preventDefault(); event.stopPropagation(); const e = new CustomEvent(\"cell-button-click\", { detail: { rowId: row.id, columnKey } }); this.dispatchEvent(e); } _handleCellTagClick(event, row, columnKey, tagId) { event.preventDefault(); event.stopPropagation(); const e = new CustomEvent(\"cell-tag-click\", { detail: { rowId: row.id, columnKey, tagId } }); this.dispatchEvent(e); } _handleCellCheckboxChange(event, row, columnKey) { event.preventDefault(); event.stopPropagation(); const e = new CustomEvent( \"cell-checkbox-change\", { detail: { rowId: row.id, columnKey, status: event.detail.status, disabled: event.detail.disabled } } ); this.dispatchEvent(e); } _getSelectableRowIds() { return this.data.map((row) => row.id); } _getSelectionStatus() { const rowIds = this._getSelectableRowIds(); if (rowIds.length === 0) return CheckboxStatus.unchecked; const selectedCount = rowIds.filter( (id) => this._selectedRowIds.has(id) ).length; if (selectedCount === 0) return CheckboxStatus.unchecked; if (selectedCount === rowIds.length) return CheckboxStatus.checked; return CheckboxStatus.mixed; } _emitSelectionChange(selectedRowIds, source) { const selectedRows = this.data.filter( (row) => selectedRowIds.includes(row.id) ); const e = new CustomEvent( \"selection-change\", { detail: { selectedRowIds, selectedRows, source } } ); this.dispatchEvent(e); } _applySelectionChange(nextSelection, source) { const selectedRowIds = Array.from(nextSelection); this._emitSelectionChange(selectedRowIds, source); if (this.selectedRowIds === void 0) { this._selectedRowIds = nextSelection; this.requestUpdate(); } } _toggleRowSelection(rowId) { const nextSelection = new Set(this._selectedRowIds); if (nextSelection.has(rowId)) { nextSelection.delete(rowId); } else { nextSelection.add(rowId); } this._applySelectionChange(nextSelection, \"row\"); } _toggleAllSelection() { const rowIds = this._getSelectableRowIds(); const status = this._getSelectionStatus(); const nextSelection = status === CheckboxStatus.checked ? /* @__PURE__ */ new Set() : new Set(rowIds); this._applySelectionChange(nextSelection, \"header\"); } _renderCell(value, row, column, expander = nothing) { if (value.type === \"regular\") { return html`<div class=${classMap({ \"grid-cell\": true, regular: true, neutral: value.neutral ?? false, \"large-icon\": value.largeIcon ?? false, \"no-wrap\": value.noWrap ?? false, [`align-${value.align ?? \"left\"}`]: true, \"divider-right\": column.dividerRight ?? false, vertical: value.vertical ?? false })} role=\"cell\" part=${ifDefined(cssPart(value, \"cell\"))} > ${expander}${value.icon3 ? html`<span class=\"icon\" part=${ifDefined(cssPart(value, \"icon3\"))} >${value.icon3}</span >` : nothing} ${value.icon2 ? html`<span class=\"icon\" part=${ifDefined(cssPart(value, \"icon2\"))} >${value.icon2}</span >` : nothing} ${value.icon ? html`<span class=\"icon\" part=${ifDefined(cssPart(value, \"icon\"))} >${value.icon}</span >` : nothing} ${value.title ? html`<span class=\"title\" part=${ifDefined(cssPart(value, \"title\"))} >${value.title}</span >` : nothing} ${value.text ? html`<span part=${ifDefined(cssPart(value, \"text\"))} >${value.text}</span >` : nothing} </div>`; } else if (value.type === \"button\") { return html`<div class=\"grid-cell button ${column.dividerRight ? \"divider-right\" : \"\"}\" role=\"cell\" > ${expander} <obc-button variant=\"normal\" fullWidth .disabled=${value.disabled ?? false} ?showLeadingIcon=${value.icon !== void 0} part=${ifDefined(cssPart(value, \"button\"))} @click=${(event) => this._handleCellButtonClick(event, row, column.key)} > ${value.icon ? html`<span slot=\"leading-icon\" part=${ifDefined(cssPart(value, \"icon\"))} >${value.icon}</span >` : nothing} ${value.text ? html`<span part=${ifDefined(cssPart(value, \"text\"))} >${value.text}</span >` : nothing} </obc-button> </div>`; } else if (value.type === \"checkbox\") { const checkboxLabel = value.label ?? value.text ?? \"\"; const ariaLabel = checkboxLabel.trim() || column.label?.trim() || \"Checkbox\"; return html`<div class=${classMap({ \"grid-cell\": true, checkbox: true, [`align-${value.align ?? \"center\"}`]: true, \"divider-right\": column.dividerRight ?? false })} role=\"cell\" part=${ifDefined(cssPart(value, \"cell\"))} > ${expander} <obc-checkbox .status=${value.status ?? CheckboxStatus.unchecked} .disabled=${value.disabled ?? false} aria-describedby=${ifDefined(value.ariaDescribedBy)} aria-label=${ariaLabel} part=${ifDefined(cssPart(value, \"checkbox\"))} @click=${(event) => { event.preventDefault(); event.stopPropagation(); }} @change=${(event) => this._handleCellCheckboxChange(event, row, column.key)} ></obc-checkbox> </div>`; } else if (value.type === \"tag\") { const tags = value.tags ?? (value.tag ? [value.tag] : void 0) ?? [ { id: value.tagId ?? \"tag\", label: value.label ?? value.text ?? \"Label\", color: value.color, hasIcon: value.hasIcon, icon: value.icon } ]; const wrap = value.wrap ?? value.tags !== void 0; const defaultMaxTags = value.tags ? 2 : void 0; const maxTags = (value.maxTags ?? defaultMaxTags) !== void 0 ? Math.max(0, Math.floor(value.maxTags ?? defaultMaxTags ?? 0)) : void 0; const visibleTags = maxTags !== void 0 ? tags.slice(0, maxTags) : tags; const overflowCount = maxTags !== void 0 ? Math.max(0, tags.length - maxTags) : 0; const overflowLabel = value.overflowLabel ?? `+${overflowCount.toString()}`; return html`<div class=${classMap({ \"grid-cell\": true, tags: tags.length > 1, wrap, [`align-${value.align ?? \"left\"}`]: true, \"divider-right\": column.dividerRight ?? false })} role=\"cell\" part=${ifDefined(cssPart(value, \"cell\"))} > ${expander}${visibleTags.map((tag) => { const hasIcon = tag.hasIcon ?? tag.icon !== void 0; return html`<obc-tag .label=${tag.label} color=${tag.color ?? TagColor.gray} ?hasIcon=${hasIcon} part=${ifDefined( [cssPart(value, \"tag\"), tag.cssPart].filter(Boolean).join(\" \") || void 0 )} @click=${(event) => this._handleCellTagClick(event, row, column.key, tag.id)} > ${hasIcon && tag.icon ? tag.icon : nothing} </obc-tag>`; })} ${overflowCount > 0 ? html`<span class=\"tag-overflow\" part=${ifDefined(cssPart(value, \"tag-overflow\"))} >${overflowLabel}</span >` : nothing} </div>`; } else if (value.type === \"horizontal-bar\") { const hasBar = value.hasBar ?? true; const hasScale = value.hasScale ?? false; const showLabels = !(value.hideLabels ?? true); const fixedAspectRatio = value.fixedAspectRatio ?? true; return html`<div class=${classMap({ \"grid-cell\": true, \"horizontal-bar\": true, [`align-${value.align ?? \"left\"}`]: true, \"divider-right\": column.dividerRight ?? false })} role=\"cell\" part=${ifDefined(cssPart(value, \"cell\"))} > ${expander} <obc-bar-horizontal .minValue=${value.minValue ?? 0} .maxValue=${value.maxValue ?? 100} .value=${value.value} .setpoint=${value.setpoint} .hasBar=${hasBar} .hasScale=${hasScale} .showLabels=${showLabels} .priority=${value.priority ?? Priority.regular} .fillMode=${value.fillMode ?? FillMode.fill} .fillMin=${value.fillMin} .fillMax=${value.fillMax} .barThickness=${value.barThickness ?? 24} .scaleType=${value.scaleType ?? ScaleType.regular} .frameStyle=${value.frameStyle ?? FrameStyle.regular} .side=${value.side ?? ExternalScaleSide.bottom} .state=${value.state ?? InstrumentState.active} .fixedAspectRatio=${fixedAspectRatio} .scaleReferenceSize=${value.scaleReferenceSize ?? 384} part=${ifDefined(cssPart(value, \"bar\"))} ></obc-bar-horizontal> </div>`; } else { return nothing; } } }"
7837
7885
  }
7838
7886
  ],
7839
7887
  "exports": [
@@ -8500,7 +8548,7 @@
8500
8548
  {
8501
8549
  "kind": "variable",
8502
8550
  "name": "ObcUserButton",
8503
- "default": "class extends LitElement { constructor() { super(...arguments); this.variant = \"icon\"; this.size = \"regular\"; this.styleType = \"flat\"; this.static = false; this.disabled = false; this.initials = \"\"; } get formattedInitials() { if (!this.initials) return \"\"; const clean = this.initials.replace(/\\s+/g, \"\").toUpperCase(); const maxInitialsLength = this.size === \"large\" ? 3 : 2; if (clean.length > maxInitialsLength) { console.warn( `Initials \"${this.initials}\" are longer than ${maxInitialsLength} characters.` ); return clean.slice(0, maxInitialsLength); } return clean; } get shouldShowIcon() { return this.variant === \"icon\"; } render() { const styleType = this.size === \"large\" && this.styleType === \"flat\" ? \"normal\" : this.styleType; const wrapperClasses = { wrapper: true, \"wrapper-static\": this.static, [`style-${styleType}`]: true, \"mode-icon\": this.shouldShowIcon, \"mode-initials\": !this.shouldShowIcon, \"state-static\": this.static, [`size-${this.size}`]: true }; const tag = this.static ? literal`div` : literal`button`; const label = this.label && !this.static ? html`<span class=\"user-label\" part=\"label\">${this.label}</span>` : nothing; return html` <${tag} class=${classMap(wrapperClasses)} ?disabled=${this.disabled} aria-label=${this.initials || \"User button\"} > <div class=\"content-container\" part=\"content-container\"> <div class=\"user-button-circle\"> ${this.shouldShowIcon ? html` <div class=\"icon-container\"> <slot name=\"icon\"> <!-- Fallback to default icon if no slot content --> <obi-user></obi-user> </slot> </div> ` : html` <span class=\"user-initials\"> ${this.formattedInitials} </span> `} </div> ${label} </div> </${tag}> `; } }"
8551
+ "default": "class extends LitElement { constructor() { super(...arguments); this.variant = \"icon\"; this.size = \"regular\"; this.styleType = \"flat\"; this.static = false; this.disabled = false; this.initials = \"\"; } get formattedInitials() { if (!this.initials) return \"\"; const clean = this.initials.replace(/\\s+/g, \"\").toUpperCase(); const maxInitialsLength = this.size === \"large\" ? 3 : 2; if (clean.length > maxInitialsLength) { console.warn( `Initials \"${this.initials}\" are longer than ${maxInitialsLength} characters.` ); return clean.slice(0, maxInitialsLength); } return clean; } get shouldShowIcon() { return this.variant === \"icon\"; } render() { const styleType = this.size === \"large\" && this.styleType === \"flat\" ? \"normal\" : this.styleType; const wrapperClasses = { wrapper: true, \"wrapper-static\": this.static, [`style-${styleType}`]: true, \"mode-icon\": this.shouldShowIcon, \"mode-initials\": !this.shouldShowIcon, \"state-static\": this.static, [`size-${this.size}`]: true, \"has-sublabel\": Boolean(this.sublabel) && !this.static }; const tag = this.static ? literal`div` : literal`button`; const visibleText = [this.label, this.sublabel].filter(Boolean).join(\", \"); const accessibleName = !this.static && visibleText || this.initials || \"User button\"; const label = this.label && !this.static ? html`<span class=\"user-label\" part=\"label\">${this.label}</span>` : nothing; const sublabel = this.sublabel && !this.static ? html`<span class=\"user-sublabel\" part=\"sublabel\"> ${this.sublabel} </span>` : nothing; return html` <${tag} class=${classMap(wrapperClasses)} ?disabled=${this.disabled} aria-label=${accessibleName} > <div class=\"content-container\" part=\"content-container\"> <div class=\"user-button-circle\"> ${this.shouldShowIcon ? html` <div class=\"icon-container\"> <slot name=\"icon\"> <!-- Fallback to default icon if no slot content --> <obi-user></obi-user> </slot> </div> ` : html` <span class=\"user-initials\"> ${this.formattedInitials} </span> `} </div> ${label} ${sublabel} </div> </${tag}> `; } }"
8504
8552
  }
8505
8553
  ],
8506
8554
  "exports": [
@@ -8553,7 +8601,7 @@
8553
8601
  {
8554
8602
  "kind": "variable",
8555
8603
  "name": "ObcUserMenu",
8556
- "default": "class extends LitElement { constructor() { super(...arguments); this.type = \"sign-in\"; this.size = \"regular\"; this.hasRecentlySignedIn = false; this.showUsername = true; this.username = \"\"; this.showPassword = true; this.password = \"\"; this.usernameError = \"\"; this.passwordError = \"\"; this.recentUsers = []; this.signedInActions = []; } get showRecentUsers() { return this.hasRecentlySignedIn && this.recentUsers.length > 0; } renderTextInput(placeholder, type = HTMLInputTypeAttribute.Text, value = \"\", onInput, errorText = \"\") { const isPassword = type === HTMLInputTypeAttribute.Password; return html` <obc-text-input-field .placeholder=${placeholder} .type=${type} .textAlign=${ObcTextInputFieldTextAlign.Left} .value=${value} .error=${Boolean(errorText)} .errorText=${errorText} .required=${true} .hasClearButton=${!isPassword} @input=${onInput} > </obc-text-input-field> `; } renderUserButtons(count, isLarge) { const size = isLarge ? Size.large : Size.regular; const users = this.recentUsers.slice(0, count); return html` <div class=${classMap({ users: true, large: isLarge, single: users.length === 1 })} > ${users.map( (user) => html` <obc-user-button .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${size} .initials=${user.initials} .label=${user.label} @click=${() => this.handleRecentUserClick(user)} ></obc-user-button> ` )} </div> `; } renderUserProfile(layout, size) { if (!this.userInitials && !this.userLabel) { return nothing; } const userButtonSize = size === \"large\" ? Size.large : Size.regular; return html` <div class=${classMap({ \"user-profile\": true, [layout]: true })} > <obc-user-button class=${classMap({ \"user-avatar\": true, [`size-${size}`]: true })} .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${userButtonSize} .initials=${this.userInitials ?? \"\"} .label=${this.userLabel ?? \"\"} ></obc-user-button> </div> `; } getSignedInActionIcon(actionId) { switch (actionId) { case \"calendar\": return html`<obi-calendar-google></obi-calendar-google>`; case \"log\": return html`<obi-log-open-google></obi-log-open-google>`; case \"preferences\": return html`<obi-settings-iec></obi-settings-iec>`; case \"user-account\": return html`<obi-user></obi-user>`; default: return nothing; } } normalizeActionId(actionId) { return actionId.trim().toLowerCase().replace(/[^a-z0-9]+/g, \"-\"); } handleSignedInActionClick(action) { this.dispatchEvent( new CustomEvent(\"signed-in-action-click\", { detail: { id: action.id, label: action.label } }) ); } handleRecentUserClick(user) { this.dispatchEvent( new CustomEvent(\"recent-user-click\", { detail: { initials: user.initials, label: user.label } }) ); } handleUsernameInput(event) { const target = event.target; this.username = target.value ?? \"\"; if (this.username) { this.usernameError = \"\"; } } handlePasswordInput(event) { const target = event.target; this.password = target.value ?? \"\"; if (this.password) { this.passwordError = \"\"; } } validateSignIn() { let valid = true; const needsUsername = this.type === \"sign-in\" && this.showUsername; const needsPassword = this.showPassword; if (needsUsername && !this.username) { this.usernameError = msg(\"Username is required\"); valid = false; } if (needsPassword && !this.password) { this.passwordError = msg(\"Password is required\"); valid = false; } return valid; } handleSignInClick() { if (!this.validateSignIn()) { return; } this.dispatchEvent( new CustomEvent(\"sign-in-click\", { detail: { username: this.showUsername ? this.username : void 0, password: this.showPassword ? this.password : void 0 } }) ); } handleSignOutClick() { this.dispatchEvent(new CustomEvent(\"sign-out-click\")); } renderSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderUserSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > <div class=\"user-primary\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"fields\"> ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderUserSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderLoadingSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"vertical\", \"large\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderLoadingSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderSignedIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-primary signed-in\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"divider\" aria-hidden=\"true\"></div> ${this.signedInActions.length ? html` <div class=\"nav-container\"> ${this.signedInActions.map((action) => { const normalizedId = this.normalizeActionId(action.id); return html` <obc-navigation-item .label=${action.label} hasIcon @click=${() => this.handleSignedInActionClick(action)} > <span slot=\"icon\"> <slot name=\"signed-in-action-icon-${normalizedId}\"> ${this.getSignedInActionIcon(normalizedId)} </slot> </span> </obc-navigation-item> `; })} </div> ` : nothing} <div class=\"button-container\"> <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } renderSignedInSmall() { const primaryAction = this.signedInActions.find( (action) => action.id === this.primaryActionId ); return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=\"button-container\"> ${primaryAction ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${() => this.handleSignedInActionClick(primaryAction)} > ${primaryAction.label} </obc-button> ` : nothing} <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } render() { let content = nothing; if (this.type === \"sign-in\") { content = this.size === \"small\" ? this.renderSignInSmall() : this.renderSignIn(); } if (this.type === \"user-sign-in\") { content = this.size === \"small\" ? this.renderUserSignInSmall() : this.renderUserSignIn(); } if (this.type === \"loading-sign-in\") { content = this.size === \"small\" ? this.renderLoadingSignInSmall() : this.renderLoadingSignIn(); } if (this.type === \"signed-in\") { content = this.size === \"small\" ? this.renderSignedInSmall() : this.renderSignedIn(); } return html` <div class=${classMap({ card: true, [`size-${this.size}`]: true, [`type-${this.type}`]: true })} > ${content} </div> `; } }"
8604
+ "default": "class extends LitElement { constructor() { super(...arguments); this.type = \"sign-in\"; this.size = \"regular\"; this.hasRecentlySignedIn = false; this.showUsername = true; this.username = \"\"; this.showPassword = true; this.password = \"\"; this.usernameError = \"\"; this.passwordError = \"\"; this.recentUsers = []; this.signedInActions = []; this.showUseAnotherAccount = true; } get showRecentUsers() { return this.hasRecentlySignedIn && this.recentUsers.length > 0; } renderTextInput(placeholder, type = HTMLInputTypeAttribute.Text, value = \"\", onInput, errorText = \"\") { const isPassword = type === HTMLInputTypeAttribute.Password; return html` <obc-text-input-field .placeholder=${placeholder} .type=${type} .textAlign=${ObcTextInputFieldTextAlign.Left} .value=${value} .error=${Boolean(errorText)} .errorText=${errorText} .required=${true} .hasClearButton=${!isPassword} @input=${onInput} > </obc-text-input-field> `; } renderUserButtons(count, isLarge) { const size = isLarge ? Size.large : Size.regular; const users = this.recentUsers.slice(0, count); return html` <div class=${classMap({ users: true, large: isLarge, single: users.length === 1 })} > ${users.map( (user) => html` <obc-user-button .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${size} .initials=${user.initials} .label=${user.label} .sublabel=${isLarge ? user.role : void 0} @click=${() => this.handleRecentUserClick(user)} ></obc-user-button> ` )} </div> `; } renderUserProfile(layout, size) { if (!this.userInitials && !this.userLabel) { return nothing; } const userButtonSize = size === \"large\" ? Size.large : Size.regular; const role = size === \"large\" ? this.userRole : void 0; return html` <div class=${classMap({ \"user-profile\": true, [layout]: true })} > <obc-user-button class=${classMap({ \"user-avatar\": true, [`size-${size}`]: true, \"has-role\": Boolean(role) })} .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${userButtonSize} .initials=${this.userInitials ?? \"\"} .label=${this.userLabel ?? \"\"} .sublabel=${role} ></obc-user-button> </div> `; } getSignedInActionIcon(actionId) { switch (actionId) { case \"calendar\": return html`<obi-calendar-google></obi-calendar-google>`; case \"log\": return html`<obi-log-open-google></obi-log-open-google>`; case \"preferences\": return html`<obi-settings-iec></obi-settings-iec>`; case \"user-account\": return html`<obi-user></obi-user>`; default: return nothing; } } normalizeActionId(actionId) { return actionId.trim().toLowerCase().replace(/[^a-z0-9]+/g, \"-\"); } handleSignedInActionClick(action) { this.dispatchEvent( new CustomEvent(\"signed-in-action-click\", { detail: { id: action.id, label: action.label } }) ); } handleRecentUserClick(user) { this.dispatchEvent( new CustomEvent(\"recent-user-click\", { detail: { ...user } }) ); } handleUsernameInput(event) { const target = event.target; this.username = target.value ?? \"\"; if (this.username) { this.usernameError = \"\"; } } handlePasswordInput(event) { const target = event.target; this.password = target.value ?? \"\"; if (this.password) { this.passwordError = \"\"; } } validateSignIn() { let valid = true; const needsUsername = this.type === \"sign-in\" && this.showUsername; const needsPassword = this.showPassword; if (needsUsername && !this.username) { this.usernameError = msg(\"Username is required\"); valid = false; } if (needsPassword && !this.password) { this.passwordError = msg(\"Password is required\"); valid = false; } return valid; } handleSignInClick() { if (!this.validateSignIn()) { return; } this.dispatchEvent( new CustomEvent(\"sign-in-click\", { detail: { username: this.showUsername ? this.username : void 0, password: this.showPassword ? this.password : void 0 } }) ); } handleSignOutClick() { this.dispatchEvent(new CustomEvent(\"sign-out-click\")); } handleUseAnotherAccountClick() { this.dispatchEvent(new CustomEvent(\"use-another-account-click\")); } renderSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderUserSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > <div class=\"user-primary\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"fields\"> ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> ${this.showUseAnotherAccount ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleUseAnotherAccountClick} > ${msg(\"Use another account\")} </obc-button> ` : nothing} </div> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderUserSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> ${this.showUseAnotherAccount ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleUseAnotherAccountClick} > ${msg(\"Use another account\")} </obc-button> ` : nothing} </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderLoadingSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"vertical\", \"large\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderLoadingSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderSignedIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-primary signed-in\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"divider\" aria-hidden=\"true\"></div> ${this.signedInActions.length ? html` <div class=\"nav-container\"> ${this.signedInActions.map((action) => { const normalizedId = this.normalizeActionId(action.id); return html` <obc-navigation-item .label=${action.label} hasIcon @click=${() => this.handleSignedInActionClick(action)} > <span slot=\"icon\"> <slot name=\"signed-in-action-icon-${normalizedId}\"> ${this.getSignedInActionIcon(normalizedId)} </slot> </span> </obc-navigation-item> `; })} </div> ` : nothing} <div class=\"button-container\"> <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } renderSignedInSmall() { const primaryAction = this.signedInActions.find( (action) => action.id === this.primaryActionId ); return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=\"button-container\"> ${primaryAction ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${() => this.handleSignedInActionClick(primaryAction)} > ${primaryAction.label} </obc-button> ` : nothing} <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } render() { let content = nothing; if (this.type === \"sign-in\") { content = this.size === \"small\" ? this.renderSignInSmall() : this.renderSignIn(); } if (this.type === \"user-sign-in\") { content = this.size === \"small\" ? this.renderUserSignInSmall() : this.renderUserSignIn(); } if (this.type === \"loading-sign-in\") { content = this.size === \"small\" ? this.renderLoadingSignInSmall() : this.renderLoadingSignIn(); } if (this.type === \"signed-in\") { content = this.size === \"small\" ? this.renderSignedInSmall() : this.renderSignedIn(); } return html` <div class=${classMap({ card: true, [`size-${this.size}`]: true, [`type-${this.type}`]: true })} > ${content} </div> `; } }"
8557
8605
  }
8558
8606
  ],
8559
8607
  "exports": [
@@ -49834,15 +49882,22 @@
49834
49882
  "declarations": [
49835
49883
  {
49836
49884
  "kind": "class",
49837
- "description": "",
49885
+ "description": "`<obc-alert-list-details-experimental>` lists alerts in a table with\nconsumer-defined columns, grouping alerts through `memberOf`.\n\n## Features\n- **Columns:** `columns` sets which columns show and in what order. A data\n column renders each cell from `cell(alert)`; a slot column renders\n whatever the consumer places in the cell's slot.\n- **Column factories:** `statusColumn()`, `ackColumn()`, `timeColumn()` and\n `tagIdColumn()` build the standard data columns; each takes overrides\n such as `label`, `width` or `dividerRight`.\n- **Filter modes:** `filterMode` lists unacknowledged, all, shelved,\n blocked or rectified alerts, with an empty state per filter mode.\n- **Grouping:** an alert listing group ids in `memberOf` renders under each\n of those groups; groups nest and can be collapsed.\n- **Selection:** `selectedRowId` highlights one row. When a collapsed group\n hides it, the nearest visible group row is highlighted instead.\n\n## Usage Guidelines\n- Use a slot column when the cell content must be owned by the consumer,\n for example a button the application disables or removes later. Slotted\n content stays in the light DOM, so it can be looked up by id.\n- Slot names are `cell-<key>:<rowId>`. `cellSlots` lists every one, with its\n alert, row id and column key, and `cell-slots-change` fires when the list\n changes. The Svelte wrapper renders its `cell` snippet once per entry. An\n alert in two groups has two rows, so it gets two entries.\n- Without a wrapper, build the names from `getAlertRows(alerts, filterMode)`\n and `alertListCellSlotName(key, rowId)`, or read `cellSlots`.\n- Clicks on buttons, links and inputs in a cell do not fire `row-click`.\n- The consumer owns the selection: set `selectedRowId` from `row-click`, and\n set it to `undefined` on a second click to unselect. The list never changes\n it; clear it when the row is no longer in `getAlertRows(alerts, filterMode)`.\n\n## Example\n```html\n<obc-alert-list-details-experimental>\n <obc-button slot=\"cell-ack:radar\" id=\"ack-radar\">ACK</obc-button>\n</obc-alert-list-details-experimental>\n```\nwith `columns` set to `[statusColumn(), {key: 'ack', label: 'ACK-status', slot: true}]`.",
49838
49886
  "name": "ObcAlertListDetailsExperimental",
49887
+ "slots": [
49888
+ {
49889
+ "description": "Content of the cell in slot column `<key>` for row `<rowId>`.",
49890
+ "name": "cell-<key>:<rowId>"
49891
+ }
49892
+ ],
49839
49893
  "members": [
49840
49894
  {
49841
49895
  "kind": "field",
49842
- "name": "selectedMode",
49896
+ "name": "filterMode",
49843
49897
  "type": {
49844
- "text": "AlertListMode"
49845
- }
49898
+ "text": "FilterModes"
49899
+ },
49900
+ "description": "Which alerts to list."
49846
49901
  },
49847
49902
  {
49848
49903
  "kind": "field",
@@ -49850,30 +49905,26 @@
49850
49905
  "type": {
49851
49906
  "text": "Alert[]"
49852
49907
  },
49853
- "default": "[]"
49908
+ "default": "[]",
49909
+ "description": "Alerts to list."
49854
49910
  },
49855
49911
  {
49856
49912
  "kind": "field",
49857
- "name": "showTime",
49913
+ "name": "columns",
49858
49914
  "type": {
49859
- "text": "boolean"
49915
+ "text": "AlertListColumn[]"
49860
49916
  },
49861
- "default": "false"
49917
+ "default": "[ statusColumn(), ackColumn({dividerRight: true}), tagIdColumn(), ]",
49918
+ "description": "Columns in display order."
49862
49919
  },
49863
49920
  {
49864
49921
  "kind": "field",
49865
- "name": "timeFormatter",
49866
- "type": {
49867
- "text": "(time: Date) => string"
49868
- }
49869
- },
49870
- {
49871
- "kind": "field",
49872
- "name": "small",
49922
+ "name": "showHeader",
49873
49923
  "type": {
49874
49924
  "text": "boolean"
49875
49925
  },
49876
- "default": "false"
49926
+ "default": "true",
49927
+ "description": "Whether to show the column header row."
49877
49928
  },
49878
49929
  {
49879
49930
  "kind": "field",
@@ -49884,6 +49935,14 @@
49884
49935
  "default": "true",
49885
49936
  "description": "Whether groups start expanded. Set false to open the list collapsed."
49886
49937
  },
49938
+ {
49939
+ "kind": "field",
49940
+ "name": "selectedRowId",
49941
+ "type": {
49942
+ "text": "string | undefined"
49943
+ },
49944
+ "description": "Row id to highlight, as given by `row-click` or `getAlertRows()`. Nothing is highlighted when no row has this id."
49945
+ },
49887
49946
  {
49888
49947
  "kind": "field",
49889
49948
  "name": "alertList",
@@ -49904,6 +49963,55 @@
49904
49963
  "privacy": "private",
49905
49964
  "default": "new Map<string, Alert>()"
49906
49965
  },
49966
+ {
49967
+ "kind": "field",
49968
+ "name": "allRowIds",
49969
+ "privacy": "private",
49970
+ "default": "new Set<string>()"
49971
+ },
49972
+ {
49973
+ "kind": "field",
49974
+ "name": "_cellSlots",
49975
+ "type": {
49976
+ "text": "AlertListCellSlot[]"
49977
+ },
49978
+ "privacy": "private",
49979
+ "default": "[]"
49980
+ },
49981
+ {
49982
+ "kind": "field",
49983
+ "name": "cellSlotsChanged",
49984
+ "type": {
49985
+ "text": "boolean"
49986
+ },
49987
+ "privacy": "private",
49988
+ "default": "false"
49989
+ },
49990
+ {
49991
+ "kind": "field",
49992
+ "name": "cellSlots",
49993
+ "type": {
49994
+ "text": "AlertListCellSlot[]"
49995
+ },
49996
+ "description": "Slot of every cell in a slot column, rows in collapsed groups included.",
49997
+ "readonly": true
49998
+ },
49999
+ {
50000
+ "kind": "method",
50001
+ "name": "willUpdate",
50002
+ "parameters": [
50003
+ {
50004
+ "name": "changed",
50005
+ "type": {
50006
+ "text": "PropertyValues<this>"
50007
+ }
50008
+ }
50009
+ ]
50010
+ },
50011
+ {
50012
+ "kind": "method",
50013
+ "name": "updated"
50014
+ },
49907
50015
  {
49908
50016
  "kind": "method",
49909
50017
  "name": "getVisibleAlerts",
@@ -49966,21 +50074,49 @@
49966
50074
  }
49967
50075
  ]
49968
50076
  },
50077
+ {
50078
+ "kind": "method",
50079
+ "name": "compareRows",
50080
+ "privacy": "private",
50081
+ "parameters": [
50082
+ {
50083
+ "name": "compare",
50084
+ "type": {
50085
+ "text": "(a: Alert, b: Alert) => number"
50086
+ }
50087
+ },
50088
+ {
50089
+ "name": "aRow",
50090
+ "type": {
50091
+ "text": "ObcTableRow"
50092
+ }
50093
+ },
50094
+ {
50095
+ "name": "bRow",
50096
+ "type": {
50097
+ "text": "ObcTableRow"
50098
+ }
50099
+ }
50100
+ ]
50101
+ },
49969
50102
  {
49970
50103
  "kind": "field",
49971
- "name": "columns",
50104
+ "name": "tableColumns",
50105
+ "type": {
50106
+ "text": "ObcTableColumn[]"
50107
+ },
49972
50108
  "privacy": "private",
49973
50109
  "readonly": true
49974
50110
  },
49975
50111
  {
49976
50112
  "kind": "field",
49977
- "name": "metadata",
50113
+ "name": "gridColumns",
49978
50114
  "privacy": "private",
49979
50115
  "readonly": true
49980
50116
  },
49981
50117
  {
49982
50118
  "kind": "field",
49983
- "name": "filteredAlerts",
50119
+ "name": "metadata",
49984
50120
  "privacy": "private",
49985
50121
  "readonly": true
49986
50122
  },
@@ -49994,6 +50130,17 @@
49994
50130
  }
49995
50131
  }
49996
50132
  },
50133
+ {
50134
+ "kind": "method",
50135
+ "name": "highlightedRowId",
50136
+ "privacy": "private",
50137
+ "return": {
50138
+ "type": {
50139
+ "text": "string | undefined"
50140
+ }
50141
+ },
50142
+ "description": "The selected row, or the nearest visible group row when a collapsed group hides it."
50143
+ },
49997
50144
  {
49998
50145
  "kind": "method",
49999
50146
  "name": "buildRowCells",
@@ -50012,6 +50159,19 @@
50012
50159
  }
50013
50160
  ]
50014
50161
  },
50162
+ {
50163
+ "kind": "method",
50164
+ "name": "slotNames",
50165
+ "privacy": "private",
50166
+ "parameters": [
50167
+ {
50168
+ "name": "rows",
50169
+ "type": {
50170
+ "text": "ObcTableRow[]"
50171
+ }
50172
+ }
50173
+ ]
50174
+ },
50015
50175
  {
50016
50176
  "kind": "method",
50017
50177
  "name": "render"
@@ -50025,10 +50185,10 @@
50025
50185
  "events": [
50026
50186
  {
50027
50187
  "type": {
50028
- "text": "ObcAckClickEvent"
50188
+ "text": "ObcAlertListCellClickEvent"
50029
50189
  },
50030
- "description": "Fired when the user clicks the \"ACK\" button.",
50031
- "name": "ack-click"
50190
+ "description": "Fired when the user clicks a button rendered by a data column, such as the one from `ackColumn()`.",
50191
+ "name": "cell-click"
50032
50192
  },
50033
50193
  {
50034
50194
  "type": {
@@ -50036,6 +50196,13 @@
50036
50196
  },
50037
50197
  "description": "Fired when the user clicks a row.",
50038
50198
  "name": "row-click"
50199
+ },
50200
+ {
50201
+ "type": {
50202
+ "text": "ObcAlertListCellSlotsChangeEvent"
50203
+ },
50204
+ "description": "Fired when `cellSlots` changes; the detail is the new list.",
50205
+ "name": "cell-slots-change"
50039
50206
  }
50040
50207
  ],
50041
50208
  "superclass": {
@@ -50048,9 +50215,9 @@
50048
50215
  "exports": [
50049
50216
  {
50050
50217
  "kind": "js",
50051
- "name": "getAlertListModeData",
50218
+ "name": "getFilterModeData",
50052
50219
  "declaration": {
50053
- "name": "getAlertListModeData",
50220
+ "name": "getFilterModeData",
50054
50221
  "module": "src/components/alert-list-details-experimental/alert-list-details-experimental.ts"
50055
50222
  }
50056
50223
  },
@@ -50062,6 +50229,54 @@
50062
50229
  "module": "src/components/alert-list-details-experimental/alert-list-details-experimental.ts"
50063
50230
  }
50064
50231
  },
50232
+ {
50233
+ "kind": "js",
50234
+ "name": "alertListCellSlotName",
50235
+ "declaration": {
50236
+ "name": "alertListCellSlotName",
50237
+ "module": "src/components/alert-list-details-experimental/alert-list-details-experimental.ts"
50238
+ }
50239
+ },
50240
+ {
50241
+ "kind": "js",
50242
+ "name": "statusColumn",
50243
+ "declaration": {
50244
+ "name": "statusColumn",
50245
+ "module": "src/components/alert-list-details-experimental/alert-list-details-experimental.ts"
50246
+ }
50247
+ },
50248
+ {
50249
+ "kind": "js",
50250
+ "name": "ackColumn",
50251
+ "declaration": {
50252
+ "name": "ackColumn",
50253
+ "module": "src/components/alert-list-details-experimental/alert-list-details-experimental.ts"
50254
+ }
50255
+ },
50256
+ {
50257
+ "kind": "js",
50258
+ "name": "timeColumn",
50259
+ "declaration": {
50260
+ "name": "timeColumn",
50261
+ "module": "src/components/alert-list-details-experimental/alert-list-details-experimental.ts"
50262
+ }
50263
+ },
50264
+ {
50265
+ "kind": "js",
50266
+ "name": "tagIdColumn",
50267
+ "declaration": {
50268
+ "name": "tagIdColumn",
50269
+ "module": "src/components/alert-list-details-experimental/alert-list-details-experimental.ts"
50270
+ }
50271
+ },
50272
+ {
50273
+ "kind": "js",
50274
+ "name": "getAlertRows",
50275
+ "declaration": {
50276
+ "name": "getAlertRows",
50277
+ "module": "src/components/alert-list-details-experimental/alert-list-details-experimental.ts"
50278
+ }
50279
+ },
50065
50280
  {
50066
50281
  "kind": "js",
50067
50282
  "name": "ObcAlertListDetailsExperimental",
@@ -67458,6 +67673,12 @@
67458
67673
  "name": "_handleRowClick",
67459
67674
  "privacy": "private",
67460
67675
  "parameters": [
67676
+ {
67677
+ "name": "event",
67678
+ "type": {
67679
+ "text": "MouseEvent"
67680
+ }
67681
+ },
67461
67682
  {
67462
67683
  "name": "row",
67463
67684
  "type": {
@@ -71959,7 +72180,7 @@
71959
72180
  "declarations": [
71960
72181
  {
71961
72182
  "kind": "class",
71962
- "description": "`obc-user-button` – A compact, circular button for representing a user via icon or initials.\n\nDisplays either a user icon or user initials inside a circular button, with optional label text. Commonly used for user profile access, account switching, or avatar actions in toolbars and navigation. The button supports multiple visual styles and can be rendered as a static (non-interactive) element.\n\nAppears as a button by default, but switches to a non-interactive div when the `static` property is set.\n\n## Features\n- **Variants:**\n - `icon`: Shows a user icon (default, fallback if initials are invalid or missing).\n - `initials`: Shows up to two uppercase initials (falls back to icon if input is empty or longer than two characters).\n- **Style Types:**\n - `flat`: Minimal, flat appearance (default).\n - `normal`: Outlined with background and border.\n - `selected`: Highlighted to indicate selection or active state.\n- **Static Mode:**\n - Set `static` to render as a non-interactive element for use in read-only or decorative contexts.\n- **Disabled State:**\n - Set `disabled` to visually and functionally disable the button.\n- **Custom Icon Slot:**\n - Provide a custom icon via the `icon` slot when using the `icon` variant.\n- **Label Support:**\n - Optional `label` property displays text next to the button (not shown in static mode).\n\n## Usage Guidelines\nUse `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.\n- Use the `icon` variant for generic user representation, or when no initials are available.\n- Use the `initials` variant to personalize the button with user initials (max two characters).\n- Use `styleType=\"selected\"` to indicate the current user or active selection.\n- Use `static` for non-interactive displays, such as in lists or summaries.\n- Avoid using for critical actions or as a replacement for full user profile cards.\n\n**TODO(designer):** Confirm if there are recommended scenarios for when to use `flat`, `normal`, or `selected` style types, and if there are accessibility guidelines for initials fallback.\n\n## Slots\n\n| Slot Name | Renders When... | Purpose |\n|-----------|-----------------|---------|\n| `icon` | `variant=\"icon\"` | Custom icon to display instead of the default user icon. |\n\n## Best Practices & Constraints\n- Initials longer than two characters are truncated and a warning is logged.\n- If `initials` is empty or invalid, the button falls back to the user icon.\n- The `label` is only visible when the button is interactive (not static).\n- For accessibility, the button uses `aria-label` based on initials or a default.\n- Only use the `static` property for non-interactive contexts; otherwise, the button is clickable.\n\n## Example:\n```html\n<obc-user-button variant=\"initials\" initials=\"JD\" styleType=\"normal\" label=\"John Doe\"></obc-user-button>\n<obc-user-button variant=\"icon\" styleType=\"flat\">\n <obi-placeholder slot=\"icon\"></obi-placeholder>\n</obc-user-button>\n```",
72183
+ "description": "`obc-user-button` – A compact, circular button for representing a user via icon or initials.\n\nDisplays either a user icon or user initials inside a circular button, with optional label text. Commonly used for user profile access, account switching, or avatar actions in toolbars and navigation. The button supports multiple visual styles and can be rendered as a static (non-interactive) element.\n\nAppears as a button by default, but switches to a non-interactive div when the `static` property is set.\n\n## Features\n- **Variants:**\n - `icon`: Shows a user icon (default, fallback if initials are invalid or missing).\n - `initials`: Shows up to two uppercase initials (falls back to icon if input is empty or longer than two characters).\n- **Style Types:**\n - `flat`: Minimal, flat appearance (default).\n - `normal`: Outlined with background and border.\n - `selected`: Highlighted to indicate selection or active state.\n- **Static Mode:**\n - Set `static` to render as a non-interactive element for use in read-only or decorative contexts.\n- **Disabled State:**\n - Set `disabled` to visually and functionally disable the button.\n- **Custom Icon Slot:**\n - Provide a custom icon via the `icon` slot when using the `icon` variant.\n- **Label Support:**\n - Optional `label` property displays text next to the button (not shown in static mode).\n - Optional `sublabel` adds a second, lighter line under the label, for a\n secondary detail such as the user's role.\n\n## Usage Guidelines\nUse `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.\n- Use the `icon` variant for generic user representation, or when no initials are available.\n- Use the `initials` variant to personalize the button with user initials (max two characters).\n- Use `styleType=\"selected\"` to indicate the current user or active selection.\n- Use `static` for non-interactive displays, such as in lists or summaries.\n- Avoid using for critical actions or as a replacement for full user profile cards.\n\n**TODO(designer):** Confirm if there are recommended scenarios for when to use `flat`, `normal`, or `selected` style types, and if there are accessibility guidelines for initials fallback.\n\n## Slots\n\n| Slot Name | Renders When... | Purpose |\n|-----------|-----------------|---------|\n| `icon` | `variant=\"icon\"` | Custom icon to display instead of the default user icon. |\n\n## Best Practices & Constraints\n- Initials longer than two characters are truncated and a warning is logged.\n- If `initials` is empty or invalid, the button falls back to the user icon.\n- The `label` is only visible when the button is interactive (not static).\n- For accessibility, the button is named after its visible text — `label` and\n `sublabel` falling back to the initials when it shows no text.\n- Only use the `static` property for non-interactive contexts; otherwise, the button is clickable.\n\n## Example:\n```html\n<obc-user-button variant=\"initials\" initials=\"JD\" styleType=\"normal\" label=\"John Doe\"></obc-user-button>\n<obc-user-button variant=\"icon\" styleType=\"flat\">\n <obi-placeholder slot=\"icon\"></obi-placeholder>\n</obc-user-button>\n```",
71963
72184
  "name": "ObcUserButton",
71964
72185
  "slots": [
71965
72186
  {
@@ -72026,6 +72247,14 @@
72026
72247
  },
72027
72248
  "description": "Optional label text to display next to the button (not shown in static mode)."
72028
72249
  },
72250
+ {
72251
+ "kind": "field",
72252
+ "name": "sublabel",
72253
+ "type": {
72254
+ "text": "string | undefined"
72255
+ },
72256
+ "description": "Optional second line under the label, for a secondary detail such as a role (not shown in static mode)."
72257
+ },
72029
72258
  {
72030
72259
  "kind": "field",
72031
72260
  "name": "formattedInitials",
@@ -72072,7 +72301,7 @@
72072
72301
  "declarations": [
72073
72302
  {
72074
72303
  "kind": "class",
72075
- "description": "`<obc-user-menu>` – A user menu component with sign-in and signed-in layouts.\n\nProvides multiple layouts for authentication and account access states, including\nsign-in forms, user-specific sign-in, loading states, and signed-in navigation.\n\n### Features\n- **Multiple States:** Supports sign-in, user sign-in, loading, and signed-in layouts.\n- **Size Options:** Regular and small sizes for compact layouts.\n- **Recent Users:** Optional \"Recently signed in\" section for quick access.\n- **Navigation Actions:** Signed-in state lists the actions it is given.\n\n### Variants\n- `type`: `sign-in`, `user-sign-in`, `loading-sign-in`, `signed-in`\n- `size`: `regular`, `small`\n\n### Usage Guidelines\nUse `obc-user-menu` in authentication or account panels where quick access to\nsign-in, profile, or account actions is needed. The `user-sign-in` type is\nbest for fast re-auth flows; `loading-sign-in` is for pending auth states.\n\n### Properties and Configuration\n- `type` (`ObcUserMenuType`): Controls the layout state. Defaults to `sign-in`.\n- `size` (`ObcUserMenuSize`): Controls the overall size. Defaults to `regular`.\n- `hasRecentlySignedIn` (`boolean`): Toggles the recent users section.\n Defaults to `false`.\n- `showUsername` (`boolean`): Toggles the username field. Defaults to `true`.\n- `showPassword` (`boolean`): Toggles the password field. Defaults to `true`.\n- `username` (`string`): Current username value for sign-in layouts.\n- `password` (`string`): Current password value for sign-in layouts.\n- `usernameError` (`string`): Error message for the username field.\n- `passwordError` (`string`): Error message for the password field.\n- `userInitials` (`string`): Initials for the primary user profile.\n- `userLabel` (`string`): Label for the primary user profile.\n- `recentUsers` (`ObcUserMenuUser[]`): List of recent users shown in the\n \"Recently signed in\" section. Empty renders no section.\n- `signedInActions` (`ObcUserMenuSignedInAction[]`): Actions shown in the\n signed-in navigation list. Empty renders no actions.\n- `primaryActionId` (`string`): Id of the action promoted to a button in the\n small signed-in layout.\n\n### Events\n- `sign-in-click` – Fired when a sign-in button is clicked.\n- `sign-out-click` – Fired when the sign-out button is clicked.\n- `signed-in-action-click` – Fired when a signed-in action is clicked.\n- `recent-user-click` – Fired when a recent user button is clicked.\n\n### Slots\n- `signed-in-action-icon-{id}`: Optional icon for a signed-in action. The\n `{id}` is the normalized action id.\n\n### Example\n```html\n<obc-user-menu\n type=\"user-sign-in\"\n size=\"small\"\n hasRecentlySignedIn=\"false\"\n userInitials=\"JD\"\n userLabel=\"John Doe\"\n></obc-user-menu>\n```",
72304
+ "description": "`<obc-user-menu>` – A user menu component with sign-in and signed-in layouts.\n\nProvides multiple layouts for authentication and account access states, including\nsign-in forms, user-specific sign-in, loading states, and signed-in navigation.\n\n### Features\n- **Multiple States:** Supports sign-in, user sign-in, loading, and signed-in layouts.\n- **Size Options:** Regular and small sizes for compact layouts.\n- **Recent Users:** Optional \"Recently signed in\" section for quick access.\n- **Navigation Actions:** Signed-in state lists the actions it is given.\n\n### Variants\n- `type`: `sign-in`, `user-sign-in`, `loading-sign-in`, `signed-in`\n- `size`: `regular`, `small`\n\n### Usage Guidelines\nUse `obc-user-menu` in authentication or account panels where quick access to\nsign-in, profile, or account actions is needed. The `user-sign-in` type is\nbest for fast re-auth flows; `loading-sign-in` is for pending auth states.\n\n### Properties and Configuration\n- `type` (`ObcUserMenuType`): Controls the layout state. Defaults to `sign-in`.\n- `size` (`ObcUserMenuSize`): Controls the overall size. Defaults to `regular`.\n- `hasRecentlySignedIn` (`boolean`): Toggles the recent users section.\n Defaults to `false`.\n- `showUsername` (`boolean`): Toggles the username field. Defaults to `true`.\n- `showPassword` (`boolean`): Toggles the password field. Defaults to `true`.\n- `username` (`string`): Current username value for sign-in layouts.\n- `password` (`string`): Current password value for sign-in layouts.\n- `usernameError` (`string`): Error message for the username field.\n- `passwordError` (`string`): Error message for the password field.\n- `userInitials` (`string`): Initials for the primary user profile.\n- `userLabel` (`string`): Label for the primary user profile.\n- `userRole` (`string`): Role shown under the primary user's label. Omit it\n to show no role; only the regular size draws one.\n- `recentUsers` (`ObcUserMenuUser[]`): List of recent users shown in the\n \"Recently signed in\" section. Empty renders no section. Each user may\n carry its own `role`.\n- `showUseAnotherAccount` (`boolean`): Toggles the \"Use another account\"\n button in the `user-sign-in` layouts, both sizes. Defaults to `true`.\n- `signedInActions` (`ObcUserMenuSignedInAction[]`): Actions shown in the\n signed-in navigation list. Empty renders no actions.\n- `primaryActionId` (`string`): Id of the action promoted to a button in the\n small signed-in layout.\n\n### Events\n- `sign-in-click` – Fired when a sign-in button is clicked.\n- `sign-out-click` – Fired when the sign-out button is clicked.\n- `use-another-account-click` – Fired when the \"Use another account\" button\n is clicked. The menu does not change its own type; set it to `sign-in` in\n the handler to show the full form.\n- `signed-in-action-click` – Fired when a signed-in action is clicked.\n- `recent-user-click` – Fired when a recent user button is clicked.\n\n### Slots\n- `signed-in-action-icon-{id}`: Optional icon for a signed-in action. The\n `{id}` is the normalized action id.\n\n### Example\n```html\n<obc-user-menu\n type=\"user-sign-in\"\n size=\"small\"\n hasRecentlySignedIn=\"false\"\n userInitials=\"JD\"\n userLabel=\"John Doe\"\n></obc-user-menu>\n```",
72076
72305
  "name": "ObcUserMenu",
72077
72306
  "slots": [
72078
72307
  {
@@ -72176,6 +72405,14 @@
72176
72405
  },
72177
72406
  "description": "Label for the primary user profile."
72178
72407
  },
72408
+ {
72409
+ "kind": "field",
72410
+ "name": "userRole",
72411
+ "type": {
72412
+ "text": "string | undefined"
72413
+ },
72414
+ "description": "Role shown under the primary user's label; omit it to show no role."
72415
+ },
72179
72416
  {
72180
72417
  "kind": "field",
72181
72418
  "name": "recentUsers",
@@ -72202,6 +72439,15 @@
72202
72439
  },
72203
72440
  "description": "Id of the action promoted to a button in the small signed-in layout."
72204
72441
  },
72442
+ {
72443
+ "kind": "field",
72444
+ "name": "showUseAnotherAccount",
72445
+ "type": {
72446
+ "text": "boolean"
72447
+ },
72448
+ "default": "true",
72449
+ "description": "Controls the visibility of the \"Use another account\" button."
72450
+ },
72205
72451
  {
72206
72452
  "kind": "field",
72207
72453
  "name": "showRecentUsers",
@@ -72374,6 +72620,11 @@
72374
72620
  "name": "handleSignOutClick",
72375
72621
  "privacy": "private"
72376
72622
  },
72623
+ {
72624
+ "kind": "method",
72625
+ "name": "handleUseAnotherAccountClick",
72626
+ "privacy": "private"
72627
+ },
72377
72628
  {
72378
72629
  "kind": "method",
72379
72630
  "name": "renderSignIn",
@@ -72435,9 +72686,9 @@
72435
72686
  {
72436
72687
  "name": "recent-user-click",
72437
72688
  "type": {
72438
- "text": "CustomEvent<{initials: string, label: string}>"
72689
+ "text": "ObcUserMenuRecentUserClickEvent"
72439
72690
  },
72440
- "description": "Fired when a recent user button is clicked."
72691
+ "description": "Fired when a recent user button is clicked, carrying that user's entry."
72441
72692
  },
72442
72693
  {
72443
72694
  "name": "sign-in-click",
@@ -72452,6 +72703,13 @@
72452
72703
  "text": "CustomEvent<void>"
72453
72704
  },
72454
72705
  "description": "Fired when the sign-out button is clicked."
72706
+ },
72707
+ {
72708
+ "name": "use-another-account-click",
72709
+ "type": {
72710
+ "text": "CustomEvent<void>"
72711
+ },
72712
+ "description": "Fired when the \"Use another account\" button is clicked."
72455
72713
  }
72456
72714
  ],
72457
72715
  "superclass": {