@oicl/openbridge-webcomponents 2.0.0-next.168 → 2.0.0-next.169

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 (67) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +3352 -2948
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +465 -3
  4. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.d.ts.map +1 -1
  5. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.js +18 -1
  6. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.js.map +1 -1
  7. package/dist/components/alert-menu/alert-menu.css.js +21 -1
  8. package/dist/components/alert-menu/alert-menu.css.js.map +1 -1
  9. package/dist/components/alert-menu/alert-menu.d.ts +14 -0
  10. package/dist/components/alert-menu/alert-menu.d.ts.map +1 -1
  11. package/dist/components/alert-menu/alert-menu.js +10 -0
  12. package/dist/components/alert-menu/alert-menu.js.map +1 -1
  13. package/dist/components/app-menu/app-menu.css.js +23 -1
  14. package/dist/components/app-menu/app-menu.css.js.map +1 -1
  15. package/dist/components/app-menu/app-menu.d.ts +14 -0
  16. package/dist/components/app-menu/app-menu.d.ts.map +1 -1
  17. package/dist/components/app-menu/app-menu.js +17 -1
  18. package/dist/components/app-menu/app-menu.js.map +1 -1
  19. package/dist/components/brilliance-menu/brilliance-menu.css.js +21 -1
  20. package/dist/components/brilliance-menu/brilliance-menu.css.js.map +1 -1
  21. package/dist/components/brilliance-menu/brilliance-menu.d.ts +14 -0
  22. package/dist/components/brilliance-menu/brilliance-menu.d.ts.map +1 -1
  23. package/dist/components/brilliance-menu/brilliance-menu.js +10 -0
  24. package/dist/components/brilliance-menu/brilliance-menu.js.map +1 -1
  25. package/dist/components/command-menu/command-menu.css.js +21 -1
  26. package/dist/components/command-menu/command-menu.css.js.map +1 -1
  27. package/dist/components/command-menu/command-menu.d.ts +14 -0
  28. package/dist/components/command-menu/command-menu.d.ts.map +1 -1
  29. package/dist/components/command-menu/command-menu.js +10 -0
  30. package/dist/components/command-menu/command-menu.js.map +1 -1
  31. package/dist/components/context-menu-input/context-menu-input.css.js +58 -3
  32. package/dist/components/context-menu-input/context-menu-input.css.js.map +1 -1
  33. package/dist/components/context-menu-input/context-menu-input.d.ts +14 -1
  34. package/dist/components/context-menu-input/context-menu-input.d.ts.map +1 -1
  35. package/dist/components/context-menu-input/context-menu-input.js +11 -0
  36. package/dist/components/context-menu-input/context-menu-input.js.map +1 -1
  37. package/dist/components/navigation-menu/navigation-menu.css.js +21 -1
  38. package/dist/components/navigation-menu/navigation-menu.css.js.map +1 -1
  39. package/dist/components/navigation-menu/navigation-menu.d.ts +14 -0
  40. package/dist/components/navigation-menu/navigation-menu.d.ts.map +1 -1
  41. package/dist/components/navigation-menu/navigation-menu.js +10 -0
  42. package/dist/components/navigation-menu/navigation-menu.js.map +1 -1
  43. package/dist/components/system-menu/system-menu.css.js +81 -61
  44. package/dist/components/system-menu/system-menu.css.js.map +1 -1
  45. package/dist/components/system-menu/system-menu.d.ts +14 -0
  46. package/dist/components/system-menu/system-menu.d.ts.map +1 -1
  47. package/dist/components/system-menu/system-menu.js +10 -0
  48. package/dist/components/system-menu/system-menu.js.map +1 -1
  49. package/dist/components/top-bar/top-bar.d.ts +11 -4
  50. package/dist/components/top-bar/top-bar.d.ts.map +1 -1
  51. package/dist/components/top-bar/top-bar.js +18 -10
  52. package/dist/components/top-bar/top-bar.js.map +1 -1
  53. package/dist/components/user-button/user-button.d.ts +1 -0
  54. package/dist/components/user-button/user-button.d.ts.map +1 -1
  55. package/dist/components/user-button/user-button.js +11 -1
  56. package/dist/components/user-button/user-button.js.map +1 -1
  57. package/dist/components/user-menu/user-menu.css.js +21 -1
  58. package/dist/components/user-menu/user-menu.css.js.map +1 -1
  59. package/dist/components/user-menu/user-menu.d.ts +14 -0
  60. package/dist/components/user-menu/user-menu.d.ts.map +1 -1
  61. package/dist/components/user-menu/user-menu.js +10 -0
  62. package/dist/components/user-menu/user-menu.js.map +1 -1
  63. package/dist/internal/popover-controller.d.ts +128 -0
  64. package/dist/internal/popover-controller.d.ts.map +1 -0
  65. package/dist/internal/popover-controller.js +121 -0
  66. package/dist/internal/popover-controller.js.map +1 -0
  67. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"alert-list-details-experimental.js","sources":["../../../src/components/alert-list-details-experimental/alert-list-details-experimental.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, unsafeCSS} from 'lit';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport {customElement} from '../../decorator.js';\nimport compentStyle from './alert-list-details-experimental.css?inline';\nimport {msg} from '@lit/localize';\nimport {property, query, state} from 'lit/decorators.js';\nimport {repeat} from 'lit/directives/repeat.js';\nimport '../icon-button/icon-button.js';\nimport '../button/button.js';\nimport '../../icons/icon-silence-iec.js';\nimport '../../icons/icon-alerts.js';\nimport '../../icons/icon-alerts-shelf.js';\nimport '../../icons/icon-alerts-active.js';\nimport '../../icons/icon-alarm-rectified-iec.js';\nimport '../../icons/icon-unacknowledged.js';\nimport '../../icons/icon-alarm-noack-iec.js';\nimport '../../icons/icon-warning-noack-iec.js';\nimport '../alert-icon/alert-icon.js';\nimport {\n Alert,\n comparePriorityAlerts,\n isActive,\n isAcknowledged,\n isBlocked,\n isShelved,\n} from '../../types.js';\nimport {\n excludedFromUnackedFilter,\n requiresAcknowledgement,\n usesAlarmNoAckIcon,\n} from '../../alert-severity.js';\nimport {\n ObcTable,\n ObcTableCellClickEvent,\n ObcTableCellData,\n ObcTableCellType,\n ObcTableExpandToggleEvent,\n ObcTableRowClickEvent,\n ObcTableRow,\n ObcTableColumn,\n} from '../table/table.js';\nimport '../scrollbar/scrollbar.js';\n\nexport enum FilterModes {\n UNACKED = 'unacked',\n ALL = 'all',\n SHELVED = 'shelved',\n BLOCKED = 'blocked',\n RECTIFIED = 'rectified',\n}\n\nexport type ObcAlertListCellClickEvent = CustomEvent<{\n alert: Alert;\n columnKey: string;\n rowId: string;\n}>;\n\nexport type ObcRowClickEvent = CustomEvent<{\n alert: Alert;\n rowId: string;\n}>;\n\nexport interface AlertListColumnBase {\n /** Unique within the list; part of the cell slot name. */\n key: string;\n label: string;\n /** CSS grid track size. Defaults to `1fr` for the first column, `min-content` for the rest. */\n width?: string;\n dividerRight?: boolean;\n}\n\n/** A column whose cells the list renders from `cell(alert)`. */\nexport interface AlertListDataColumn extends AlertListColumnBase {\n cell: (alert: Alert) => ObcTableCellData | undefined;\n /** Makes the column sortable. */\n compare?: (a: Alert, b: Alert) => number;\n sortDirection?: 'asc' | 'desc';\n}\n\n/** A column whose cells the consumer supplies through `cell-<key>:<rowId>` slots. */\nexport interface AlertListSlotColumn extends AlertListColumnBase {\n slot: true;\n}\n\nexport type AlertListColumn = AlertListDataColumn | AlertListSlotColumn;\n\nexport type AlertListColumnOptions = Partial<AlertListColumnBase>;\n\n/** One cell of a slot column, for every row including rows in collapsed groups. */\nexport interface AlertListCellSlot {\n name: string;\n alert: Alert;\n rowId: string;\n columnKey: string;\n}\n\nexport type ObcAlertListCellSlotsChangeEvent = CustomEvent<AlertListCellSlot[]>;\n\nexport interface AlertListRow {\n rowId: string;\n parentRowId?: string;\n alert: Alert;\n level: number;\n expandable: boolean;\n}\n\nexport function getFilterModeData(filterMode: FilterModes) {\n if (filterMode === FilterModes.ALL)\n return {\n name: FilterModes.ALL,\n title: msg('All'),\n emptyTitle: msg('No active alerts'),\n emptyIcon: html`<obi-alerts></obi-alerts>`,\n filter: (alert: Alert) => !isShelved(alert) && isActive(alert),\n };\n else if (filterMode === FilterModes.UNACKED)\n return {\n name: FilterModes.UNACKED,\n title: msg('Unacked'),\n emptyTitle: msg('No unacknowledged alerts'),\n emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`,\n filter: (alert: Alert) =>\n !isAcknowledged(alert) &&\n isActive(alert) &&\n !excludedFromUnackedFilter(alert.type) &&\n !isShelved(alert),\n };\n else if (filterMode === FilterModes.SHELVED)\n return {\n name: FilterModes.SHELVED,\n title: msg('Shelved'),\n emptyTitle: msg('No shelved alerts'),\n emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`,\n filter: (alert: Alert) => isShelved(alert),\n };\n else if (filterMode === FilterModes.BLOCKED)\n return {\n name: FilterModes.BLOCKED,\n title: msg('Blocked'),\n emptyTitle: msg('No blocked alerts'),\n emptyIcon: html`<obi-alerts-active></obi-alerts-active>`,\n filter: (alert: Alert) => isBlocked(alert),\n };\n else if (filterMode === FilterModes.RECTIFIED)\n return {\n name: FilterModes.RECTIFIED,\n title: msg('Rectified'),\n emptyTitle: msg('No rectified alerts'),\n emptyIcon: html`<obi-alarm-rectified-iec></obi-alarm-rectified-iec>`,\n filter: (alert: Alert) => !isActive(alert),\n };\n else throw new Error('Invalid filter mode');\n}\n\nexport function canAckFilter(filter: (alert: Alert) => boolean) {\n return (alert: Alert) =>\n !isAcknowledged(alert) &&\n !alert.noAck &&\n !excludedFromUnackedFilter(alert.type) &&\n filter(alert);\n}\n\n/** Name of the slot that fills the cell of a slot column in one row. */\nexport function alertListCellSlotName(columnKey: string, rowId: string) {\n // Row ids are URI-encoded too, so neither part can contain the `:` separator.\n return `cell-${encodeURIComponent(columnKey)}:${rowId}`;\n}\n\n/** Alert icon, text and source; sorted by priority. */\nexport function statusColumn(\n options: AlertListColumnOptions = {}\n): AlertListDataColumn {\n return {\n key: 'status',\n label: 'Status',\n sortDirection: 'desc',\n compare: comparePriorityAlerts,\n cell: (alert) => ({\n type: ObcTableCellType.Regular,\n largeIcon: true,\n text: alert.text,\n title: alert.source,\n noWrap: true,\n icon: html`<obc-alert-icon\n .type=${alert.type}\n .acknowledged=${isAcknowledged(alert)}\n .active=${isActive(alert)}\n ></obc-alert-icon>`,\n }),\n ...options,\n };\n}\n\n/** ACK button, or the no-ack icon, for alerts that await acknowledgement. The button fires `cell-click`. */\nexport function ackColumn(\n options: AlertListColumnOptions = {}\n): AlertListDataColumn {\n return {\n key: 'ack',\n label: 'ACK-status',\n cell: (alert) => {\n if (\n isAcknowledged(alert) ||\n !isActive(alert) ||\n !requiresAcknowledgement(alert.type)\n ) {\n return {type: ObcTableCellType.Regular};\n }\n if (alert.noAck) {\n const icon = usesAlarmNoAckIcon(alert.type)\n ? html`<obi-alarm-noack-iec usecsscolor></obi-alarm-noack-iec>`\n : html`<obi-warning-noack-iec usecsscolor></obi-warning-noack-iec>`;\n return {\n type: ObcTableCellType.Regular,\n largeIcon: true,\n icon,\n align: 'center',\n };\n }\n return {type: ObcTableCellType.Button, text: msg('ACK')};\n },\n ...options,\n };\n}\n\n/** Activation time; sorted by time. */\nexport function timeColumn({\n formatter = (time: Date) =>\n time.toLocaleTimeString(undefined, {hour12: false}),\n ...options\n}: AlertListColumnOptions & {\n formatter?: (time: Date) => string;\n} = {}): AlertListDataColumn {\n return {\n key: 'time',\n label: 'Activated',\n compare: (a, b) => new Date(a.time).getTime() - new Date(b.time).getTime(),\n cell: (alert) => ({\n type: ObcTableCellType.Regular,\n text: formatter(alert.time),\n align: 'center',\n neutral: true,\n }),\n ...options,\n };\n}\n\n/** Tag ID prefixed with `#`; sorted alphabetically. */\nexport function tagIdColumn(\n options: AlertListColumnOptions = {}\n): AlertListDataColumn {\n return {\n key: 'tagId',\n label: 'Tag ID',\n compare: (a, b) => a.tagId.localeCompare(b.tagId),\n cell: (alert) => ({\n type: ObcTableCellType.Regular,\n text: '#' + alert.tagId,\n align: 'right',\n }),\n ...options,\n };\n}\n\nfunction isSlotColumn(column: AlertListColumn): column is AlertListSlotColumn {\n return 'slot' in column && column.slot === true;\n}\n\n/** Row ids join URI-encoded alert ids with `/`, so the last `/` separates the parent. */\nfunction parentRowIdOf(rowId: string): string | undefined {\n const separatorIndex = rowId.lastIndexOf('/');\n return separatorIndex === -1 ? undefined : rowId.slice(0, separatorIndex);\n}\n\n/** Keeps column keys clear of the row fields `obc-table` reserves (`id`, `level`, …). */\nconst TABLE_KEY_PREFIX = 'column-';\n\nfunction walkAlertRows(\n alerts: Alert[],\n isExpanded: (rowId: string) => boolean\n): AlertListRow[] {\n const alertIds = new Set(alerts.map((alert) => alert.id));\n const membersByGroupId = new Map<string, Alert[]>();\n const roots: Alert[] = [];\n for (const alert of alerts) {\n const groupIds = (alert.memberOf ?? []).filter(\n (groupId) => groupId !== alert.id && alertIds.has(groupId)\n );\n if (groupIds.length === 0) {\n roots.push(alert);\n continue;\n }\n for (const groupId of groupIds) {\n const members = membersByGroupId.get(groupId) ?? [];\n members.push(alert);\n membersByGroupId.set(groupId, members);\n }\n }\n\n const reachable = new Set<string>();\n const markReachable = (alert: Alert) => {\n if (reachable.has(alert.id)) {\n return;\n }\n reachable.add(alert.id);\n for (const member of membersByGroupId.get(alert.id) ?? []) {\n markReachable(member);\n }\n };\n roots.forEach(markReachable);\n for (const alert of alerts) {\n if (!reachable.has(alert.id)) {\n roots.push(alert);\n markReachable(alert);\n }\n }\n\n const rows: AlertListRow[] = [];\n const visit = (\n alert: Alert,\n level: number,\n parentRowId: string | undefined,\n ancestors: Set<string>\n ) => {\n const segment = encodeURIComponent(alert.id);\n const rowId =\n parentRowId === undefined ? segment : `${parentRowId}/${segment}`;\n const members = membersByGroupId.get(alert.id) ?? [];\n // A member can name a group that is also its own descendant.\n const expandableMembers = members.filter(\n (member) => !ancestors.has(member.id)\n );\n\n rows.push({\n rowId,\n parentRowId,\n alert,\n level,\n expandable: expandableMembers.length > 0,\n });\n\n if (!isExpanded(rowId)) {\n return;\n }\n const nextAncestors = new Set(ancestors).add(alert.id);\n for (const member of expandableMembers) {\n visit(member, level + 1, rowId, nextAncestors);\n }\n };\n\n for (const alert of roots) {\n visit(alert, 0, undefined, new Set());\n }\n return rows;\n}\n\n/**\n * Every row `obc-alert-list-details-experimental` can show for these alerts\n * and filter mode, rows inside collapsed groups included. An alert that is a member\n * of several groups gets one row, and one `rowId`, under each.\n */\nexport function getAlertRows(\n alerts: Alert[],\n filterMode: FilterModes\n): AlertListRow[] {\n const {filter} = getFilterModeData(filterMode);\n return walkAlertRows(alerts.filter(filter), () => true);\n}\n\n/**\n * `<obc-alert-list-details-experimental>` lists alerts in a table with\n * consumer-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 * ```\n * with `columns` set to `[statusColumn(), {key: 'ack', label: 'ACK-status', slot: true}]`.\n *\n * @property filterMode - Which alerts to list.\n * @property alerts - Alerts to list.\n * @property columns - Columns in display order.\n * @property showHeader - Whether to show the column header row.\n * @property defaultExpanded - Whether groups start expanded. Set false to open the list collapsed.\n * @property selectedRowId - Row id to highlight, as given by `row-click` or `getAlertRows()`. Nothing is highlighted when no row has this id.\n * @property ariaLabel - Accessible name of the list, mapped to the `aria-label` attribute and forwarded to its table. `aria-labelledby` is not supported: ID references cannot cross the shadow boundary.\n * @slot cell-<key>:<rowId> - Content of the cell in slot column `<key>` for row `<rowId>`.\n * @fires {ObcAlertListCellClickEvent} cell-click - Fired when the user clicks a button rendered by a data column, such as the one from `ackColumn()`.\n * @fires {ObcRowClickEvent} row-click - Fired when the user clicks a row.\n * @fires {ObcAlertListCellSlotsChangeEvent} cell-slots-change - Fired when `cellSlots` changes; the detail is the new list.\n * @experimental\n */\n@customElement('obc-alert-list-details-experimental')\nexport class ObcAlertListDetailsExperimental extends LitElement {\n // Reactive so a consumer changing the name re-renders the table.\n @property({type: String, attribute: 'aria-label'})\n override ariaLabel: string | null = null;\n\n @property({type: String}) filterMode: FilterModes = FilterModes.ALL;\n @property({type: Array}) alerts: Alert[] = [];\n @property({type: Array, attribute: false}) columns: AlertListColumn[] = [\n statusColumn(),\n ackColumn({dividerRight: true}),\n tagIdColumn(),\n ];\n @property({type: Boolean, attribute: false}) showHeader: boolean = true;\n @property({type: Boolean, attribute: false}) defaultExpanded: boolean = true;\n @property({type: String}) selectedRowId?: string;\n\n @query('obc-table')\n private alertList!: ObcTable;\n\n @state() private expansionOverrides = new Map<string, boolean>();\n\n private alertByRowId = new Map<string, Alert>();\n private allRowIds = new Set<string>();\n\n private _cellSlots: AlertListCellSlot[] = [];\n private cellSlotsChanged = false;\n\n /** Slot of every cell in a slot column, rows in collapsed groups included. */\n get cellSlots(): AlertListCellSlot[] {\n return this._cellSlots;\n }\n\n override willUpdate(changed: PropertyValues<this>) {\n if (\n !changed.has('alerts') &&\n !changed.has('columns') &&\n !changed.has('filterMode')\n ) {\n return;\n }\n const rows = getAlertRows(this.alerts, this.filterMode);\n this.allRowIds = new Set(rows.map((row) => row.rowId));\n const slotColumns = this.columns.filter(isSlotColumn);\n const next = getAlertRows(this.alerts, this.filterMode).flatMap((row) =>\n slotColumns.map((column) => ({\n name: alertListCellSlotName(column.key, row.rowId),\n alert: row.alert,\n rowId: row.rowId,\n columnKey: column.key,\n }))\n );\n const unchanged =\n next.length === this._cellSlots.length &&\n next.every(\n (slot, index) =>\n slot.name === this._cellSlots[index].name &&\n slot.alert === this._cellSlots[index].alert\n );\n if (!unchanged) {\n this._cellSlots = next;\n this.cellSlotsChanged = true;\n }\n }\n\n override updated() {\n if (this.cellSlotsChanged) {\n this.cellSlotsChanged = false;\n this.dispatchEvent(\n new CustomEvent('cell-slots-change', {\n detail: this._cellSlots,\n }) as ObcAlertListCellSlotsChangeEvent\n );\n }\n }\n\n public getVisibleAlerts(): Alert[] {\n const seen = new Set<string>();\n return this.alertList\n .getAllVisibleRows()\n .map((rowId) => this.alertByRowId.get(rowId))\n .filter((alert): alert is Alert => alert !== undefined)\n .filter((alert) => {\n if (seen.has(alert.id)) {\n return false;\n }\n seen.add(alert.id);\n return true;\n });\n }\n\n private onRowClick(e: ObcTableRowClickEvent) {\n const rowId = e.detail.row.id;\n const alert = this.alertByRowId.get(rowId);\n if (alert) {\n this.dispatchEvent(\n new CustomEvent('row-click', {\n detail: {alert, rowId},\n }) as ObcRowClickEvent\n );\n }\n }\n\n private onCellButtonClick(e: ObcTableCellClickEvent) {\n const {rowId, columnKey} = e.detail;\n const alert = this.alertByRowId.get(rowId);\n if (alert) {\n this.dispatchEvent(\n new CustomEvent('cell-click', {\n detail: {\n alert,\n columnKey: columnKey.slice(TABLE_KEY_PREFIX.length),\n rowId,\n },\n bubbles: false,\n }) as ObcAlertListCellClickEvent\n );\n }\n }\n\n private onExpandToggle(e: ObcTableExpandToggleEvent) {\n const overrides = new Map(this.expansionOverrides);\n overrides.set(e.detail.rowId, e.detail.expanded);\n this.expansionOverrides = overrides;\n }\n\n private isExpanded(rowId: string) {\n return this.expansionOverrides.get(rowId) ?? this.defaultExpanded;\n }\n\n private compareRows(\n compare: (a: Alert, b: Alert) => number,\n aRow: ObcTableRow,\n bRow: ObcTableRow\n ) {\n const aAlert = this.alertByRowId.get(aRow.id);\n const bAlert = this.alertByRowId.get(bRow.id);\n return aAlert && bAlert ? compare(aAlert, bAlert) : 0;\n }\n\n private get tableColumns(): ObcTableColumn[] {\n return this.columns.map((column): ObcTableColumn => {\n const base = {\n label: column.label,\n key: TABLE_KEY_PREFIX + column.key,\n dividerRight: column.dividerRight,\n };\n if (isSlotColumn(column)) {\n return {\n ...base,\n renderCell: (_value, row) =>\n html`<slot\n name=${alertListCellSlotName(column.key, row.id)}\n ></slot>`,\n };\n }\n const {compare} = column;\n if (compare) {\n return {\n ...base,\n sortable: true,\n sortDirection: column.sortDirection,\n compareFunction: (_a, _b, aRow, bRow) =>\n this.compareRows(compare, aRow, bRow),\n };\n }\n return base;\n });\n }\n\n private get gridColumns() {\n const columnTracks = this.columns.map(\n (column, index) => column.width ?? (index === 0 ? '1fr' : 'min-content')\n );\n // The empty trailing track takes the table body's end padding and\n // scrollbar gutter, which obc-table's subgrids add to the last track.\n return [...columnTracks, 'min-content'].join(' ');\n }\n\n private get metadata() {\n return getFilterModeData(this.filterMode);\n }\n\n private buildVisibleRows(): ObcTableRow[] {\n const rows = walkAlertRows(\n this.alerts.filter(this.metadata.filter),\n (rowId) => this.isExpanded(rowId)\n );\n this.alertByRowId = new Map(rows.map((row) => [row.rowId, row.alert]));\n const highlightedRowId = this.highlightedRowId();\n return rows.map((row) => ({\n ...this.buildRowCells(row.alert),\n id: row.rowId,\n parentId: row.parentRowId,\n level: row.level,\n expandable: row.expandable,\n expanded: this.isExpanded(row.rowId),\n selected: row.rowId === highlightedRowId,\n }));\n }\n\n /** The selected row, or the nearest visible group row when a collapsed group hides it. */\n private highlightedRowId(): string | undefined {\n if (\n this.selectedRowId === undefined ||\n !this.allRowIds.has(this.selectedRowId)\n ) {\n return undefined;\n }\n let rowId: string | undefined = this.selectedRowId;\n while (rowId !== undefined && !this.alertByRowId.has(rowId)) {\n rowId = parentRowIdOf(rowId);\n }\n return rowId;\n }\n\n private buildRowCells(\n alert: Alert\n ): Record<string, ObcTableCellData | undefined> {\n const cells: Record<string, ObcTableCellData | undefined> = {};\n for (const column of this.columns) {\n cells[TABLE_KEY_PREFIX + column.key] = isSlotColumn(column)\n ? // obc-table skips renderCell for an undefined value.\n {type: ObcTableCellType.Regular}\n : column.cell(alert);\n }\n return cells;\n }\n\n private slotNames(rows: ObcTableRow[]) {\n const slotColumns = this.columns.filter(isSlotColumn);\n return rows.flatMap((row) =>\n slotColumns.map((column) => alertListCellSlotName(column.key, row.id))\n );\n }\n\n override render() {\n const selectedList = this.metadata;\n const data = this.buildVisibleRows();\n\n return html`\n <div class=\"wrapper\">\n ${\n data.length > 0\n ? html` <obc-table\n class=\"alert-list\"\n aria-label=${ifDefined(this.ariaLabel ?? undefined)}\n style=\"--alert-list-grid-columns: ${this.gridColumns}\"\n .data=${data}\n .columns=${this.tableColumns}\n .striped=${true}\n .showHeader=${this.showHeader}\n @row-click=${this.onRowClick}\n @cell-button-click=${this.onCellButtonClick}\n @expand-toggle=${this.onExpandToggle}\n >\n ${repeat(\n this.slotNames(data),\n (name) => name,\n // Forwards the host's slot into the one obc-table renders in the cell.\n (name) => html`<slot name=${name} slot=${name}></slot>`\n )}\n </obc-table>\n <div class=\"spacer\"></div>`\n : html` <div class=\"empty-list\">\n <div class=\"icon\">${selectedList.emptyIcon}</div>\n <div class=\"empty-title\">${selectedList.emptyTitle}</div>\n </div>`\n }\n </div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-list-details-experimental': ObcAlertListDetailsExperimental;\n }\n}\n"],"names":["FilterModes"],"mappings":"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"}
1
+ {"version":3,"file":"alert-list-details-experimental.js","sources":["../../../src/components/alert-list-details-experimental/alert-list-details-experimental.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, unsafeCSS} from 'lit';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport {customElement} from '../../decorator.js';\nimport compentStyle from './alert-list-details-experimental.css?inline';\nimport {msg} from '@lit/localize';\nimport {property, query, state} from 'lit/decorators.js';\nimport {repeat} from 'lit/directives/repeat.js';\nimport '../icon-button/icon-button.js';\nimport '../button/button.js';\nimport '../../icons/icon-silence-iec.js';\nimport '../../icons/icon-alerts.js';\nimport '../../icons/icon-alerts-shelf.js';\nimport '../../icons/icon-alerts-active.js';\nimport '../../icons/icon-alarm-rectified-iec.js';\nimport '../../icons/icon-unacknowledged.js';\nimport '../../icons/icon-alarm-noack-iec.js';\nimport '../../icons/icon-warning-noack-iec.js';\nimport '../alert-icon/alert-icon.js';\nimport {\n StyleType,\n Variant,\n initialsFromName,\n} from '../user-button/user-button.js';\nimport {\n Alert,\n comparePriorityAlerts,\n isActive,\n isAcknowledged,\n isBlocked,\n isShelved,\n} from '../../types.js';\nimport {\n excludedFromUnackedFilter,\n requiresAcknowledgement,\n usesAlarmNoAckIcon,\n} from '../../alert-severity.js';\nimport {\n ObcTable,\n ObcTableCellClickEvent,\n ObcTableCellData,\n ObcTableCellType,\n ObcTableExpandToggleEvent,\n ObcTableRowClickEvent,\n ObcTableRow,\n ObcTableColumn,\n} from '../table/table.js';\nimport '../scrollbar/scrollbar.js';\n\nexport enum FilterModes {\n UNACKED = 'unacked',\n ALL = 'all',\n SHELVED = 'shelved',\n BLOCKED = 'blocked',\n RECTIFIED = 'rectified',\n}\n\nexport type ObcAlertListCellClickEvent = CustomEvent<{\n alert: Alert;\n columnKey: string;\n rowId: string;\n}>;\n\nexport type ObcRowClickEvent = CustomEvent<{\n alert: Alert;\n rowId: string;\n}>;\n\nexport interface AlertListColumnBase {\n /** Unique within the list; part of the cell slot name. */\n key: string;\n label: string;\n /** CSS grid track size. Defaults to `1fr` for the first column, `min-content` for the rest. */\n width?: string;\n dividerRight?: boolean;\n}\n\n/** A column whose cells the list renders from `cell(alert)`. */\nexport interface AlertListDataColumn extends AlertListColumnBase {\n cell: (alert: Alert) => ObcTableCellData | undefined;\n /** Makes the column sortable. */\n compare?: (a: Alert, b: Alert) => number;\n sortDirection?: 'asc' | 'desc';\n}\n\n/** A column whose cells the consumer supplies through `cell-<key>:<rowId>` slots. */\nexport interface AlertListSlotColumn extends AlertListColumnBase {\n slot: true;\n}\n\nexport type AlertListColumn = AlertListDataColumn | AlertListSlotColumn;\n\nexport type AlertListColumnOptions = Partial<AlertListColumnBase>;\n\n/** One cell of a slot column, for every row including rows in collapsed groups. */\nexport interface AlertListCellSlot {\n name: string;\n alert: Alert;\n rowId: string;\n columnKey: string;\n}\n\nexport type ObcAlertListCellSlotsChangeEvent = CustomEvent<AlertListCellSlot[]>;\n\nexport interface AlertListRow {\n rowId: string;\n parentRowId?: string;\n alert: Alert;\n level: number;\n expandable: boolean;\n}\n\nexport function getFilterModeData(filterMode: FilterModes) {\n if (filterMode === FilterModes.ALL)\n return {\n name: FilterModes.ALL,\n title: msg('All'),\n emptyTitle: msg('No active alerts'),\n emptyIcon: html`<obi-alerts></obi-alerts>`,\n filter: (alert: Alert) => !isShelved(alert) && isActive(alert),\n };\n else if (filterMode === FilterModes.UNACKED)\n return {\n name: FilterModes.UNACKED,\n title: msg('Unacked'),\n emptyTitle: msg('No unacknowledged alerts'),\n emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`,\n filter: (alert: Alert) =>\n !isAcknowledged(alert) &&\n isActive(alert) &&\n !excludedFromUnackedFilter(alert.type) &&\n !isShelved(alert),\n };\n else if (filterMode === FilterModes.SHELVED)\n return {\n name: FilterModes.SHELVED,\n title: msg('Shelved'),\n emptyTitle: msg('No shelved alerts'),\n emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`,\n filter: (alert: Alert) => isShelved(alert),\n };\n else if (filterMode === FilterModes.BLOCKED)\n return {\n name: FilterModes.BLOCKED,\n title: msg('Blocked'),\n emptyTitle: msg('No blocked alerts'),\n emptyIcon: html`<obi-alerts-active></obi-alerts-active>`,\n filter: (alert: Alert) => isBlocked(alert),\n };\n else if (filterMode === FilterModes.RECTIFIED)\n return {\n name: FilterModes.RECTIFIED,\n title: msg('Rectified'),\n emptyTitle: msg('No rectified alerts'),\n emptyIcon: html`<obi-alarm-rectified-iec></obi-alarm-rectified-iec>`,\n filter: (alert: Alert) => !isActive(alert),\n };\n else throw new Error('Invalid filter mode');\n}\n\nexport function canAckFilter(filter: (alert: Alert) => boolean) {\n return (alert: Alert) =>\n !isAcknowledged(alert) &&\n !alert.noAck &&\n !excludedFromUnackedFilter(alert.type) &&\n filter(alert);\n}\n\n/** Name of the slot that fills the cell of a slot column in one row. */\nexport function alertListCellSlotName(columnKey: string, rowId: string) {\n // Row ids are URI-encoded too, so neither part can contain the `:` separator.\n return `cell-${encodeURIComponent(columnKey)}:${rowId}`;\n}\n\n/** Alert icon, text and source; sorted by priority. */\nexport function statusColumn(\n options: AlertListColumnOptions = {}\n): AlertListDataColumn {\n return {\n key: 'status',\n label: 'Status',\n sortDirection: 'desc',\n compare: comparePriorityAlerts,\n cell: (alert) => ({\n type: ObcTableCellType.Regular,\n largeIcon: true,\n text: alert.text,\n title: alert.source,\n noWrap: true,\n icon: html`<obc-alert-icon\n .type=${alert.type}\n .acknowledged=${isAcknowledged(alert)}\n .active=${isActive(alert)}\n ></obc-alert-icon>`,\n }),\n ...options,\n };\n}\n\n/** ACK button, or the no-ack icon, for alerts that await acknowledgement. The button fires `cell-click`. */\nexport function ackColumn(\n options: AlertListColumnOptions = {}\n): AlertListDataColumn {\n return {\n key: 'ack',\n label: 'ACK-status',\n cell: (alert) => {\n if (isAcknowledged(alert) && alert.acknowledged) {\n const ackedBy = alert.acknowledged.acknowledgedBy;\n if (!ackedBy || ackedBy.trim() === '')\n return {type: ObcTableCellType.Regular};\n return {\n type: ObcTableCellType.Regular,\n largeIcon: true,\n icon: html`<obc-user-button\n .variant=${Variant.initials}\n .initials=${initialsFromName(ackedBy)}\n .static=${true}\n .styleType=${StyleType.normal}\n ></obc-user-button>`,\n align: 'center',\n };\n }\n if (!isActive(alert) || !requiresAcknowledgement(alert.type)) {\n return {type: ObcTableCellType.Regular};\n }\n if (alert.noAck) {\n const icon = usesAlarmNoAckIcon(alert.type)\n ? html`<obi-alarm-noack-iec usecsscolor></obi-alarm-noack-iec>`\n : html`<obi-warning-noack-iec usecsscolor></obi-warning-noack-iec>`;\n return {\n type: ObcTableCellType.Regular,\n largeIcon: true,\n icon,\n align: 'center',\n };\n }\n return {type: ObcTableCellType.Button, text: msg('ACK')};\n },\n ...options,\n };\n}\n\n/** Activation time; sorted by time. */\nexport function timeColumn({\n formatter = (time: Date) =>\n time.toLocaleTimeString(undefined, {hour12: false}),\n ...options\n}: AlertListColumnOptions & {\n formatter?: (time: Date) => string;\n} = {}): AlertListDataColumn {\n return {\n key: 'time',\n label: 'Activated',\n compare: (a, b) => new Date(a.time).getTime() - new Date(b.time).getTime(),\n cell: (alert) => ({\n type: ObcTableCellType.Regular,\n text: formatter(alert.time),\n align: 'center',\n neutral: true,\n }),\n ...options,\n };\n}\n\n/** Tag ID prefixed with `#`; sorted alphabetically. */\nexport function tagIdColumn(\n options: AlertListColumnOptions = {}\n): AlertListDataColumn {\n return {\n key: 'tagId',\n label: 'Tag ID',\n compare: (a, b) => a.tagId.localeCompare(b.tagId),\n cell: (alert) => ({\n type: ObcTableCellType.Regular,\n text: '#' + alert.tagId,\n align: 'right',\n }),\n ...options,\n };\n}\n\nfunction isSlotColumn(column: AlertListColumn): column is AlertListSlotColumn {\n return 'slot' in column && column.slot === true;\n}\n\n/** Row ids join URI-encoded alert ids with `/`, so the last `/` separates the parent. */\nfunction parentRowIdOf(rowId: string): string | undefined {\n const separatorIndex = rowId.lastIndexOf('/');\n return separatorIndex === -1 ? undefined : rowId.slice(0, separatorIndex);\n}\n\n/** Keeps column keys clear of the row fields `obc-table` reserves (`id`, `level`, …). */\nconst TABLE_KEY_PREFIX = 'column-';\n\nfunction walkAlertRows(\n alerts: Alert[],\n isExpanded: (rowId: string) => boolean\n): AlertListRow[] {\n const alertIds = new Set(alerts.map((alert) => alert.id));\n const membersByGroupId = new Map<string, Alert[]>();\n const roots: Alert[] = [];\n for (const alert of alerts) {\n const groupIds = (alert.memberOf ?? []).filter(\n (groupId) => groupId !== alert.id && alertIds.has(groupId)\n );\n if (groupIds.length === 0) {\n roots.push(alert);\n continue;\n }\n for (const groupId of groupIds) {\n const members = membersByGroupId.get(groupId) ?? [];\n members.push(alert);\n membersByGroupId.set(groupId, members);\n }\n }\n\n const reachable = new Set<string>();\n const markReachable = (alert: Alert) => {\n if (reachable.has(alert.id)) {\n return;\n }\n reachable.add(alert.id);\n for (const member of membersByGroupId.get(alert.id) ?? []) {\n markReachable(member);\n }\n };\n roots.forEach(markReachable);\n for (const alert of alerts) {\n if (!reachable.has(alert.id)) {\n roots.push(alert);\n markReachable(alert);\n }\n }\n\n const rows: AlertListRow[] = [];\n const visit = (\n alert: Alert,\n level: number,\n parentRowId: string | undefined,\n ancestors: Set<string>\n ) => {\n const segment = encodeURIComponent(alert.id);\n const rowId =\n parentRowId === undefined ? segment : `${parentRowId}/${segment}`;\n const members = membersByGroupId.get(alert.id) ?? [];\n // A member can name a group that is also its own descendant.\n const expandableMembers = members.filter(\n (member) => !ancestors.has(member.id)\n );\n\n rows.push({\n rowId,\n parentRowId,\n alert,\n level,\n expandable: expandableMembers.length > 0,\n });\n\n if (!isExpanded(rowId)) {\n return;\n }\n const nextAncestors = new Set(ancestors).add(alert.id);\n for (const member of expandableMembers) {\n visit(member, level + 1, rowId, nextAncestors);\n }\n };\n\n for (const alert of roots) {\n visit(alert, 0, undefined, new Set());\n }\n return rows;\n}\n\n/**\n * Every row `obc-alert-list-details-experimental` can show for these alerts\n * and filter mode, rows inside collapsed groups included. An alert that is a member\n * of several groups gets one row, and one `rowId`, under each.\n */\nexport function getAlertRows(\n alerts: Alert[],\n filterMode: FilterModes\n): AlertListRow[] {\n const {filter} = getFilterModeData(filterMode);\n return walkAlertRows(alerts.filter(filter), () => true);\n}\n\n/**\n * `<obc-alert-list-details-experimental>` lists alerts in a table with\n * consumer-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 * ```\n * with `columns` set to `[statusColumn(), {key: 'ack', label: 'ACK-status', slot: true}]`.\n *\n * @property filterMode - Which alerts to list.\n * @property alerts - Alerts to list.\n * @property columns - Columns in display order.\n * @property showHeader - Whether to show the column header row.\n * @property defaultExpanded - Whether groups start expanded. Set false to open the list collapsed.\n * @property selectedRowId - Row id to highlight, as given by `row-click` or `getAlertRows()`. Nothing is highlighted when no row has this id.\n * @property ariaLabel - Accessible name of the list, mapped to the `aria-label` attribute and forwarded to its table. `aria-labelledby` is not supported: ID references cannot cross the shadow boundary.\n * @slot cell-<key>:<rowId> - Content of the cell in slot column `<key>` for row `<rowId>`.\n * @fires {ObcAlertListCellClickEvent} cell-click - Fired when the user clicks a button rendered by a data column, such as the one from `ackColumn()`.\n * @fires {ObcRowClickEvent} row-click - Fired when the user clicks a row.\n * @fires {ObcAlertListCellSlotsChangeEvent} cell-slots-change - Fired when `cellSlots` changes; the detail is the new list.\n * @experimental\n */\n@customElement('obc-alert-list-details-experimental')\nexport class ObcAlertListDetailsExperimental extends LitElement {\n // Reactive so a consumer changing the name re-renders the table.\n @property({type: String, attribute: 'aria-label'})\n override ariaLabel: string | null = null;\n\n @property({type: String}) filterMode: FilterModes = FilterModes.ALL;\n @property({type: Array}) alerts: Alert[] = [];\n @property({type: Array, attribute: false}) columns: AlertListColumn[] = [\n statusColumn(),\n ackColumn({dividerRight: true}),\n tagIdColumn(),\n ];\n @property({type: Boolean, attribute: false}) showHeader: boolean = true;\n @property({type: Boolean, attribute: false}) defaultExpanded: boolean = true;\n @property({type: String}) selectedRowId?: string;\n\n @query('obc-table')\n private alertList!: ObcTable;\n\n @state() private expansionOverrides = new Map<string, boolean>();\n\n private alertByRowId = new Map<string, Alert>();\n private allRowIds = new Set<string>();\n\n private _cellSlots: AlertListCellSlot[] = [];\n private cellSlotsChanged = false;\n\n /** Slot of every cell in a slot column, rows in collapsed groups included. */\n get cellSlots(): AlertListCellSlot[] {\n return this._cellSlots;\n }\n\n override willUpdate(changed: PropertyValues<this>) {\n if (\n !changed.has('alerts') &&\n !changed.has('columns') &&\n !changed.has('filterMode')\n ) {\n return;\n }\n const rows = getAlertRows(this.alerts, this.filterMode);\n this.allRowIds = new Set(rows.map((row) => row.rowId));\n const slotColumns = this.columns.filter(isSlotColumn);\n const next = getAlertRows(this.alerts, this.filterMode).flatMap((row) =>\n slotColumns.map((column) => ({\n name: alertListCellSlotName(column.key, row.rowId),\n alert: row.alert,\n rowId: row.rowId,\n columnKey: column.key,\n }))\n );\n const unchanged =\n next.length === this._cellSlots.length &&\n next.every(\n (slot, index) =>\n slot.name === this._cellSlots[index].name &&\n slot.alert === this._cellSlots[index].alert\n );\n if (!unchanged) {\n this._cellSlots = next;\n this.cellSlotsChanged = true;\n }\n }\n\n override updated() {\n if (this.cellSlotsChanged) {\n this.cellSlotsChanged = false;\n this.dispatchEvent(\n new CustomEvent('cell-slots-change', {\n detail: this._cellSlots,\n }) as ObcAlertListCellSlotsChangeEvent\n );\n }\n }\n\n public getVisibleAlerts(): Alert[] {\n const seen = new Set<string>();\n return this.alertList\n .getAllVisibleRows()\n .map((rowId) => this.alertByRowId.get(rowId))\n .filter((alert): alert is Alert => alert !== undefined)\n .filter((alert) => {\n if (seen.has(alert.id)) {\n return false;\n }\n seen.add(alert.id);\n return true;\n });\n }\n\n private onRowClick(e: ObcTableRowClickEvent) {\n const rowId = e.detail.row.id;\n const alert = this.alertByRowId.get(rowId);\n if (alert) {\n this.dispatchEvent(\n new CustomEvent('row-click', {\n detail: {alert, rowId},\n }) as ObcRowClickEvent\n );\n }\n }\n\n private onCellButtonClick(e: ObcTableCellClickEvent) {\n const {rowId, columnKey} = e.detail;\n const alert = this.alertByRowId.get(rowId);\n if (alert) {\n this.dispatchEvent(\n new CustomEvent('cell-click', {\n detail: {\n alert,\n columnKey: columnKey.slice(TABLE_KEY_PREFIX.length),\n rowId,\n },\n bubbles: false,\n }) as ObcAlertListCellClickEvent\n );\n }\n }\n\n private onExpandToggle(e: ObcTableExpandToggleEvent) {\n const overrides = new Map(this.expansionOverrides);\n overrides.set(e.detail.rowId, e.detail.expanded);\n this.expansionOverrides = overrides;\n }\n\n private isExpanded(rowId: string) {\n return this.expansionOverrides.get(rowId) ?? this.defaultExpanded;\n }\n\n private compareRows(\n compare: (a: Alert, b: Alert) => number,\n aRow: ObcTableRow,\n bRow: ObcTableRow\n ) {\n const aAlert = this.alertByRowId.get(aRow.id);\n const bAlert = this.alertByRowId.get(bRow.id);\n return aAlert && bAlert ? compare(aAlert, bAlert) : 0;\n }\n\n private get tableColumns(): ObcTableColumn[] {\n return this.columns.map((column): ObcTableColumn => {\n const base = {\n label: column.label,\n key: TABLE_KEY_PREFIX + column.key,\n dividerRight: column.dividerRight,\n };\n if (isSlotColumn(column)) {\n return {\n ...base,\n renderCell: (_value, row) =>\n html`<slot\n name=${alertListCellSlotName(column.key, row.id)}\n ></slot>`,\n };\n }\n const {compare} = column;\n if (compare) {\n return {\n ...base,\n sortable: true,\n sortDirection: column.sortDirection,\n compareFunction: (_a, _b, aRow, bRow) =>\n this.compareRows(compare, aRow, bRow),\n };\n }\n return base;\n });\n }\n\n private get gridColumns() {\n const columnTracks = this.columns.map(\n (column, index) => column.width ?? (index === 0 ? '1fr' : 'min-content')\n );\n // The empty trailing track takes the table body's end padding and\n // scrollbar gutter, which obc-table's subgrids add to the last track.\n return [...columnTracks, 'min-content'].join(' ');\n }\n\n private get metadata() {\n return getFilterModeData(this.filterMode);\n }\n\n private buildVisibleRows(): ObcTableRow[] {\n const rows = walkAlertRows(\n this.alerts.filter(this.metadata.filter),\n (rowId) => this.isExpanded(rowId)\n );\n this.alertByRowId = new Map(rows.map((row) => [row.rowId, row.alert]));\n const highlightedRowId = this.highlightedRowId();\n return rows.map((row) => ({\n ...this.buildRowCells(row.alert),\n id: row.rowId,\n parentId: row.parentRowId,\n level: row.level,\n expandable: row.expandable,\n expanded: this.isExpanded(row.rowId),\n selected: row.rowId === highlightedRowId,\n }));\n }\n\n /** The selected row, or the nearest visible group row when a collapsed group hides it. */\n private highlightedRowId(): string | undefined {\n if (\n this.selectedRowId === undefined ||\n !this.allRowIds.has(this.selectedRowId)\n ) {\n return undefined;\n }\n let rowId: string | undefined = this.selectedRowId;\n while (rowId !== undefined && !this.alertByRowId.has(rowId)) {\n rowId = parentRowIdOf(rowId);\n }\n return rowId;\n }\n\n private buildRowCells(\n alert: Alert\n ): Record<string, ObcTableCellData | undefined> {\n const cells: Record<string, ObcTableCellData | undefined> = {};\n for (const column of this.columns) {\n cells[TABLE_KEY_PREFIX + column.key] = isSlotColumn(column)\n ? // obc-table skips renderCell for an undefined value.\n {type: ObcTableCellType.Regular}\n : column.cell(alert);\n }\n return cells;\n }\n\n private slotNames(rows: ObcTableRow[]) {\n const slotColumns = this.columns.filter(isSlotColumn);\n return rows.flatMap((row) =>\n slotColumns.map((column) => alertListCellSlotName(column.key, row.id))\n );\n }\n\n override render() {\n const selectedList = this.metadata;\n const data = this.buildVisibleRows();\n\n return html`\n <div class=\"wrapper\">\n ${\n data.length > 0\n ? html` <obc-table\n class=\"alert-list\"\n aria-label=${ifDefined(this.ariaLabel ?? undefined)}\n style=\"--alert-list-grid-columns: ${this.gridColumns}\"\n .data=${data}\n .columns=${this.tableColumns}\n .striped=${true}\n .showHeader=${this.showHeader}\n @row-click=${this.onRowClick}\n @cell-button-click=${this.onCellButtonClick}\n @expand-toggle=${this.onExpandToggle}\n >\n ${repeat(\n this.slotNames(data),\n (name) => name,\n // Forwards the host's slot into the one obc-table renders in the cell.\n (name) => html`<slot name=${name} slot=${name}></slot>`\n )}\n </obc-table>\n <div class=\"spacer\"></div>`\n : html` <div class=\"empty-list\">\n <div class=\"icon\">${selectedList.emptyIcon}</div>\n <div class=\"empty-title\">${selectedList.emptyTitle}</div>\n </div>`\n }\n </div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-list-details-experimental': ObcAlertListDetailsExperimental;\n }\n}\n"],"names":["FilterModes"],"mappings":"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"}
@@ -1,8 +1,28 @@
1
1
  import { css } from "lit";
2
2
  const compentStyle = css`* {
3
- -webkit-tap-highlight-color: transparent;
3
+ -webkit-tap-highlight-color: transparent;
4
4
  }
5
5
 
6
+ :host([popover]) {
7
+ /* The browser pins a popover to all four edges and lets the automatic
8
+ margins centre it. Unpinning drops it back where it would normally sit,
9
+ for the consumer to position from. */
10
+ inset: auto;
11
+ margin: 0;
12
+
13
+ padding: 0;
14
+ border: none;
15
+ background: none;
16
+ color: inherit;
17
+
18
+ /* The menus scroll their own content. */
19
+ overflow: visible;
20
+
21
+ /* The browser shrink-wraps a popover to its contents. */
22
+ width: auto;
23
+ height: auto;
24
+ }
25
+
6
26
  * {
7
27
  box-sizing: border-box;
8
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"alert-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"alert-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,5 @@
1
1
  import { LitElement } from 'lit';
2
+ import { PopoverController } from '../../internal/popover-controller.js';
2
3
  import '../button/button.js';
3
4
  import '../../icons/icon-chevron-right-google.js';
4
5
  import '../../icons/icon-silence-iec.js';
@@ -86,6 +87,9 @@ export type ObcAckAllVisibleClickEvent = CustomEvent<{
86
87
  * When hidden, the "ACK visible" button expands to fill the freed space.
87
88
  * @property showAlertListButton - If true, shows the "Alerts" navigation button in the action bar.
88
89
  * When hidden, the "ACK visible" button expands to fill the freed space.
90
+ * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.
91
+ * @property open - Whether the menu is showing.
92
+ * @availableWhen open softDismiss==true
89
93
  * @slot - The alerts items as ObcAlertMenuItem
90
94
  * @slot empty-<tab>-title - Custom empty-state title for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)
91
95
  * @slot empty-<tab>-description - Custom empty-state description for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)
@@ -93,8 +97,18 @@ export type ObcAckAllVisibleClickEvent = CustomEvent<{
93
97
  * @fires {ObcAckAllVisibleClickEvent} ack-all-visible-click - Fired when the ack all visible button is clicked
94
98
  * @fires {CustomEvent} silence-click - Fired when the silence button is clicked
95
99
  * @fires {CustomEvent} go-to-alert-list-click - Fired when the go to alert list button is clicked
100
+ * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.
96
101
  */
97
102
  export declare class ObcAlertMenu extends LitElement {
103
+ /** Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself. */
104
+ softDismiss: boolean;
105
+ /**
106
+ * Whether the menu is showing.
107
+ *
108
+ * Available when `softDismiss==true`.
109
+ */
110
+ open: boolean;
111
+ protected readonly softDismissController: PopoverController;
98
112
  /** If true, displays the "Shelved" tab and enables shelving support for alerts. Set to false to hide the "Shelved" tab and related filtering. */
99
113
  hasShelved: boolean;
100
114
  /** If true, enables the "ACK visible" button, allowing users to acknowledge all currently visible alerts in the active tab. Should be set to true only when there are unacknowledged alerts in view. */
@@ -1 +1 @@
1
- {"version":3,"file":"alert-menu.d.ts","sourceRoot":"","sources":["../../../src/components/alert-menu/alert-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,0CAA0C,CAAC;AAClD,OAAO,iCAAiC,CAAC;AACzC,OAAO,gCAAgC,CAAC;AACxC,OAAO,4BAA4B,CAAC;AACpC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC;AAC5C,OAAO,+BAA+B,CAAC;AAGvC,OAAO,gDAAgD,CAAC;AAKxD,MAAM,MAAM,0BAA0B,GAAG,WAAW,CAAC;IACnD,eAAe,EAAE;QAAC,OAAO,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IACzD,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;CACxC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,qBAKa,YAAa,SAAQ,UAAU;IACf,UAAU,EAAE,OAAO,CAAS;IAE5B,SAAS,EAAE,OAAO,CAAS;IAET,iBAAiB,EAAE,OAAO,CAChE;IAEsC,mBAAmB,EAAE,OAAO,CAClE;IAEE,OAAO,CAAC,iBAAiB,CAAK;IAGvC,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,cAAc;IA+Cb,MAAM;IAqFf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
1
+ {"version":3,"file":"alert-menu.d.ts","sourceRoot":"","sources":["../../../src/components/alert-menu/alert-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,0CAA0C,CAAC;AAClD,OAAO,iCAAiC,CAAC;AACzC,OAAO,gCAAgC,CAAC;AACxC,OAAO,4BAA4B,CAAC;AACpC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC;AAC5C,OAAO,+BAA+B,CAAC;AAGvC,OAAO,gDAAgD,CAAC;AAIxD,OAAO,EAAC,iBAAiB,EAAC,MAAM,sCAAsC,CAAC;AAEvE,MAAM,MAAM,0BAA0B,GAAG,WAAW,CAAC;IACnD,eAAe,EAAE;QAAC,OAAO,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IACzD,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;CACxC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AACH,qBAKa,YAAa,SAAQ,UAAU;IACf,WAAW,UAAS;IAEpB,IAAI,UAAS;IAExC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,oBAA+B;IAE5C,UAAU,EAAE,OAAO,CAAS;IAE5B,SAAS,EAAE,OAAO,CAAS;IAET,iBAAiB,EAAE,OAAO,CAChE;IAEsC,mBAAmB,EAAE,OAAO,CAClE;IAEE,OAAO,CAAC,iBAAiB,CAAK;IAGvC,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,cAAc;IA+Cb,MAAM;IAqFf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
@@ -13,6 +13,7 @@ import { localized, msg } from "@lit/localize";
13
13
  import { customElement } from "../../decorator.js";
14
14
  import "../../building-blocks/alert-list/alert-list.js";
15
15
  import { ObcAlertMenuItemStatus } from "../alert-menu-item/alert-menu-item.js";
16
+ import { PopoverController } from "../../internal/popover-controller.js";
16
17
  var __defProp = Object.defineProperty;
17
18
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
18
19
  var __decorateClass = (decorators, target, key, kind) => {
@@ -26,6 +27,9 @@ var __decorateClass = (decorators, target, key, kind) => {
26
27
  let ObcAlertMenu = class extends LitElement {
27
28
  constructor() {
28
29
  super(...arguments);
30
+ this.softDismiss = false;
31
+ this.open = false;
32
+ this.softDismissController = new PopoverController(this);
29
33
  this.hasShelved = false;
30
34
  this.canAckAll = false;
31
35
  this.showSilenceButton = true;
@@ -160,6 +164,12 @@ let ObcAlertMenu = class extends LitElement {
160
164
  }
161
165
  };
162
166
  ObcAlertMenu.styles = unsafeCSS(compentStyle);
167
+ __decorateClass([
168
+ property({ type: Boolean })
169
+ ], ObcAlertMenu.prototype, "softDismiss", 2);
170
+ __decorateClass([
171
+ property({ type: Boolean })
172
+ ], ObcAlertMenu.prototype, "open", 2);
163
173
  __decorateClass([
164
174
  property({ type: Boolean })
165
175
  ], ObcAlertMenu.prototype, "hasShelved", 2);
@@ -1 +1 @@
1
- {"version":3,"file":"alert-menu.js","sources":["../../../src/components/alert-menu/alert-menu.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport compentStyle from './alert-menu.css?inline';\nimport '../button/button.js';\nimport '../../icons/icon-chevron-right-google.js';\nimport '../../icons/icon-silence-iec.js';\nimport '../../icons/icon-alert-list.js';\nimport '../../icons/icon-alerts.js';\nimport '../../icons/icon-alerts-shelf.js';\nimport '../../icons/icon-unacknowledged.js';\nimport '../tabbed-card/tabbed-card.js';\nimport {localized, msg} from '@lit/localize';\nimport {customElement} from '../../decorator.js';\nimport '../../building-blocks/alert-list/alert-list.js';\nimport {ObcAlertList} from '../../building-blocks/alert-list/alert-list.js';\nimport {ObcTabbedCardChangeEvent} from '../tabbed-card/tabbed-card.js';\nimport {ObcAlertMenuItemStatus} from '../alert-menu-item/alert-menu-item.js';\n\nexport type ObcAckAllVisibleClickEvent = CustomEvent<{\n visibleElements: {element: HTMLElement; index: number}[];\n tabName: 'shelved' | 'unacked' | 'all';\n}>;\n\n/**\n * `<obc-alert-menu>` – A tabbed alert summary panel for displaying, acknowledging, and managing active alerts.\n *\n * Provides a compact, interactive menu for reviewing current alerts, grouped by status (e.g., unacknowledged, active, shelved). Users can acknowledge visible alerts, silence notifications, or navigate to a full alert list. Designed for quick triage and management of alert items in a sidebar or overlay context.\n *\n * ### Features\n * - **Tabbed organization:** Switch between \"Unacked\", \"Active\", and (optionally) \"Shelved\" tabs for focused alert review.\n * - **Alert filtering:** Each tab displays only relevant alerts (e.g., \"Unacked\" shows only unacknowledged, non-shelved items).\n * - **Bulk actions:** \"ACK visible\" button allows acknowledging all currently visible (filtered) alerts at once.\n * - **Silence and navigation:** Dedicated buttons to silence alerts or jump to the full alert list.\n * - **Dynamic content:** Supports any number of `<obc-alert-menu-item>` children, with automatic empty-state messaging and icons per tab.\n * - **Responsive layout:** Adapts to available space, with scrollable alert lists and sticky action bar.\n * - **Customizable:** Optionally show/hide the \"Shelved\" tab via `hasShelved` property; enable/disable bulk ACK via `canAckAll`.\n *\n * ### Usage Guidelines\n * Use `<obc-alert-menu>` to provide users with a focused, actionable summary of current alerts, typically in a sidebar, overlay, or dashboard context. Ideal for scenarios where users need to quickly review, acknowledge, or silence multiple alerts without leaving their current workflow. Avoid using for persistent, always-visible alert banners; for that, use a dedicated alert banner or notification system.\n *\n * - Place one or more `<obc-alert-menu-item>` elements as children to populate the alert list.\n * - Use the `hasShelved` property to enable the \"Shelved\" tab if your application supports alert shelving.\n * - Use the `canAckAll` property to control whether the \"ACK visible\" button is enabled (e.g., only when there are unacknowledged alerts in view).\n * - Listen for custom events (`ack-all-visible-click`, `silence-click`, `go-to-alert-list-click`) to handle user actions.\n *\n * **TODO(designer):** Confirm if there are recommended maximum numbers of alerts to display, or if there are best practices for when to use the \"Shelved\" tab.\n *\n * ### Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |----------------------------------|----------------------------------|----------------------------------------------------------------|\n * | (default) | Always | Place one or more `<obc-alert-menu-item>` elements as alert rows. |\n * | empty-<tab>-title | Selected tab is empty | Custom title for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n * | empty-<tab>-description | Selected tab is empty | Custom description for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n * | empty-<tab>-icon | Selected tab is empty | Custom icon for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n *\n * ### Properties\n * - `hasShelved` (boolean): If true, displays the \"Shelved\" tab and enables shelving support. Default: false.\n * - `canAckAll` (boolean): If true, enables the \"ACK visible\" button for bulk acknowledgment. Default: false.\n * - `showSilenceButton` (boolean): If true, shows the \"Silence\" button. Default: true.\n * - `showAlertListButton` (boolean): If true, shows the \"Alerts\" navigation button. Default: true.\n *\n * ### Events\n * - **ack-all-visible-click** – Fired when the \"ACK visible\" button is clicked. The event detail includes the list of visible alert elements and the current tab name.\n * - **silence-click** – Fired when the \"Silence\" button is clicked.\n * - **go-to-alert-list-click** – Fired when the \"Alerts\" navigation button is clicked.\n *\n * ### Best Practices and Constraints\n * - Only enable \"ACK visible\" when there are actionable, unacknowledged alerts in the current view.\n * - Use the \"Shelved\" tab only if your application supports shelving alerts; otherwise, omit it for simplicity.\n * - For accessibility, keep all alert items and action buttons keyboard navigable.\n * - Do not use this component for persistent, always-on-screen alerts; use banners or dialogs for critical, persistent notifications.\n *\n * ### Example\n * ```\n * <obc-alert-menu hasShelved canAckAll>\n * <obc-alert-menu-item active hasTime>\n * <obi-placeholder slot=\"alert-icon\"></obi-placeholder>\n * <span slot=\"title\">Engine Overheat</span>\n * <span slot=\"description\">Main engine temperature exceeds threshold</span>\n * <span slot=\"time\">09:12:34</span>\n * </obc-alert-menu-item>\n * <!-- More alert items... -->\n * </obc-alert-menu>\n * ```\n *\n * @property hasShelved - If true, displays the \"Shelved\" tab and enables shelving support for alerts.\n * Set to false to hide the \"Shelved\" tab and related filtering.\n * @property canAckAll - If true, enables the \"ACK visible\" button, allowing users to acknowledge all currently visible alerts in the active tab.\n * Should be set to true only when there are unacknowledged alerts in view.\n * @property showSilenceButton - If true, shows the \"Silence\" button in the action bar.\n * When hidden, the \"ACK visible\" button expands to fill the freed space.\n * @property showAlertListButton - If true, shows the \"Alerts\" navigation button in the action bar.\n * When hidden, the \"ACK visible\" button expands to fill the freed space.\n * @slot - The alerts items as ObcAlertMenuItem\n * @slot empty-<tab>-title - Custom empty-state title for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @slot empty-<tab>-description - Custom empty-state description for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @slot empty-<tab>-icon - Custom empty-state icon for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @fires {ObcAckAllVisibleClickEvent} ack-all-visible-click - Fired when the ack all visible button is clicked\n * @fires {CustomEvent} silence-click - Fired when the silence button is clicked\n * @fires {CustomEvent} go-to-alert-list-click - Fired when the go to alert list button is clicked\n */\n@localized()\n/**\n * @stable\n */\n@customElement('obc-alert-menu')\nexport class ObcAlertMenu extends LitElement {\n @property({type: Boolean}) hasShelved: boolean = false;\n\n @property({type: Boolean}) canAckAll: boolean = false;\n\n @property({type: Boolean, attribute: false}) showSilenceButton: boolean =\n true;\n\n @property({type: Boolean, attribute: false}) showAlertListButton: boolean =\n true;\n\n @state() private _selectedTabIndex = 1;\n\n @query('obc-alert-list')\n private alertList!: ObcAlertList;\n\n private handleAckAllVisibleClick() {\n const panel = this.alertList;\n const visibleElements = panel.getVisibleElements();\n this.dispatchEvent(\n new CustomEvent('ack-all-visible-click', {\n detail: {\n visibleElements: visibleElements,\n tabName: this.getSelectedTab().name,\n },\n })\n );\n }\n\n private onTabChange(e: ObcTabbedCardChangeEvent) {\n this._selectedTabIndex = e.detail.tab;\n }\n\n private getSelectedTab() {\n if (this._selectedTabIndex === 0) {\n return {\n name: 'unacked',\n emptyTitle: msg('No unacknowledged alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`,\n class: 'unacked',\n filter: (item: HTMLElement) => {\n return (\n item.getAttribute('status') ===\n ObcAlertMenuItemStatus.Unacknowledged &&\n !item.hasAttribute('shelved')\n );\n },\n };\n } else if (this._selectedTabIndex === 2) {\n return {\n name: 'shelved',\n emptyTitle: msg('No shelved alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`,\n class: 'shelved',\n filter: (item: HTMLElement) => {\n return item.hasAttribute('shelved');\n },\n };\n } else {\n return {\n name: 'all',\n emptyTitle: msg('No active alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-alerts></obi-alerts>`,\n class: 'all',\n filter: (item: HTMLElement) => {\n return !item.hasAttribute('shelved');\n },\n };\n }\n }\n\n override render() {\n const t = this.getSelectedTab();\n\n return html`\n <obc-tabbed-card\n .nTabs=${this.hasShelved ? 3 : 2}\n class=\"wrapper\"\n part=\"wrapper\"\n .selectedTab=${this._selectedTabIndex}\n hasDefaultSlotOnly\n @tab-change=${this.onTabChange}\n >\n <span slot=\"tab-title-0\">${msg('Unacked')}</span>\n <span slot=\"tab-title-1\">${msg('Active')}</span>\n ${\n this.hasShelved\n ? html`<span slot=\"tab-title-2\">${msg('Shelved')}</span>`\n : nothing\n }\n <div class=\"container\">\n <obc-alert-list class=\"alert-list ${t.class}\" .filter=${t.filter}>\n <slot></slot>\n <slot name=\"empty-${t.name}-title\" slot=\"empty-title\"\n >${t.emptyTitle}</slot\n >\n <slot name=\"empty-${t.name}-description\" slot=\"empty-description\"\n >${t.emptyDescription}</slot\n >\n <slot name=\"empty-${t.name}-icon\" slot=\"empty-icon\"\n >${t.emptyIcon}</slot\n >\n </obc-alert-list>\n <div class=\"action\">\n <obc-button\n variant=\"raised\"\n .disabled=${!this.canAckAll}\n fullWidth\n class=\"btn\"\n data-testid=\"ack-all-visible-button\"\n @click=${this.handleAckAllVisibleClick}\n >\n ${msg('ACK visible')}\n </obc-button>\n ${\n this.showSilenceButton\n ? html`<obc-button\n variant=\"normal\"\n fullWidth\n class=\"btn\"\n showLeadingIcon\n @click=${() =>\n this.dispatchEvent(new CustomEvent('silence-click'))}\n >\n <obi-silence-iec slot=\"leading-icon\"></obi-silence-iec>\n ${msg('Silence')}\n </obc-button>`\n : nothing\n }\n ${\n this.showAlertListButton\n ? html`<obc-button\n variant=\"normal\"\n class=\"btn\"\n fullWidth\n showLeadingIcon\n showTrailingIcon\n @click=${() =>\n this.dispatchEvent(\n new CustomEvent('go-to-alert-list-click')\n )}\n >\n <obi-alert-list slot=\"leading-icon\"></obi-alert-list>\n <obi-chevron-right-google\n slot=\"trailing-icon\"\n ></obi-chevron-right-google>\n ${msg('Alerts')}\n </obc-button>`\n : nothing\n }\n </div>\n </div>\n </obc-tabbed-card>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-menu': ObcAlertMenu;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"alert-menu.js","sources":["../../../src/components/alert-menu/alert-menu.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport compentStyle from './alert-menu.css?inline';\nimport '../button/button.js';\nimport '../../icons/icon-chevron-right-google.js';\nimport '../../icons/icon-silence-iec.js';\nimport '../../icons/icon-alert-list.js';\nimport '../../icons/icon-alerts.js';\nimport '../../icons/icon-alerts-shelf.js';\nimport '../../icons/icon-unacknowledged.js';\nimport '../tabbed-card/tabbed-card.js';\nimport {localized, msg} from '@lit/localize';\nimport {customElement} from '../../decorator.js';\nimport '../../building-blocks/alert-list/alert-list.js';\nimport {ObcAlertList} from '../../building-blocks/alert-list/alert-list.js';\nimport {ObcTabbedCardChangeEvent} from '../tabbed-card/tabbed-card.js';\nimport {ObcAlertMenuItemStatus} from '../alert-menu-item/alert-menu-item.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\nexport type ObcAckAllVisibleClickEvent = CustomEvent<{\n visibleElements: {element: HTMLElement; index: number}[];\n tabName: 'shelved' | 'unacked' | 'all';\n}>;\n\n/**\n * `<obc-alert-menu>` – A tabbed alert summary panel for displaying, acknowledging, and managing active alerts.\n *\n * Provides a compact, interactive menu for reviewing current alerts, grouped by status (e.g., unacknowledged, active, shelved). Users can acknowledge visible alerts, silence notifications, or navigate to a full alert list. Designed for quick triage and management of alert items in a sidebar or overlay context.\n *\n * ### Features\n * - **Tabbed organization:** Switch between \"Unacked\", \"Active\", and (optionally) \"Shelved\" tabs for focused alert review.\n * - **Alert filtering:** Each tab displays only relevant alerts (e.g., \"Unacked\" shows only unacknowledged, non-shelved items).\n * - **Bulk actions:** \"ACK visible\" button allows acknowledging all currently visible (filtered) alerts at once.\n * - **Silence and navigation:** Dedicated buttons to silence alerts or jump to the full alert list.\n * - **Dynamic content:** Supports any number of `<obc-alert-menu-item>` children, with automatic empty-state messaging and icons per tab.\n * - **Responsive layout:** Adapts to available space, with scrollable alert lists and sticky action bar.\n * - **Customizable:** Optionally show/hide the \"Shelved\" tab via `hasShelved` property; enable/disable bulk ACK via `canAckAll`.\n *\n * ### Usage Guidelines\n * Use `<obc-alert-menu>` to provide users with a focused, actionable summary of current alerts, typically in a sidebar, overlay, or dashboard context. Ideal for scenarios where users need to quickly review, acknowledge, or silence multiple alerts without leaving their current workflow. Avoid using for persistent, always-visible alert banners; for that, use a dedicated alert banner or notification system.\n *\n * - Place one or more `<obc-alert-menu-item>` elements as children to populate the alert list.\n * - Use the `hasShelved` property to enable the \"Shelved\" tab if your application supports alert shelving.\n * - Use the `canAckAll` property to control whether the \"ACK visible\" button is enabled (e.g., only when there are unacknowledged alerts in view).\n * - Listen for custom events (`ack-all-visible-click`, `silence-click`, `go-to-alert-list-click`) to handle user actions.\n *\n * **TODO(designer):** Confirm if there are recommended maximum numbers of alerts to display, or if there are best practices for when to use the \"Shelved\" tab.\n *\n * ### Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |----------------------------------|----------------------------------|----------------------------------------------------------------|\n * | (default) | Always | Place one or more `<obc-alert-menu-item>` elements as alert rows. |\n * | empty-<tab>-title | Selected tab is empty | Custom title for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n * | empty-<tab>-description | Selected tab is empty | Custom description for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n * | empty-<tab>-icon | Selected tab is empty | Custom icon for the empty state (`<tab>` is one of `unacked`, `all`, `shelved`). |\n *\n * ### Properties\n * - `hasShelved` (boolean): If true, displays the \"Shelved\" tab and enables shelving support. Default: false.\n * - `canAckAll` (boolean): If true, enables the \"ACK visible\" button for bulk acknowledgment. Default: false.\n * - `showSilenceButton` (boolean): If true, shows the \"Silence\" button. Default: true.\n * - `showAlertListButton` (boolean): If true, shows the \"Alerts\" navigation button. Default: true.\n *\n * ### Events\n * - **ack-all-visible-click** – Fired when the \"ACK visible\" button is clicked. The event detail includes the list of visible alert elements and the current tab name.\n * - **silence-click** – Fired when the \"Silence\" button is clicked.\n * - **go-to-alert-list-click** – Fired when the \"Alerts\" navigation button is clicked.\n *\n * ### Best Practices and Constraints\n * - Only enable \"ACK visible\" when there are actionable, unacknowledged alerts in the current view.\n * - Use the \"Shelved\" tab only if your application supports shelving alerts; otherwise, omit it for simplicity.\n * - For accessibility, keep all alert items and action buttons keyboard navigable.\n * - Do not use this component for persistent, always-on-screen alerts; use banners or dialogs for critical, persistent notifications.\n *\n * ### Example\n * ```\n * <obc-alert-menu hasShelved canAckAll>\n * <obc-alert-menu-item active hasTime>\n * <obi-placeholder slot=\"alert-icon\"></obi-placeholder>\n * <span slot=\"title\">Engine Overheat</span>\n * <span slot=\"description\">Main engine temperature exceeds threshold</span>\n * <span slot=\"time\">09:12:34</span>\n * </obc-alert-menu-item>\n * <!-- More alert items... -->\n * </obc-alert-menu>\n * ```\n *\n * @property hasShelved - If true, displays the \"Shelved\" tab and enables shelving support for alerts.\n * Set to false to hide the \"Shelved\" tab and related filtering.\n * @property canAckAll - If true, enables the \"ACK visible\" button, allowing users to acknowledge all currently visible alerts in the active tab.\n * Should be set to true only when there are unacknowledged alerts in view.\n * @property showSilenceButton - If true, shows the \"Silence\" button in the action bar.\n * When hidden, the \"ACK visible\" button expands to fill the freed space.\n * @property showAlertListButton - If true, shows the \"Alerts\" navigation button in the action bar.\n * When hidden, the \"ACK visible\" button expands to fill the freed space.\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot - The alerts items as ObcAlertMenuItem\n * @slot empty-<tab>-title - Custom empty-state title for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @slot empty-<tab>-description - Custom empty-state description for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @slot empty-<tab>-icon - Custom empty-state icon for the selected tab (`<tab>` is one of `unacked`, `all`, `shelved`)\n * @fires {ObcAckAllVisibleClickEvent} ack-all-visible-click - Fired when the ack all visible button is clicked\n * @fires {CustomEvent} silence-click - Fired when the silence button is clicked\n * @fires {CustomEvent} go-to-alert-list-click - Fired when the go to alert list button is clicked\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.\n */\n@localized()\n/**\n * @stable\n */\n@customElement('obc-alert-menu')\nexport class ObcAlertMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: Boolean}) hasShelved: boolean = false;\n\n @property({type: Boolean}) canAckAll: boolean = false;\n\n @property({type: Boolean, attribute: false}) showSilenceButton: boolean =\n true;\n\n @property({type: Boolean, attribute: false}) showAlertListButton: boolean =\n true;\n\n @state() private _selectedTabIndex = 1;\n\n @query('obc-alert-list')\n private alertList!: ObcAlertList;\n\n private handleAckAllVisibleClick() {\n const panel = this.alertList;\n const visibleElements = panel.getVisibleElements();\n this.dispatchEvent(\n new CustomEvent('ack-all-visible-click', {\n detail: {\n visibleElements: visibleElements,\n tabName: this.getSelectedTab().name,\n },\n })\n );\n }\n\n private onTabChange(e: ObcTabbedCardChangeEvent) {\n this._selectedTabIndex = e.detail.tab;\n }\n\n private getSelectedTab() {\n if (this._selectedTabIndex === 0) {\n return {\n name: 'unacked',\n emptyTitle: msg('No unacknowledged alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-unacknowledged></obi-unacknowledged>`,\n class: 'unacked',\n filter: (item: HTMLElement) => {\n return (\n item.getAttribute('status') ===\n ObcAlertMenuItemStatus.Unacknowledged &&\n !item.hasAttribute('shelved')\n );\n },\n };\n } else if (this._selectedTabIndex === 2) {\n return {\n name: 'shelved',\n emptyTitle: msg('No shelved alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-alerts-shelf></obi-alerts-shelf>`,\n class: 'shelved',\n filter: (item: HTMLElement) => {\n return item.hasAttribute('shelved');\n },\n };\n } else {\n return {\n name: 'all',\n emptyTitle: msg('No active alerts'),\n emptyDescription: msg(\n \"Go to the 'Alert list' for more details or to manage existing alerts.\"\n ),\n emptyIcon: html`<obi-alerts></obi-alerts>`,\n class: 'all',\n filter: (item: HTMLElement) => {\n return !item.hasAttribute('shelved');\n },\n };\n }\n }\n\n override render() {\n const t = this.getSelectedTab();\n\n return html`\n <obc-tabbed-card\n .nTabs=${this.hasShelved ? 3 : 2}\n class=\"wrapper\"\n part=\"wrapper\"\n .selectedTab=${this._selectedTabIndex}\n hasDefaultSlotOnly\n @tab-change=${this.onTabChange}\n >\n <span slot=\"tab-title-0\">${msg('Unacked')}</span>\n <span slot=\"tab-title-1\">${msg('Active')}</span>\n ${\n this.hasShelved\n ? html`<span slot=\"tab-title-2\">${msg('Shelved')}</span>`\n : nothing\n }\n <div class=\"container\">\n <obc-alert-list class=\"alert-list ${t.class}\" .filter=${t.filter}>\n <slot></slot>\n <slot name=\"empty-${t.name}-title\" slot=\"empty-title\"\n >${t.emptyTitle}</slot\n >\n <slot name=\"empty-${t.name}-description\" slot=\"empty-description\"\n >${t.emptyDescription}</slot\n >\n <slot name=\"empty-${t.name}-icon\" slot=\"empty-icon\"\n >${t.emptyIcon}</slot\n >\n </obc-alert-list>\n <div class=\"action\">\n <obc-button\n variant=\"raised\"\n .disabled=${!this.canAckAll}\n fullWidth\n class=\"btn\"\n data-testid=\"ack-all-visible-button\"\n @click=${this.handleAckAllVisibleClick}\n >\n ${msg('ACK visible')}\n </obc-button>\n ${\n this.showSilenceButton\n ? html`<obc-button\n variant=\"normal\"\n fullWidth\n class=\"btn\"\n showLeadingIcon\n @click=${() =>\n this.dispatchEvent(new CustomEvent('silence-click'))}\n >\n <obi-silence-iec slot=\"leading-icon\"></obi-silence-iec>\n ${msg('Silence')}\n </obc-button>`\n : nothing\n }\n ${\n this.showAlertListButton\n ? html`<obc-button\n variant=\"normal\"\n class=\"btn\"\n fullWidth\n showLeadingIcon\n showTrailingIcon\n @click=${() =>\n this.dispatchEvent(\n new CustomEvent('go-to-alert-list-click')\n )}\n >\n <obi-alert-list slot=\"leading-icon\"></obi-alert-list>\n <obi-chevron-right-google\n slot=\"trailing-icon\"\n ></obi-chevron-right-google>\n ${msg('Alerts')}\n </obc-button>`\n : nothing\n }\n </div>\n </div>\n </obc-tabbed-card>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-menu': ObcAlertMenu;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,28 @@
1
1
  import { css } from "lit";
2
2
  const compentStyle = css`* {
3
- -webkit-tap-highlight-color: transparent;
3
+ -webkit-tap-highlight-color: transparent;
4
4
  }
5
+
6
+ :host([popover]) {
7
+ /* The browser pins a popover to all four edges and lets the automatic
8
+ margins centre it. Unpinning drops it back where it would normally sit,
9
+ for the consumer to position from. */
10
+ inset: auto;
11
+ margin: 0;
12
+
13
+ padding: 0;
14
+ border: none;
15
+ background: none;
16
+ color: inherit;
17
+
18
+ /* The menus scroll their own content. */
19
+ overflow: visible;
20
+
21
+ /* The browser shrink-wraps a popover to its contents. */
22
+ width: auto;
23
+ height: auto;
24
+ }
25
+
5
26
  .card {
6
27
  border-radius: 8px;
7
28
  background: var(--container-global-color, #fcfcfc);
@@ -14,6 +35,7 @@ const compentStyle = css`* {
14
35
  box-sizing: border-box;
15
36
  width: fit-content;
16
37
  }
38
+
17
39
  .card .main-apps {
18
40
  display: grid;
19
41
  grid-template-columns: repeat(4, 1fr);
@@ -1 +1 @@
1
- {"version":3,"file":"app-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"app-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,5 @@
1
1
  import { LitElement } from 'lit';
2
+ import { PopoverController } from '../../internal/popover-controller.js';
2
3
  import '../text-input-field/text-input-field.js';
3
4
  import '../app-button/app-button.js';
4
5
  import '../../icons/icon-search.js';
@@ -43,11 +44,24 @@ import '../../icons/icon-search.js';
43
44
  * ```
44
45
  * In this example, the menu displays a search bar and a grid of app buttons, each with an icon.
45
46
  *
47
+ * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.
48
+ * @property open - Whether the menu is showing.
49
+ * @availableWhen open softDismiss==true
46
50
  * @slot - Default slot for app buttons or custom menu items
47
51
  * @fires {CustomEvent<string>} search - Fired when the search input value changes, with the current value in `detail`.
52
+ * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.
48
53
  * @stable
49
54
  */
50
55
  export declare class ObcAppMenu extends LitElement {
56
+ /** Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself. */
57
+ softDismiss: boolean;
58
+ /**
59
+ * Whether the menu is showing.
60
+ *
61
+ * Available when `softDismiss==true`.
62
+ */
63
+ open: boolean;
64
+ protected readonly softDismissController: PopoverController;
51
65
  /**
52
66
  * Handles input events from the search field and emits a `search` event with the current value.
53
67
  *
@@ -1 +1 @@
1
- {"version":3,"file":"app-menu.d.ts","sourceRoot":"","sources":["../../../src/components/app-menu/app-menu.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAkB,MAAM,KAAK,CAAC;AAEhD,OAAO,yCAAyC,CAAC;AACjD,OAAO,6BAA6B,CAAC;AACrC,OAAO,4BAA4B,CAAC;AAGpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,qBACa,UAAW,SAAQ,UAAU;IACxC;;;;;OAKG;IACH,aAAa,CAAC,CAAC,EAAE,KAAK;IAMb,MAAM;IAmBf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,UAAU,CAAC;KAC5B;CACF"}
1
+ {"version":3,"file":"app-menu.d.ts","sourceRoot":"","sources":["../../../src/components/app-menu/app-menu.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,UAAU,EAAkB,MAAM,KAAK,CAAC;AAEhD,OAAO,yCAAyC,CAAC;AACjD,OAAO,6BAA6B,CAAC;AACrC,OAAO,4BAA4B,CAAC;AAEpC,OAAO,EAAC,iBAAiB,EAAC,MAAM,sCAAsC,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,qBACa,UAAW,SAAQ,UAAU;IACb,WAAW,UAAS;IAEpB,IAAI,UAAS;IAExC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,oBAA+B;IAEvE;;;;;OAKG;IACH,aAAa,CAAC,CAAC,EAAE,KAAK;IAMb,MAAM;IAmBf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,UAAU,CAAC;KAC5B;CACF"}
@@ -1,19 +1,29 @@
1
1
  import { customElement } from "../../decorator.js";
2
+ import { property } from "lit/decorators.js";
2
3
  import { unsafeCSS, LitElement, html } from "lit";
3
4
  import compentStyle from "./app-menu.css.js";
4
5
  import "../text-input-field/text-input-field.js";
5
6
  import "../app-button/app-button.js";
6
7
  import "../../icons/icon-search.js";
7
8
  import { stopPropagation } from "../../internal/events.js";
9
+ import { PopoverController } from "../../internal/popover-controller.js";
10
+ var __defProp = Object.defineProperty;
8
11
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
12
  var __decorateClass = (decorators, target, key, kind) => {
10
13
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
11
14
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
12
15
  if (decorator = decorators[i])
13
- result = decorator(result) || result;
16
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
17
+ if (kind && result) __defProp(target, key, result);
14
18
  return result;
15
19
  };
16
20
  let ObcAppMenu = class extends LitElement {
21
+ constructor() {
22
+ super(...arguments);
23
+ this.softDismiss = false;
24
+ this.open = false;
25
+ this.softDismissController = new PopoverController(this);
26
+ }
17
27
  /**
18
28
  * Handles input events from the search field and emits a `search` event with the current value.
19
29
  *
@@ -45,6 +55,12 @@ let ObcAppMenu = class extends LitElement {
45
55
  }
46
56
  };
47
57
  ObcAppMenu.styles = unsafeCSS(compentStyle);
58
+ __decorateClass([
59
+ property({ type: Boolean })
60
+ ], ObcAppMenu.prototype, "softDismiss", 2);
61
+ __decorateClass([
62
+ property({ type: Boolean })
63
+ ], ObcAppMenu.prototype, "open", 2);
48
64
  ObcAppMenu = __decorateClass([
49
65
  customElement("obc-app-menu")
50
66
  ], ObcAppMenu);
@@ -1 +1 @@
1
- {"version":3,"file":"app-menu.js","sources":["../../../src/components/app-menu/app-menu.ts"],"sourcesContent":["import {customElement} from '../../decorator.js';\nimport {LitElement, html, unsafeCSS} from 'lit';\nimport compentStyle from './app-menu.css?inline';\nimport '../text-input-field/text-input-field.js';\nimport '../app-button/app-button.js';\nimport '../../icons/icon-search.js';\nimport {stopPropagation} from '../../internal/events.js';\n\n/**\n * `<obc-app-menu>` – A vertical application menu component with integrated search and customizable app buttons.\n *\n * Provides a structured container for displaying a grid of application buttons, typically used for quick navigation or launching key features. Includes a built-in search input at the top to filter or locate specific applications within the menu.\n *\n * ### Features\n * - **Integrated Search:** Includes a search field with a leading icon, allowing users to filter or search for menu items.\n * - **Customizable Content:** Uses a default slot to accept any number of `<obc-app-button>` elements or other custom content.\n * - **Grid Layout:** Arranges child buttons in a responsive grid (4 columns by default) for efficient use of space.\n * - **Icon Support:** Each app button can display an icon via its own slot, supporting a wide range of visual representations.\n * - **Event Emission:** Dispatches a `search` event whenever the search input changes, enabling live filtering or external handling.\n *\n * ### Usage Guidelines\n * Use `<obc-app-menu>` to present a collection of application shortcuts, tools, or frequently accessed features in a compact, visually organized menu. Ideal for dashboards, launchers, or side panels where users need to quickly access multiple apps or modules.\n *\n * The search input is intended for filtering the visible buttons or triggering search-related logic externally. Place `<obc-app-button>` elements as children to represent each app or function.\n *\n * **TODO(designer):** Clarify if the menu is intended only for application launchers, or if it can be used for other grouped actions. Also, specify any recommended maximum number of buttons or best practices for grouping.\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|---------|\n * | (default) | Always | Place one or more `<obc-app-button>` elements or custom content to populate the menu grid. |\n *\n * ### Events\n * - `search` – Fired whenever the user types in the search input. The event's `detail` contains the current input value.\n *\n * ### Example\n * ```\n * <obc-app-menu>\n * <obc-app-button label=\"Radar\" checked>\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-app-button>\n * <obc-app-button label=\"Maps\">\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-app-button>\n * <!-- More app buttons... -->\n * </obc-app-menu>\n * ```\n * In this example, the menu displays a search bar and a grid of app buttons, each with an icon.\n *\n * @slot - Default slot for app buttons or custom menu items\n * @fires {CustomEvent<string>} search - Fired when the search input value changes, with the current value in `detail`.\n * @stable\n */\n@customElement('obc-app-menu')\nexport class ObcAppMenu extends LitElement {\n /**\n * Handles input events from the search field and emits a `search` event with the current value.\n *\n * @param e - The input event from the search field.\n * @fires search\n */\n onSearchInput(e: Event) {\n this.dispatchEvent(\n new CustomEvent('search', {detail: (e.target as HTMLInputElement).value})\n );\n }\n\n override render() {\n return html`\n <div class=\"card\">\n <obc-text-input-field\n placeholder=\"Search\"\n @input=${this.onSearchInput}\n @change=${stopPropagation}\n @clear=${stopPropagation}\n hasLeadingIcon\n >\n <obi-search slot=\"leading-icon\"></obi-search>\n </obc-text-input-field>\n <div class=\"main-apps\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-app-menu': ObcAppMenu;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAsDO,IAAM,aAAN,cAAyB,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzC,cAAc,GAAU;AACtB,SAAK;AAAA,MACH,IAAI,YAAY,UAAU,EAAC,QAAS,EAAE,OAA4B,OAAM;AAAA,IAAA;AAAA,EAE5E;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA,mBAIQ,KAAK,aAAa;AAAA,oBACjB,eAAe;AAAA,mBAChB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUhC;AAGF;AAjCa,WAgCK,SAAS,UAAU,YAAY;AAhCpC,aAAN,gBAAA;AAAA,EADN,cAAc,cAAc;AAAA,GAChB,UAAA;"}
1
+ {"version":3,"file":"app-menu.js","sources":["../../../src/components/app-menu/app-menu.ts"],"sourcesContent":["import {customElement} from '../../decorator.js';\nimport {property} from 'lit/decorators.js';\nimport {LitElement, html, unsafeCSS} from 'lit';\nimport compentStyle from './app-menu.css?inline';\nimport '../text-input-field/text-input-field.js';\nimport '../app-button/app-button.js';\nimport '../../icons/icon-search.js';\nimport {stopPropagation} from '../../internal/events.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\n/**\n * `<obc-app-menu>` – A vertical application menu component with integrated search and customizable app buttons.\n *\n * Provides a structured container for displaying a grid of application buttons, typically used for quick navigation or launching key features. Includes a built-in search input at the top to filter or locate specific applications within the menu.\n *\n * ### Features\n * - **Integrated Search:** Includes a search field with a leading icon, allowing users to filter or search for menu items.\n * - **Customizable Content:** Uses a default slot to accept any number of `<obc-app-button>` elements or other custom content.\n * - **Grid Layout:** Arranges child buttons in a responsive grid (4 columns by default) for efficient use of space.\n * - **Icon Support:** Each app button can display an icon via its own slot, supporting a wide range of visual representations.\n * - **Event Emission:** Dispatches a `search` event whenever the search input changes, enabling live filtering or external handling.\n *\n * ### Usage Guidelines\n * Use `<obc-app-menu>` to present a collection of application shortcuts, tools, or frequently accessed features in a compact, visually organized menu. Ideal for dashboards, launchers, or side panels where users need to quickly access multiple apps or modules.\n *\n * The search input is intended for filtering the visible buttons or triggering search-related logic externally. Place `<obc-app-button>` elements as children to represent each app or function.\n *\n * **TODO(designer):** Clarify if the menu is intended only for application launchers, or if it can be used for other grouped actions. Also, specify any recommended maximum number of buttons or best practices for grouping.\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|---------|\n * | (default) | Always | Place one or more `<obc-app-button>` elements or custom content to populate the menu grid. |\n *\n * ### Events\n * - `search` – Fired whenever the user types in the search input. The event's `detail` contains the current input value.\n *\n * ### Example\n * ```\n * <obc-app-menu>\n * <obc-app-button label=\"Radar\" checked>\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-app-button>\n * <obc-app-button label=\"Maps\">\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-app-button>\n * <!-- More app buttons... -->\n * </obc-app-menu>\n * ```\n * In this example, the menu displays a search bar and a grid of app buttons, each with an icon.\n *\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot - Default slot for app buttons or custom menu items\n * @fires {CustomEvent<string>} search - Fired when the search input value changes, with the current value in `detail`.\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.\n * @stable\n */\n@customElement('obc-app-menu')\nexport class ObcAppMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n /**\n * Handles input events from the search field and emits a `search` event with the current value.\n *\n * @param e - The input event from the search field.\n * @fires search\n */\n onSearchInput(e: Event) {\n this.dispatchEvent(\n new CustomEvent('search', {detail: (e.target as HTMLInputElement).value})\n );\n }\n\n override render() {\n return html`\n <div class=\"card\">\n <obc-text-input-field\n placeholder=\"Search\"\n @input=${this.onSearchInput}\n @change=${stopPropagation}\n @clear=${stopPropagation}\n hasLeadingIcon\n >\n <obi-search slot=\"leading-icon\"></obi-search>\n </obc-text-input-field>\n <div class=\"main-apps\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-app-menu': ObcAppMenu;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AA4DO,IAAM,aAAN,cAAyB,WAAW;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA;AACsB,SAAA,cAAc;AAEd,SAAA,OAAO;AAElC,SAAmB,wBAAwB,IAAI,kBAAkB,IAAI;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrE,cAAc,GAAU;AACtB,SAAK;AAAA,MACH,IAAI,YAAY,UAAU,EAAC,QAAS,EAAE,OAA4B,OAAM;AAAA,IAAA;AAAA,EAE5E;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA,mBAIQ,KAAK,aAAa;AAAA,oBACjB,eAAe;AAAA,mBAChB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUhC;AAGF;AAvCa,WAsCK,SAAS,UAAU,YAAY;AArCpB,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GADd,WACgB,WAAA,eAAA,CAAA;AAEA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAHd,WAGgB,WAAA,QAAA,CAAA;AAHhB,aAAN,gBAAA;AAAA,EADN,cAAc,cAAc;AAAA,GAChB,UAAA;"}
@@ -1,8 +1,28 @@
1
1
  import { css } from "lit";
2
2
  const componentStyle = css`* {
3
- -webkit-tap-highlight-color: transparent;
3
+ -webkit-tap-highlight-color: transparent;
4
4
  }
5
5
 
6
+ :host([popover]) {
7
+ /* The browser pins a popover to all four edges and lets the automatic
8
+ margins centre it. Unpinning drops it back where it would normally sit,
9
+ for the consumer to position from. */
10
+ inset: auto;
11
+ margin: 0;
12
+
13
+ padding: 0;
14
+ border: none;
15
+ background: none;
16
+ color: inherit;
17
+
18
+ /* The menus scroll their own content. */
19
+ overflow: visible;
20
+
21
+ /* The browser shrink-wraps a popover to its contents. */
22
+ width: auto;
23
+ height: auto;
24
+ }
25
+
6
26
  * {
7
27
  box-sizing: border-box;
8
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"brilliance-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"brilliance-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,5 @@
1
1
  import { LitElement, nothing } from 'lit';
2
+ import { PopoverController } from '../../internal/popover-controller.js';
2
3
  import '../button/button.js';
3
4
  import '../slider/slider.js';
4
5
  import '../toggle-switch/toggle-switch.js';
@@ -117,14 +118,27 @@ export type ObcLinkBrightnessChangeEvent = CustomEvent<{
117
118
  * @property brightnessInputVariant - The variant of the brightness input.
118
119
  * @property showScreenControlLink - If true, displays the screen control link.
119
120
  * @property showAdditionalScreenControls - If true, displays the additional screen controls slot.
121
+ * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.
122
+ * @property open - Whether the menu is showing.
123
+ * @availableWhen open softDismiss==true
120
124
  * @slot additional-screen-controls - Consumer-defined controls, placed after the screen control link; rendered when `showAdditionalScreenControls` is true
121
125
  * @fires {ObcPaletteChangeEvent} palette-changed - When the palette is changed
122
126
  * @fires {ObcBrightnessChangeEvent} brightness-changed - When the brightness is changed
123
127
  * @fires {ObcLinkPaletteChangeEvent} link-palette-changed - When the link palette toggle is changed
124
128
  * @fires {ObcLinkBrightnessChangeEvent} link-brightness-changed - When the link brightness toggle is changed
125
129
  * @fires {CustomEvent} screen-control-link-clicked - When the screen control link is clicked
130
+ * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.
126
131
  */
127
132
  export declare class ObcBrillianceMenu extends LitElement {
133
+ /** Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself. */
134
+ softDismiss: boolean;
135
+ /**
136
+ * Whether the menu is showing.
137
+ *
138
+ * Available when `softDismiss==true`.
139
+ */
140
+ open: boolean;
141
+ protected readonly softDismissController: PopoverController;
128
142
  /** The currently selected palette. Possible values: `'night'`, `'dusk'`, `'day'`, `'bright'`. Defaults to `'day'`. */
129
143
  palette: ObcPalette;
130
144
  /** The current brightness value (0–100). Defaults to `50`. */
@@ -1 +1 @@
1
- {"version":3,"file":"brilliance-menu.d.ts","sourceRoot":"","sources":["../../../src/components/brilliance-menu/brilliance-menu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"brilliance-menu.d.ts","sourceRoot":"","sources":["../../../src/components/brilliance-menu/brilliance-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,UAAU,EAAQ,OAAO,EAAY,MAAM,KAAK,CAAC;AAG7E,OAAO,qBAAqB,CAAC;AAC7B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,mCAAmC,CAAC;AAC3C,OAAO,+CAA+C,CAAC;AACvD,OAAO,iDAAiD,CAAC;AACzD,OAAO,4CAA4C,CAAC;AACpD,OAAO,iDAAiD,CAAC;AACzD,OAAO,mCAAmC,CAAC;AAC3C,OAAO,kCAAkC,CAAC;AAC1C,OAAO,iCAAiC,CAAC;AACzC,OAAO,wCAAwC,CAAC;AAChD,OAAO,0BAA0B,CAAC;AAClC,OAAO,iDAAiD,CAAC;AACzD,OAAO,gDAAgD,CAAC;AACxD,OAAO,yCAAyC,CAAC;AACjD,OAAO,0CAA0C,CAAC;AAClD,OAAO,iCAAiC,CAAC;AAUzC,OAAO,uDAAuD,CAAC;AAC/D,OAAO,uCAAuC,CAAC;AAC/C,OAAO,6BAA6B,CAAC;AACrC,OAAO,+BAA+B,CAAC;AACvC,OAAO,uBAAuB,CAAC;AAG/B,OAAO,4CAA4C,CAAC;AACpD,OAAO,2CAA2C,CAAC;AAEnD,OAAO,EAAC,iBAAiB,EAAC,MAAM,sCAAsC,CAAC;AAEvE,oBAAY,UAAU;IACpB,KAAK,UAAU;IACf,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,MAAM,WAAW;CAClB;AAED,oBAAY,wBAAwB;IAClC,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,MAAM,WAAW;CAClB;AAED,oBAAY,yBAAyB;IACnC,OAAO,YAAY;IACnB,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAC,CAAC,CAAC;AACrE,MAAM,MAAM,wBAAwB,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AACpE,MAAM,MAAM,yBAAyB,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,CAAC,CAAC;AACtE,MAAM,MAAM,4BAA4B,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,CAAC,CAAC;AAKzE;;;GAGG;AAEH;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,qBAKa,iBAAkB,SAAQ,UAAU;IACpB,WAAW,UAAS;IAEpB,IAAI,UAAS;IAExC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,oBAA+B;IAE7C,OAAO,EAAE,UAAU,CAAkB;IAErC,UAAU,SAAM;IAG1C,kBAAkB,UAAS;IAEA,eAAe,UAAS;IAEN,cAAc,UAAQ;IAEtB,WAAW,UAAQ;IAEnB,gBAAgB,UAAQ;IACxB,eAAe,UAAQ;IACvB,cAAc,UAAQ;IACtB,iBAAiB,UAAQ;IAE5C,OAAO,2BAAmC;IAE1C,cAAc,SAAO;IAErB,aAAa,SAAO;IAEpB,mBAAmB,SAAK;IAExB,mBAAmB,SAAM;IAEzB,sBAAsB,4BACZ;IAET,qBAAqB,UAAS;IAE9B,4BAA4B,UAAS;IAEvD,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAclD;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,WAAW;IASnC;;;;OAIG;IACH,uBAAuB,CAAC,KAAK,EAAE,WAAW;IAS1C,kBAAkB,CAAC,IAAI,EAAE,MAAM;IAa/B,IAAI,qBAAqB,YAExB;IAED,IAAI,qBAAqB,YAExB;IAED;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,WAAW;IAQvC;;;;OAIG;IACH,uBAAuB,CAAC,KAAK,EAAE,WAAW;IAQ1C,IAAI,iBAAiB,IAAI,UAAU,EAAE,CAOpC;IAED,IAAI,kBAAkB,YAIrB;IAED,IAAI,kBAAkB,YAIrB;IAEQ,OAAO,CAAC,aAAa,CAAqB;IAEnD,OAAO,CAAC,aAAa;IAKrB,OAAO,KAAK,IAAI,GAaf;IAED,WAAW;IAaX,eAAe;IAaf,gBAAgB;IAiJhB,IAAI,gBAAgB,eAGnB;IAED,IAAI,WAAW,0DAcd;IAED,OAAO,CAAC,cAAc;IA6BtB,aAAa;IA0Gb,uBAAuB;IAmCd,MAAM;IA8Cf,8BAA8B;IAI9B,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,qBAAqB,EAAE,iBAAiB,CAAC;KAC1C;CACF"}