@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.146 → 2.0.0-next.147

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 (28) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +45 -16
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +1 -1
  4. package/dist/building-blocks/readout-block/readout-block.d.ts +1 -1
  5. package/dist/building-blocks/readout-block/readout-block.js.map +1 -1
  6. package/dist/components/textbox/textbox.d.ts +1 -1
  7. package/dist/components/textbox/textbox.js.map +1 -1
  8. package/dist/components/top-bar/top-bar.css.js +44 -15
  9. package/dist/components/top-bar/top-bar.css.js.map +1 -1
  10. package/dist/components/top-bar/top-bar.js +1 -1
  11. package/dist/components/top-bar/top-bar.js.map +1 -1
  12. package/dist/navigation-instruments/readout/readout.d.ts +1 -1
  13. package/dist/navigation-instruments/readout/readout.js.map +1 -1
  14. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +1 -1
  15. package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
  16. package/package.json +1 -1
  17. package/script/agent-docs/emitters.ts +3 -2
  18. package/src/building-blocks/readout-block/readout-block.stories.ts +1 -1
  19. package/src/building-blocks/readout-block/readout-block.ts +1 -1
  20. package/src/components/textbox/textbox.stories.ts +1 -1
  21. package/src/components/textbox/textbox.ts +1 -1
  22. package/src/components/top-bar/top-bar.css +44 -18
  23. package/src/components/top-bar/top-bar.ts +1 -1
  24. package/src/navigation-instruments/readout/readout.stories.ts +1 -1
  25. package/src/navigation-instruments/readout/readout.ts +1 -1
  26. package/src/navigation-instruments/readout-list-item/readout-list-item.stories.ts +1 -1
  27. package/src/navigation-instruments/readout-list-item/readout-list-item.ts +1 -1
  28. package/vitest.browser.config.ts +3 -0
@@ -8220,7 +8220,7 @@
8220
8220
  {
8221
8221
  "kind": "variable",
8222
8222
  "name": "ObcTopBar",
8223
- "default": "class extends LitElement { constructor() { super(...arguments); this.appTitle = \"App\"; this.pageName = \"Page\"; this.menuButtonIcon = \"menu\"; this.menuButtonActivated = false; this.dimmingButtonActivated = false; this.appsButtonActivated = false; this.leftMoreButtonActivated = false; this.userButtonActivated = false; this.userButtonDisabled = false; this.tall = false; this.wideMenuButton = false; this.showAppsButton = false; this.showDimmingButton = false; this.showUserButton = false; this.showClock = false; this.showDate = false; this.showAppIcon = false; this.inactive = false; this.appButtonBreakpointPx = 500; this.dimmingButtonBreakpointPx = 500; this.appTitleBreakpointPx = 500; this.userButtonBreakpointPx = 500; this.appIconBreakpointPx = 500; this.settings = false; this.breadcrumbItems = []; this.leftButtonEvent = null; this.leftButtonTimeout = null; this.isLeftButtonDown = false; this.isEmergencyBrightness = false; } dimmingButtonClicked() { this.dispatchEvent(new CustomEvent(\"dimming-button-clicked\")); } appsButtonClicked() { this.dispatchEvent(new CustomEvent(\"apps-button-clicked\")); } leftMoreButtonClicked() { this.dispatchEvent(new CustomEvent(\"left-more-button-clicked\")); } userButtonClicked() { this.dispatchEvent(new CustomEvent(\"user-button-clicked\")); } leftButtonDown(event) { this.leftButtonEvent = event; this.isLeftButtonDown = true; this.leftButtonTimeout = setTimeout(() => { this.leftButtonEvent = null; this.dispatchEvent(new CustomEvent(\"emergency-brightness-start\")); this.isEmergencyBrightness = true; }, 500); } leftButtonUp() { if (this.leftButtonEvent) { this.dispatchEvent(this.leftButtonEvent); this.leftButtonEvent = null; } if (this.leftButtonTimeout) { clearTimeout(this.leftButtonTimeout); this.leftButtonTimeout = null; } if (this.isEmergencyBrightness) { this.dispatchEvent(new CustomEvent(\"emergency-brightness-stop\")); this.isEmergencyBrightness = false; } this.isLeftButtonDown = false; } leftButtonLeave() { if (!this.isLeftButtonDown) return; if (this.leftButtonTimeout) { clearInterval(this.leftButtonTimeout); this.leftButtonTimeout = null; } if (this.isEmergencyBrightness) { this.dispatchEvent(new CustomEvent(\"emergency-brightness-stop\")); this.isEmergencyBrightness = false; } this.isLeftButtonDown = false; } render() { const leftGroup = []; if (this.settings) { leftGroup.push( html`<div class=\"menu-button\"> <obc-icon-button variant=\"flat\" @pointerdown=${() => this.leftButtonDown(new CustomEvent(\"close\"))} @pointerup=${() => this.leftButtonUp()} @pointerleave=${() => this.leftButtonLeave()} > <obi-close-google></obi-close-google> </obc-icon-button> </div>` ); leftGroup.push( html`<obc-icon-button variant=\"flat\" @click=${() => this.dispatchEvent(new CustomEvent(\"back\"))} > <obi-arrow-left-google></obi-arrow-left-google> </obc-icon-button>` ); leftGroup.push(html`<div class=\"title\">${this.appTitle}</div>`); leftGroup.push( html`<obc-breadcrumb .items=${this.breadcrumbItems} @breadcrumb-click=${(e) => this.dispatchEvent( new CustomEvent(\"breadcrumb-click\", { detail: e.detail }) )} ></obc-breadcrumb>` ); } else { if (!this.inactive) { leftGroup.push( html`<div class=\"menu-button ${this.wideMenuButton ? \"wide\" : null}\"> <obc-icon-button variant=\"flat\" @pointerdown=${() => this.leftButtonDown(new CustomEvent(\"menu-button-clicked\"))} @pointerup=${() => this.leftButtonUp()} @pointerleave=${() => this.leftButtonLeave()} ?activated=${this.menuButtonActivated} > ${this.menuButtonIcon === \"menu\" ? html`<obi-menu-iec></obi-menu-iec>` : html`<obi-home></obi-home>`} </obc-icon-button> </div>` ); } if (this.showAppIcon) { leftGroup.push( html`<div class=\"app-icon\"><slot name=\"app-icon\"></slot></div>` ); } leftGroup.push(html`<div class=\"title\">${this.appTitle}</div>`); leftGroup.push(html`<div class=\"page-name\">${this.pageName}</div>`); leftGroup.push(html`<slot name=\"command-button\"></slot>`); } const breakpointMoreButton = Math.max( this.appButtonBreakpointPx, this.dimmingButtonBreakpointPx ); return html` <style> @media (max-width: ${breakpointMoreButton}px) { .left-more-button { display: revert !important; } .group.left > * { margin-right: 4px; margin-left: 4px; } } @media (max-width: ${this.appButtonBreakpointPx}px) { .apps-button { display: none; } } @media (max-width: ${this.dimmingButtonBreakpointPx}px) { .dimming-button { display: none; } } @media (max-width: ${this.appTitleBreakpointPx}px) { .title { display: none; } } @media (max-width: ${this.userButtonBreakpointPx}px) { .user-button { display: none; } } @media (max-width: ${this.appIconBreakpointPx}px) { .app-icon { display: none; } } </style> <nav class=${classMap({ wrapper: true, inactive: this.inactive, settings: this.settings, tall: this.tall })} role=\"menubar\" > <div class=\"left group\">${leftGroup}</div> <div class=\"right group\"> <div class=\"alert-container\"> <slot name=\"alerts\"></slot> </div> ${this.showDimmingButton && !this.inactive ? html`<obc-icon-button class=\"dimming-button\" part=\"dimming-button\" variant=\"flat\" @click=${this.dimmingButtonClicked} ?activated=${this.dimmingButtonActivated} > <obi-palette-day-night-iec></obi-palette-day-night-iec> </obc-icon-button>` : null} ${this.showUserButton && !this.inactive ? html`<obc-icon-button class=\"user-button\" variant=\"flat\" part=\"user-button\" @click=${this.userButtonClicked} ?activated=${this.userButtonActivated} ?disabled=${this.userButtonDisabled} > <obi-user></obi-user> </obc-icon-button>` : null} ${this.showAppsButton && !this.inactive ? html`<obc-icon-button class=\"apps-button\" variant=\"flat\" part=\"apps-button\" @click=${this.appsButtonClicked} ?activated=${this.appsButtonActivated} > <obi-applications></obi-applications> </obc-icon-button>` : null} ${this.showClock ? html`<slot name=\"clock\"></slot>` : null} ${!this.inactive ? html`<obc-icon-button class=\"left-more-button\" part=\"left-more-button\" variant=\"flat\" @click=${this.leftMoreButtonClicked} ?activated=${this.leftMoreButtonActivated} > <obi-more-vertical-google></obi-more-vertical-google> </obc-icon-button>` : null} </div> </nav> `; } }"
8223
+ "default": "class extends LitElement { constructor() { super(...arguments); this.appTitle = \"App\"; this.pageName = \"Page\"; this.menuButtonIcon = \"menu\"; this.menuButtonActivated = false; this.dimmingButtonActivated = false; this.appsButtonActivated = false; this.leftMoreButtonActivated = false; this.userButtonActivated = false; this.userButtonDisabled = false; this.tall = false; this.wideMenuButton = false; this.showAppsButton = false; this.showDimmingButton = false; this.showUserButton = false; this.showClock = false; this.showDate = false; this.showAppIcon = false; this.inactive = false; this.appButtonBreakpointPx = 500; this.dimmingButtonBreakpointPx = 500; this.appTitleBreakpointPx = 500; this.userButtonBreakpointPx = 500; this.appIconBreakpointPx = 500; this.settings = false; this.breadcrumbItems = []; this.leftButtonEvent = null; this.leftButtonTimeout = null; this.isLeftButtonDown = false; this.isEmergencyBrightness = false; } dimmingButtonClicked() { this.dispatchEvent(new CustomEvent(\"dimming-button-clicked\")); } appsButtonClicked() { this.dispatchEvent(new CustomEvent(\"apps-button-clicked\")); } leftMoreButtonClicked() { this.dispatchEvent(new CustomEvent(\"left-more-button-clicked\")); } userButtonClicked() { this.dispatchEvent(new CustomEvent(\"user-button-clicked\")); } leftButtonDown(event) { this.leftButtonEvent = event; this.isLeftButtonDown = true; this.leftButtonTimeout = setTimeout(() => { this.leftButtonEvent = null; this.dispatchEvent(new CustomEvent(\"emergency-brightness-start\")); this.isEmergencyBrightness = true; }, 500); } leftButtonUp() { if (this.leftButtonEvent) { this.dispatchEvent(this.leftButtonEvent); this.leftButtonEvent = null; } if (this.leftButtonTimeout) { clearTimeout(this.leftButtonTimeout); this.leftButtonTimeout = null; } if (this.isEmergencyBrightness) { this.dispatchEvent(new CustomEvent(\"emergency-brightness-stop\")); this.isEmergencyBrightness = false; } this.isLeftButtonDown = false; } leftButtonLeave() { if (!this.isLeftButtonDown) return; if (this.leftButtonTimeout) { clearInterval(this.leftButtonTimeout); this.leftButtonTimeout = null; } if (this.isEmergencyBrightness) { this.dispatchEvent(new CustomEvent(\"emergency-brightness-stop\")); this.isEmergencyBrightness = false; } this.isLeftButtonDown = false; } render() { const leftGroup = []; if (this.settings) { leftGroup.push( html`<div class=\"menu-button\"> <obc-icon-button variant=\"flat\" @pointerdown=${() => this.leftButtonDown(new CustomEvent(\"close\"))} @pointerup=${() => this.leftButtonUp()} @pointerleave=${() => this.leftButtonLeave()} > <obi-close-google></obi-close-google> </obc-icon-button> </div>` ); leftGroup.push( html`<obc-icon-button variant=\"flat\" @click=${() => this.dispatchEvent(new CustomEvent(\"back\"))} > <obi-arrow-left-google></obi-arrow-left-google> </obc-icon-button>` ); leftGroup.push(html`<div class=\"title\">${this.appTitle}</div>`); leftGroup.push( html`<obc-breadcrumb .items=${this.breadcrumbItems} @breadcrumb-click=${(e) => this.dispatchEvent( new CustomEvent(\"breadcrumb-click\", { detail: e.detail }) )} ></obc-breadcrumb>` ); } else { if (!this.inactive) { leftGroup.push( html`<div class=\"menu-button ${this.wideMenuButton ? \"wide\" : null}\"> <obc-icon-button variant=\"flat\" @pointerdown=${() => this.leftButtonDown(new CustomEvent(\"menu-button-clicked\"))} @pointerup=${() => this.leftButtonUp()} @pointerleave=${() => this.leftButtonLeave()} ?activated=${this.menuButtonActivated} > ${this.menuButtonIcon === \"menu\" ? html`<obi-menu-iec></obi-menu-iec>` : html`<obi-home></obi-home>`} </obc-icon-button> </div>` ); } if (this.showAppIcon) { leftGroup.push( html`<div class=\"app-icon\"><slot name=\"app-icon\"></slot></div>` ); } leftGroup.push(html`<div class=\"title\">${this.appTitle}</div>`); leftGroup.push(html`<div class=\"page-name\">${this.pageName}</div>`); leftGroup.push(html`<slot name=\"command-button\"></slot>`); } const breakpointMoreButton = Math.max( this.appButtonBreakpointPx, this.dimmingButtonBreakpointPx ); return html` <style> @media (max-width: ${breakpointMoreButton}px) { .left-more-button { display: revert !important; } .group.left > * { margin-right: 4px; margin-left: 4px; } } @media (max-width: ${this.appButtonBreakpointPx}px) { .apps-button { display: none; } } @media (max-width: ${this.dimmingButtonBreakpointPx}px) { .dimming-button { display: none; } } @media (max-width: ${this.appTitleBreakpointPx}px) { .title { display: none !important; /* the stylesheet's display wins over this inline rule otherwise */ } } @media (max-width: ${this.userButtonBreakpointPx}px) { .user-button { display: none; } } @media (max-width: ${this.appIconBreakpointPx}px) { .app-icon { display: none; } } </style> <nav class=${classMap({ wrapper: true, inactive: this.inactive, settings: this.settings, tall: this.tall })} role=\"menubar\" > <div class=\"left group\">${leftGroup}</div> <div class=\"right group\"> <div class=\"alert-container\"> <slot name=\"alerts\"></slot> </div> ${this.showDimmingButton && !this.inactive ? html`<obc-icon-button class=\"dimming-button\" part=\"dimming-button\" variant=\"flat\" @click=${this.dimmingButtonClicked} ?activated=${this.dimmingButtonActivated} > <obi-palette-day-night-iec></obi-palette-day-night-iec> </obc-icon-button>` : null} ${this.showUserButton && !this.inactive ? html`<obc-icon-button class=\"user-button\" variant=\"flat\" part=\"user-button\" @click=${this.userButtonClicked} ?activated=${this.userButtonActivated} ?disabled=${this.userButtonDisabled} > <obi-user></obi-user> </obc-icon-button>` : null} ${this.showAppsButton && !this.inactive ? html`<obc-icon-button class=\"apps-button\" variant=\"flat\" part=\"apps-button\" @click=${this.appsButtonClicked} ?activated=${this.appsButtonActivated} > <obi-applications></obi-applications> </obc-icon-button>` : null} ${this.showClock ? html`<slot name=\"clock\"></slot>` : null} ${!this.inactive ? html`<obc-icon-button class=\"left-more-button\" part=\"left-more-button\" variant=\"flat\" @click=${this.leftMoreButtonClicked} ?activated=${this.leftMoreButtonActivated} > <obi-more-vertical-google></obi-more-vertical-google> </obc-icon-button>` : null} </div> </nav> `; } }"
8224
8224
  }
8225
8225
  ],
8226
8226
  "exports": [
@@ -152,7 +152,7 @@ export declare enum ReadoutBlockHidePhase {
152
152
  * @csspart block-text - The `obc-textbox` rendering the number.
153
153
  * @csspart block-icon - The leading marker-icon container.
154
154
  * @csspart degree - The trailing degree-glyph column.
155
- * @experimental
155
+ * @beta
156
156
  */
157
157
  export declare class ObcReadoutBlock extends LitElement {
158
158
  /** Semantic variant (value / setpoint / advice). */
@@ -1 +1 @@
1
- {"version":3,"file":"readout-block.js","sources":["../../../src/building-blocks/readout-block/readout-block.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS, type TemplateResult} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport componentStyle from './readout-block.css?inline';\nimport {customElement} from '../../decorator.js';\nimport '../../components/textbox/textbox.js';\nimport {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n ObcTextboxAlignment,\n} from '../../components/textbox/textbox.js';\nimport '../../icons/icon-input-right.js';\nimport '../../icons/icon-notification-advice.js';\nimport '../../icons/icon-notification-advice-active.js';\nimport '../../icons/icon-caution-google.js';\nimport '../../icons/icon-caution-color-iec.js';\nimport '../../icons/icon-warning-unacknowledged-outlined.js';\nimport '../../icons/icon-warning-unacknowledged-iec.js';\nimport '../../icons/icon-alarm.js';\nimport '../../icons/icon-alarm-unacknowledged-iec.js';\nimport '../../icons/icon-running.js';\nimport '../../icons/icon-running-color-iec.js';\nimport {\n formatNumericValue,\n readoutFormattedInteger,\n assertReadoutValueType,\n assertReadoutFractionDigits,\n isReadoutDigitCountMissing,\n resolveReadoutDigitCount,\n resolveReadoutNumericValue,\n resolveReadoutTextValue,\n READOUT_UNAVAILABLE_DASH,\n ReadoutValueType,\n type ReadoutNumericFormatOptions,\n} from '../../navigation-instruments/readout/readout-formatters.js';\nimport {\n type AlertFrameConfig,\n wrapWithAlertFrame,\n} from '../../components/alert-frame/alert-frame.js';\n\n// Re-exported so consumers can configure typography without a second import path.\nexport {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n ObcTextboxAlignment,\n} from '../../components/textbox/textbox.js';\nexport {ReadoutValueType} from '../../navigation-instruments/readout/readout-formatters.js';\n\n/**\n * Semantic variant of the block. Drives the default marker icon and the\n * colour token; the layout is identical across variants.\n * - `value`: the primary reading (no default marker icon).\n * - `setpoint`: a setpoint reference (default `input-right` marker).\n * - `advice`: an advisory reference (default `notification-advice` marker).\n */\nexport enum ReadoutBlockVariant {\n value = 'value',\n setpoint = 'setpoint',\n advice = 'advice',\n}\n\n/**\n * Density tier of the block — drives icon size, the icon↔number gap, and the\n * degree-column width tier. The number typography size is controlled\n * independently via {@link ObcReadoutBlock.valueSize} so a parent can de-emphasise\n * one block relative to another within the same tier.\n */\nexport enum ReadoutBlockSize {\n small = 'small',\n medium = 'medium',\n large = 'large',\n}\n\n/**\n * Per-block measurement quality, rendered as a non-shifting outline chip.\n * - `low-integrity`: the value is suspect.\n * - `invalid`: the value is invalid.\n */\nexport enum ReadoutBlockDataQuality {\n lowIntegrity = 'low-integrity',\n invalid = 'invalid',\n}\n\n/**\n * Semantic category of an advice block (Figma 6.1 \"Readout-block-advice\"\n * Value axis). Drives the default marker icon and — while {@link\n * ObcReadoutBlock.active} — the triggered styling:\n * - `regular` / `optimal` / `eco`: the advice diamond; triggered renders the\n * filled diamond (tinted enhanced-blue / mint for optimal / eco) and a\n * SemiBold number.\n * - `caution` / `warning` / `alarm` / `running`: the matching neutral outline\n * icon; triggered swaps in the filled IEC status icon and the active text\n * colour.\n *\n * TODO(designer): the optimal / eco triggered tint covers the whole diamond\n * glyph — the Figma icon tints only the inner plus, which needs a two-tone\n * icon asset; and the advice \"Enhanced\" state (indent background chip) is not\n * implemented yet. Both flagged as \"may change\" in the 6.1 review.\n */\nexport enum ReadoutAdviceCategory {\n regular = 'regular',\n optimal = 'optimal',\n eco = 'eco',\n caution = 'caution',\n warning = 'warning',\n alarm = 'alarm',\n running = 'running',\n}\n\n/**\n * Pop-up fade phase for a setpoint block. Driven by the parent's setpoint\n * interaction state machine; only meaningful for `role=\"setpoint\"`.\n */\nexport enum ReadoutBlockHidePhase {\n none = 'none',\n hiding = 'hiding',\n hidden = 'hidden',\n}\n\n/**\n * `<obc-readout-block>` – the most atomic readout primitive: a single\n * cap-height-aligned, width-reservable numeric segment (value / setpoint /\n * advice).\n *\n * It renders one `obc-textbox` number with optional hinted leading zeros, a\n * reservable width, an optional leading marker icon (via the `icon` slot or the\n * role default), an optional trailing degree glyph, an `off`/unavailable text\n * state, per-block data-quality and an optional per-block alert frame.\n *\n * Setting `valueType` to `text` renders `value` verbatim (e.g.\n * `\"Auto\"`) instead of a formatted number.\n *\n * This is a building block used inside `obc-readout-list-item` (and, in a future\n * refactor, inside `obc-readout`); it is not normally used on its own. Colour is\n * inherited from the host context (the parent sets the role colour), so the\n * block stays neutral until placed.\n *\n * @property variant - Semantic variant (value / setpoint / advice).\n * @property value - The value; `null`/`undefined` renders a dash. A number by default, or text when\n * `valueType` is `text`.\n * @property valueType - How `value` is interpreted. `number` (default) formats it via\n * `fractionDigits`; `text` renders it verbatim and ignores the numeric\n * format options. Passing text while this is `number` throws.\n * @property size - Density tier — icon size, gap, degree tier.\n * @property valueSize - Resolved number-typography size. When unset it is derived from `size`\n * (small→s, medium→m, large→l), so a parent that de-emphasises a block (e.g.\n * a secondary setpoint) can pass a smaller size without changing the tier.\n * @property enhanced - Accent (in-command) colour tone.\n * @property weight - Number font weight (regular / semibold / bold); colour is independent.\n * @property hasDegree - Render the trailing cap-height degree glyph (`°`).\n * @property hasIcon - Show the leading marker-icon container (always on for setpoint/advice).\n * @property fractionDigits - Number of fraction digits. Must be between 0 and 100 — the range\n * `Number.prototype.toFixed` accepts; outside it throws a `RangeError`.\n * A fractional count truncates (`2.7` → `2`). A count that never arrived\n * (`NaN`, `null` or unset) renders the reading as the unavailable dash —\n * formatting with a precision the author never chose would let a critical\n * `0.4` pass for a healthy `0`.\n * @availableWhen fractionDigits valueType==number\n * @property maxDigits - Integer digits to reserve / hint (independent of `fractionDigits`).\n * Bounded before use: a fractional count\n * truncates (`2.7` → `2`), anything above 100 — including `Infinity` —\n * caps at 100, and a negative count reserves nothing. A count that never\n * arrived (`NaN`, `null` or unset) renders the reading as the unavailable\n * dash, consistent with `fractionDigits`.\n * @availableWhen maxDigits valueType==number\n * @property hintedZeros - Render muted leading zeros filling the integer part to `maxDigits`.\n * @availableWhen hintedZeros valueType==number\n * @property spaceReserver - Explicit longest string to reserve width for (e.g. `\"0000.0\"`).\n * @property off - Render `offText` instead of a number (e.g. equipment powered down).\n * @property offText - Text shown when `off` is true.\n * @property alignment - Text alignment of the number within its reserved width.\n * @property active - The advice is triggered: the marker swaps to its filled/status icon and\n * the number takes the category's triggered styling (SemiBold for\n * regular/optimal/eco, active text colour for the alert categories). Only\n * meaningful for `variant=\"advice\"`.\n * @availableWhen active variant==advice\n * @property dataQuality - Per-block measurement quality (outline chip).\n * @property alert - Per-block alert frame; nests inside any parent alert frame.\n * @property touching - Setpoint focus (touch) state — only meaningful for `role=\"setpoint\"`.\n * @property hidePhase - Setpoint pop-up fade phase — only meaningful for `role=\"setpoint\"`.\n * @property category - Semantic category of an advice block — picks the default marker icon\n * and the `active` styling. Only meaningful for `variant=\"advice\"`.\n * @availableWhen category variant==advice\n * @slot icon - Replaces the role's default marker icon.\n * @csspart block - The block container (carries role / tone / data-quality).\n * @csspart block-content - The number + degree group.\n * @csspart block-text - The `obc-textbox` rendering the number.\n * @csspart block-icon - The leading marker-icon container.\n * @csspart degree - The trailing degree-glyph column.\n * @experimental\n */\n@customElement('obc-readout-block')\nexport class ObcReadoutBlock extends LitElement {\n @property({type: String}) variant: ReadoutBlockVariant =\n ReadoutBlockVariant.value;\n\n @property({type: String}) value: number | string | null = null;\n\n @property({type: String}) valueType: ReadoutValueType =\n ReadoutValueType.number;\n\n @property({type: String}) size: ReadoutBlockSize = ReadoutBlockSize.small;\n\n @property({type: String}) valueSize?: ObcTextboxSize;\n\n @property({type: Boolean}) enhanced = false;\n\n @property({type: String}) weight: ObcTextboxFontWeight =\n ObcTextboxFontWeight.regular;\n\n @property({type: Boolean}) hasDegree = false;\n\n @property({type: Boolean}) hasIcon = false;\n\n @property({type: Number}) fractionDigits = 0;\n\n @property({type: Number}) maxDigits = 0;\n\n @property({type: Boolean}) hintedZeros = false;\n\n @property({type: String}) spaceReserver?: string;\n\n @property({type: Boolean}) off = false;\n\n @property({type: String}) offText = 'OFF';\n\n @property({type: String}) alignment: ObcTextboxAlignment =\n ObcTextboxAlignment.Right;\n\n @property({type: String}) category: ReadoutAdviceCategory =\n ReadoutAdviceCategory.regular;\n\n @property({type: Boolean}) active = false;\n\n @property({type: String}) dataQuality?: ReadoutBlockDataQuality;\n\n // `boolean | …` (not `false | …`): the generated Angular wrapper widens a\n // literal-`false` union to `boolean`. `wrapWithAlertFrame` treats any\n // non-object as \"no frame\", so accepting `boolean` is harmless.\n @property({type: Object}) alert: boolean | AlertFrameConfig = false;\n\n @property({type: Boolean}) touching = false;\n\n @property({type: String}) hidePhase: ReadoutBlockHidePhase =\n ReadoutBlockHidePhase.none;\n\n @state() private hasAssignedIcon = false;\n\n private get resolvedValueSize(): ObcTextboxSize {\n if (this.valueSize) {\n return this.valueSize;\n }\n switch (this.size) {\n case ReadoutBlockSize.large:\n return ObcTextboxSize.l;\n case ReadoutBlockSize.medium:\n return ObcTextboxSize.m;\n default:\n return ObcTextboxSize.s;\n }\n }\n\n /**\n * `maxDigits` bounded to a usable count. Every width calculation below goes\n * through this rather than the raw property, so an `Infinity` (or absurdly\n * large) value cannot reach `String.prototype.repeat`.\n */\n private get resolvedMaxDigits(): number {\n return resolveReadoutDigitCount(this.maxDigits);\n }\n\n /**\n * Whether a digit knob failed to arrive (`NaN` / `null` / `undefined`).\n * The reading then renders as the unavailable dash rather than silently\n * formatting with a default the author never chose — a critical `0.4`\n * formatted with a failed `fractionDigits` would otherwise print as a\n * plausible-looking `0`. A missing `maxDigits` dashes too, for consistency:\n * either knob arriving broken means the row's configuration cannot be\n * trusted.\n */\n private get digitCountsMissing(): boolean {\n return (\n isReadoutDigitCountMissing(this.fractionDigits) ||\n isReadoutDigitCountMissing(this.maxDigits)\n );\n }\n\n private get numericFormatOptions(): ReadoutNumericFormatOptions {\n return {\n // The unavailable placeholder stays short (`\\u2012.\\u2012\\u2012`): `maxDigits`\n // already reserves the width, so it sits at the right edge of it.\n showZeroPadding: false,\n minValueLength: this.resolvedMaxDigits,\n // A missing precision shapes the placeholder as zero fraction digits (a\n // single dash) — and keeps a runtime `undefined`/`null` out of the\n // options object, which is typed `number` throughout the formatters.\n fractionDigits: isReadoutDigitCountMissing(this.fractionDigits)\n ? 0\n : this.fractionDigits,\n };\n }\n\n /** Widest possible value string for width reservation (e.g. `\"000.0\"`). */\n private get reserverText(): string {\n const maxDigits = this.resolvedMaxDigits;\n if (maxDigits <= 0) {\n return '';\n }\n const integer = '0'.repeat(maxDigits);\n return this.fractionDigits > 0\n ? `${integer}.${'0'.repeat(this.fractionDigits)}`\n : integer;\n }\n\n /**\n * Effective width reserver: the wider of the explicit `spaceReserver` and the\n * `maxDigits`/`fractionDigits`-derived reserve, so an explicit reserver can\n * never reserve *less* than the formatted value needs. Under tabular-nums the\n * rendered width is proportional to character count, so \"wider\" compares length.\n */\n private widerReserver(explicit: string | undefined, derived: string): string {\n if (!explicit) {\n return derived;\n }\n if (!derived) {\n return explicit;\n }\n return explicit.length >= derived.length ? explicit : derived;\n }\n\n private dataQualityClasses(): Record<string, boolean> {\n return {\n 'data-low-integrity':\n this.dataQuality === ReadoutBlockDataQuality.lowIntegrity,\n 'data-invalid': this.dataQuality === ReadoutBlockDataQuality.invalid,\n };\n }\n\n private onIconSlotChange = (event: Event): void => {\n // `slotchange` fires after the first render once content is (re)assigned,\n // so it covers the initial state without a firstUpdated re-render.\n this.hasAssignedIcon =\n (event.target as HTMLSlotElement).assignedElements({flatten: true})\n .length > 0;\n };\n\n private renderIcon(): TemplateResult | typeof nothing {\n // Value blocks only show an icon when asked; setpoint/advice always reserve\n // their marker. The role default is rendered as a direct child (so it sizes\n // via `.block-icon obi-*`) and hidden once an icon is assigned to the slot —\n // `{flatten: true}` sees through a forwarded-but-empty parent slot, so the\n // default still shows when the consumer overrides nothing.\n const showIcon = this.variant !== ReadoutBlockVariant.value || this.hasIcon;\n if (!showIcon) {\n return nothing;\n }\n let fallback: TemplateResult | typeof nothing = nothing;\n if (this.variant === ReadoutBlockVariant.setpoint) {\n fallback = html`<obi-input-right></obi-input-right>`;\n } else if (this.variant === ReadoutBlockVariant.advice) {\n fallback = this.adviceFallbackIcon();\n }\n return html`<span class=\"block-icon\" part=\"block-icon\" aria-hidden=\"true\">\n <slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot>\n ${this.hasAssignedIcon ? nothing : fallback}\n </span>`;\n }\n\n /**\n * The advice marker for the current category / triggered state. Resting\n * categories carry a neutral outline glyph (tinted via `currentColor`);\n * triggered alert categories swap to the filled IEC status icon rendered\n * with `useCssColor`, which selects the icon's token-coloured variant\n * (alert fill + on-alert glyph, e.g. `--alert-caution-color` +\n * `--on-caution-active-color`) — without it the same icon is a\n * single-colour `currentColor` silhouette. This mirrors `obc-alert-icon`.\n * The resting icons and the advice diamond deliberately stay on\n * `currentColor`: their css-colour variants hard-code\n * `--element-active-color`, which would defeat the neutral tint and the\n * optimal / eco triggered tint applied from CSS.\n */\n private adviceFallbackIcon(): TemplateResult {\n const active = this.active;\n switch (this.category) {\n case ReadoutAdviceCategory.caution:\n return active\n ? html`<obi-caution-color-iec useCssColor></obi-caution-color-iec>`\n : html`<obi-caution-google></obi-caution-google>`;\n case ReadoutAdviceCategory.warning:\n return active\n ? html`<obi-warning-unacknowledged-iec\n useCssColor\n ></obi-warning-unacknowledged-iec>`\n : html`<obi-warning-unacknowledged-outlined></obi-warning-unacknowledged-outlined>`;\n case ReadoutAdviceCategory.alarm:\n return active\n ? html`<obi-alarm-unacknowledged-iec\n useCssColor\n ></obi-alarm-unacknowledged-iec>`\n : html`<obi-alarm></obi-alarm>`;\n case ReadoutAdviceCategory.running:\n return active\n ? html`<obi-running-color-iec useCssColor></obi-running-color-iec>`\n : html`<obi-running></obi-running>`;\n default:\n // regular / optimal / eco share the advice diamond; the triggered tint\n // is applied via CSS on `.block-icon` (see `advice-*` classes).\n return active\n ? html`<obi-notification-advice-active></obi-notification-advice-active>`\n : html`<obi-notification-advice></obi-notification-advice>`;\n }\n }\n\n /**\n * A cap-height `°` column whose width scales with the number size. Inherits the\n * block's colour.\n */\n private renderDegreeGlyph(size: ObcTextboxSize): TemplateResult {\n return html`\n <span\n class=${classMap({\n 'degree-column': true,\n [`degree-${size}`]: true,\n 'degree-inherit': true,\n })}\n part=\"degree\"\n >\n <obc-textbox class=\"degree-glyph\" .size=${size} alignment=\"center\"\n >°</obc-textbox\n >\n </span>\n `;\n }\n\n protected override willUpdate(changed: Map<string, unknown>): void {\n super.willUpdate(changed);\n // Never gate this on `changed`: a throw clears Lit's changed map, so the\n // next update would skip the check and render the invalid value as a dash\n // (readout-components.md § 1, pinned by readout-block.spec.ts).\n assertReadoutValueType('obc-readout-block', this.value, this.valueType);\n assertReadoutFractionDigits('obc-readout-block', this.fractionDigits);\n }\n\n override render() {\n const valueSize = this.resolvedValueSize;\n const isAdvice = this.variant === ReadoutBlockVariant.advice;\n // Triggered regular/optimal/eco advice renders SemiBold (Figma 6.1); the\n // alert categories keep the caller's weight and change colour instead.\n const adviceSemibold =\n isAdvice &&\n this.active &&\n (this.category === ReadoutAdviceCategory.regular ||\n this.category === ReadoutAdviceCategory.optimal ||\n this.category === ReadoutAdviceCategory.eco);\n const weight = adviceSemibold ? ObcTextboxFontWeight.semibold : this.weight;\n const formatOptions = this.numericFormatOptions;\n const isTextMode = this.valueType === ReadoutValueType.text;\n // A missing digit knob makes the reading untrustworthy, so it resolves to\n // \"no reading\" and renders the dash (see `digitCountsMissing`). Text mode\n // is unaffected — it ignores the numeric knobs entirely.\n const valueForFormat = this.digitCountsMissing\n ? undefined\n : resolveReadoutNumericValue(this.value, this.valueType);\n const textValue = resolveReadoutTextValue(this.value, this.valueType);\n // Text mode renders verbatim and ignores the numeric format options; a\n // blank / missing text value still falls back to the unavailable dash.\n const text = this.off\n ? this.offText\n : isTextMode\n ? (textValue ?? READOUT_UNAVAILABLE_DASH)\n : formatNumericValue(valueForFormat, formatOptions);\n // Hinted zeros pad the INTEGER part up to `maxDigits`, independent of\n // `fractionDigits` (the decimal point and fraction digits never count toward\n // `maxDigits`). Negative / dashed values are not padded. Example: value 1.2,\n // maxDigits 3, fractionDigits 1 → \"001.2\".\n const hintCount =\n this.off ||\n isTextMode ||\n !this.hintedZeros ||\n valueForFormat === undefined ||\n valueForFormat < 0\n ? 0\n : Math.max(this.resolvedMaxDigits - readoutFormattedInteger(text), 0);\n const hinted = hintCount > 0 ? '0'.repeat(hintCount) : '';\n // Hinted zeros already fill to `maxDigits`, so they win over an explicit\n // `spaceReserver`; otherwise the wider of the two reserves wins. Text mode\n // honours only an explicit `spaceReserver` (readout-components.md § 4).\n const reserver = isTextMode\n ? (this.spaceReserver ?? '')\n : this.hintedZeros\n ? this.reserverText\n : this.widerReserver(this.spaceReserver, this.reserverText);\n\n const block = html`\n <div\n class=${classMap({\n block: true,\n [`block-${this.variant}`]: true,\n [`size-${this.size}`]: true,\n [`value-size-${valueSize}`]: true,\n [`advice-${this.category}`]: isAdvice,\n 'advice-active': isAdvice && this.active,\n 'tone-enhanced': this.enhanced,\n touching: this.touching,\n 'is-hiding': this.hidePhase === ReadoutBlockHidePhase.hiding,\n 'is-hidden': this.hidePhase === ReadoutBlockHidePhase.hidden,\n ...this.dataQualityClasses(),\n })}\n part=\"block block-${this.variant}\"\n >\n ${this.renderIcon()}\n <span class=\"block-content\" part=\"block-content\">\n <obc-textbox\n class=\"block-text\"\n part=\"block-text\"\n .size=${valueSize}\n .fontWeight=${weight}\n .alignment=${this.alignment}\n .tabularNums=${true}\n >\n ${hinted\n ? html`<span class=\"hinted-zero\" aria-hidden=\"true\"\n >${hinted}</span\n >`\n : nothing}${text}\n ${reserver ? html`<span slot=\"length\">${reserver}</span>` : nothing}\n </obc-textbox>\n ${this.hasDegree ? this.renderDegreeGlyph(valueSize) : nothing}\n </span>\n </div>\n `;\n return wrapWithAlertFrame(this.alert ?? false, block);\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-readout-block': ObcReadoutBlock;\n }\n}\n"],"names":["ReadoutBlockVariant","ReadoutBlockSize","ReadoutBlockDataQuality","ReadoutAdviceCategory","ReadoutBlockHidePhase"],"mappings":"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"}
1
+ {"version":3,"file":"readout-block.js","sources":["../../../src/building-blocks/readout-block/readout-block.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS, type TemplateResult} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport componentStyle from './readout-block.css?inline';\nimport {customElement} from '../../decorator.js';\nimport '../../components/textbox/textbox.js';\nimport {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n ObcTextboxAlignment,\n} from '../../components/textbox/textbox.js';\nimport '../../icons/icon-input-right.js';\nimport '../../icons/icon-notification-advice.js';\nimport '../../icons/icon-notification-advice-active.js';\nimport '../../icons/icon-caution-google.js';\nimport '../../icons/icon-caution-color-iec.js';\nimport '../../icons/icon-warning-unacknowledged-outlined.js';\nimport '../../icons/icon-warning-unacknowledged-iec.js';\nimport '../../icons/icon-alarm.js';\nimport '../../icons/icon-alarm-unacknowledged-iec.js';\nimport '../../icons/icon-running.js';\nimport '../../icons/icon-running-color-iec.js';\nimport {\n formatNumericValue,\n readoutFormattedInteger,\n assertReadoutValueType,\n assertReadoutFractionDigits,\n isReadoutDigitCountMissing,\n resolveReadoutDigitCount,\n resolveReadoutNumericValue,\n resolveReadoutTextValue,\n READOUT_UNAVAILABLE_DASH,\n ReadoutValueType,\n type ReadoutNumericFormatOptions,\n} from '../../navigation-instruments/readout/readout-formatters.js';\nimport {\n type AlertFrameConfig,\n wrapWithAlertFrame,\n} from '../../components/alert-frame/alert-frame.js';\n\n// Re-exported so consumers can configure typography without a second import path.\nexport {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n ObcTextboxAlignment,\n} from '../../components/textbox/textbox.js';\nexport {ReadoutValueType} from '../../navigation-instruments/readout/readout-formatters.js';\n\n/**\n * Semantic variant of the block. Drives the default marker icon and the\n * colour token; the layout is identical across variants.\n * - `value`: the primary reading (no default marker icon).\n * - `setpoint`: a setpoint reference (default `input-right` marker).\n * - `advice`: an advisory reference (default `notification-advice` marker).\n */\nexport enum ReadoutBlockVariant {\n value = 'value',\n setpoint = 'setpoint',\n advice = 'advice',\n}\n\n/**\n * Density tier of the block — drives icon size, the icon↔number gap, and the\n * degree-column width tier. The number typography size is controlled\n * independently via {@link ObcReadoutBlock.valueSize} so a parent can de-emphasise\n * one block relative to another within the same tier.\n */\nexport enum ReadoutBlockSize {\n small = 'small',\n medium = 'medium',\n large = 'large',\n}\n\n/**\n * Per-block measurement quality, rendered as a non-shifting outline chip.\n * - `low-integrity`: the value is suspect.\n * - `invalid`: the value is invalid.\n */\nexport enum ReadoutBlockDataQuality {\n lowIntegrity = 'low-integrity',\n invalid = 'invalid',\n}\n\n/**\n * Semantic category of an advice block (Figma 6.1 \"Readout-block-advice\"\n * Value axis). Drives the default marker icon and — while {@link\n * ObcReadoutBlock.active} — the triggered styling:\n * - `regular` / `optimal` / `eco`: the advice diamond; triggered renders the\n * filled diamond (tinted enhanced-blue / mint for optimal / eco) and a\n * SemiBold number.\n * - `caution` / `warning` / `alarm` / `running`: the matching neutral outline\n * icon; triggered swaps in the filled IEC status icon and the active text\n * colour.\n *\n * TODO(designer): the optimal / eco triggered tint covers the whole diamond\n * glyph — the Figma icon tints only the inner plus, which needs a two-tone\n * icon asset; and the advice \"Enhanced\" state (indent background chip) is not\n * implemented yet. Both flagged as \"may change\" in the 6.1 review.\n */\nexport enum ReadoutAdviceCategory {\n regular = 'regular',\n optimal = 'optimal',\n eco = 'eco',\n caution = 'caution',\n warning = 'warning',\n alarm = 'alarm',\n running = 'running',\n}\n\n/**\n * Pop-up fade phase for a setpoint block. Driven by the parent's setpoint\n * interaction state machine; only meaningful for `role=\"setpoint\"`.\n */\nexport enum ReadoutBlockHidePhase {\n none = 'none',\n hiding = 'hiding',\n hidden = 'hidden',\n}\n\n/**\n * `<obc-readout-block>` – the most atomic readout primitive: a single\n * cap-height-aligned, width-reservable numeric segment (value / setpoint /\n * advice).\n *\n * It renders one `obc-textbox` number with optional hinted leading zeros, a\n * reservable width, an optional leading marker icon (via the `icon` slot or the\n * role default), an optional trailing degree glyph, an `off`/unavailable text\n * state, per-block data-quality and an optional per-block alert frame.\n *\n * Setting `valueType` to `text` renders `value` verbatim (e.g.\n * `\"Auto\"`) instead of a formatted number.\n *\n * This is a building block used inside `obc-readout-list-item` (and, in a future\n * refactor, inside `obc-readout`); it is not normally used on its own. Colour is\n * inherited from the host context (the parent sets the role colour), so the\n * block stays neutral until placed.\n *\n * @property variant - Semantic variant (value / setpoint / advice).\n * @property value - The value; `null`/`undefined` renders a dash. A number by default, or text when\n * `valueType` is `text`.\n * @property valueType - How `value` is interpreted. `number` (default) formats it via\n * `fractionDigits`; `text` renders it verbatim and ignores the numeric\n * format options. Passing text while this is `number` throws.\n * @property size - Density tier — icon size, gap, degree tier.\n * @property valueSize - Resolved number-typography size. When unset it is derived from `size`\n * (small→s, medium→m, large→l), so a parent that de-emphasises a block (e.g.\n * a secondary setpoint) can pass a smaller size without changing the tier.\n * @property enhanced - Accent (in-command) colour tone.\n * @property weight - Number font weight (regular / semibold / bold); colour is independent.\n * @property hasDegree - Render the trailing cap-height degree glyph (`°`).\n * @property hasIcon - Show the leading marker-icon container (always on for setpoint/advice).\n * @property fractionDigits - Number of fraction digits. Must be between 0 and 100 — the range\n * `Number.prototype.toFixed` accepts; outside it throws a `RangeError`.\n * A fractional count truncates (`2.7` → `2`). A count that never arrived\n * (`NaN`, `null` or unset) renders the reading as the unavailable dash —\n * formatting with a precision the author never chose would let a critical\n * `0.4` pass for a healthy `0`.\n * @availableWhen fractionDigits valueType==number\n * @property maxDigits - Integer digits to reserve / hint (independent of `fractionDigits`).\n * Bounded before use: a fractional count\n * truncates (`2.7` → `2`), anything above 100 — including `Infinity` —\n * caps at 100, and a negative count reserves nothing. A count that never\n * arrived (`NaN`, `null` or unset) renders the reading as the unavailable\n * dash, consistent with `fractionDigits`.\n * @availableWhen maxDigits valueType==number\n * @property hintedZeros - Render muted leading zeros filling the integer part to `maxDigits`.\n * @availableWhen hintedZeros valueType==number\n * @property spaceReserver - Explicit longest string to reserve width for (e.g. `\"0000.0\"`).\n * @property off - Render `offText` instead of a number (e.g. equipment powered down).\n * @property offText - Text shown when `off` is true.\n * @property alignment - Text alignment of the number within its reserved width.\n * @property active - The advice is triggered: the marker swaps to its filled/status icon and\n * the number takes the category's triggered styling (SemiBold for\n * regular/optimal/eco, active text colour for the alert categories). Only\n * meaningful for `variant=\"advice\"`.\n * @availableWhen active variant==advice\n * @property dataQuality - Per-block measurement quality (outline chip).\n * @property alert - Per-block alert frame; nests inside any parent alert frame.\n * @property touching - Setpoint focus (touch) state — only meaningful for `role=\"setpoint\"`.\n * @property hidePhase - Setpoint pop-up fade phase — only meaningful for `role=\"setpoint\"`.\n * @property category - Semantic category of an advice block — picks the default marker icon\n * and the `active` styling. Only meaningful for `variant=\"advice\"`.\n * @availableWhen category variant==advice\n * @slot icon - Replaces the role's default marker icon.\n * @csspart block - The block container (carries role / tone / data-quality).\n * @csspart block-content - The number + degree group.\n * @csspart block-text - The `obc-textbox` rendering the number.\n * @csspart block-icon - The leading marker-icon container.\n * @csspart degree - The trailing degree-glyph column.\n * @beta\n */\n@customElement('obc-readout-block')\nexport class ObcReadoutBlock extends LitElement {\n @property({type: String}) variant: ReadoutBlockVariant =\n ReadoutBlockVariant.value;\n\n @property({type: String}) value: number | string | null = null;\n\n @property({type: String}) valueType: ReadoutValueType =\n ReadoutValueType.number;\n\n @property({type: String}) size: ReadoutBlockSize = ReadoutBlockSize.small;\n\n @property({type: String}) valueSize?: ObcTextboxSize;\n\n @property({type: Boolean}) enhanced = false;\n\n @property({type: String}) weight: ObcTextboxFontWeight =\n ObcTextboxFontWeight.regular;\n\n @property({type: Boolean}) hasDegree = false;\n\n @property({type: Boolean}) hasIcon = false;\n\n @property({type: Number}) fractionDigits = 0;\n\n @property({type: Number}) maxDigits = 0;\n\n @property({type: Boolean}) hintedZeros = false;\n\n @property({type: String}) spaceReserver?: string;\n\n @property({type: Boolean}) off = false;\n\n @property({type: String}) offText = 'OFF';\n\n @property({type: String}) alignment: ObcTextboxAlignment =\n ObcTextboxAlignment.Right;\n\n @property({type: String}) category: ReadoutAdviceCategory =\n ReadoutAdviceCategory.regular;\n\n @property({type: Boolean}) active = false;\n\n @property({type: String}) dataQuality?: ReadoutBlockDataQuality;\n\n // `boolean | …` (not `false | …`): the generated Angular wrapper widens a\n // literal-`false` union to `boolean`. `wrapWithAlertFrame` treats any\n // non-object as \"no frame\", so accepting `boolean` is harmless.\n @property({type: Object}) alert: boolean | AlertFrameConfig = false;\n\n @property({type: Boolean}) touching = false;\n\n @property({type: String}) hidePhase: ReadoutBlockHidePhase =\n ReadoutBlockHidePhase.none;\n\n @state() private hasAssignedIcon = false;\n\n private get resolvedValueSize(): ObcTextboxSize {\n if (this.valueSize) {\n return this.valueSize;\n }\n switch (this.size) {\n case ReadoutBlockSize.large:\n return ObcTextboxSize.l;\n case ReadoutBlockSize.medium:\n return ObcTextboxSize.m;\n default:\n return ObcTextboxSize.s;\n }\n }\n\n /**\n * `maxDigits` bounded to a usable count. Every width calculation below goes\n * through this rather than the raw property, so an `Infinity` (or absurdly\n * large) value cannot reach `String.prototype.repeat`.\n */\n private get resolvedMaxDigits(): number {\n return resolveReadoutDigitCount(this.maxDigits);\n }\n\n /**\n * Whether a digit knob failed to arrive (`NaN` / `null` / `undefined`).\n * The reading then renders as the unavailable dash rather than silently\n * formatting with a default the author never chose — a critical `0.4`\n * formatted with a failed `fractionDigits` would otherwise print as a\n * plausible-looking `0`. A missing `maxDigits` dashes too, for consistency:\n * either knob arriving broken means the row's configuration cannot be\n * trusted.\n */\n private get digitCountsMissing(): boolean {\n return (\n isReadoutDigitCountMissing(this.fractionDigits) ||\n isReadoutDigitCountMissing(this.maxDigits)\n );\n }\n\n private get numericFormatOptions(): ReadoutNumericFormatOptions {\n return {\n // The unavailable placeholder stays short (`\\u2012.\\u2012\\u2012`): `maxDigits`\n // already reserves the width, so it sits at the right edge of it.\n showZeroPadding: false,\n minValueLength: this.resolvedMaxDigits,\n // A missing precision shapes the placeholder as zero fraction digits (a\n // single dash) — and keeps a runtime `undefined`/`null` out of the\n // options object, which is typed `number` throughout the formatters.\n fractionDigits: isReadoutDigitCountMissing(this.fractionDigits)\n ? 0\n : this.fractionDigits,\n };\n }\n\n /** Widest possible value string for width reservation (e.g. `\"000.0\"`). */\n private get reserverText(): string {\n const maxDigits = this.resolvedMaxDigits;\n if (maxDigits <= 0) {\n return '';\n }\n const integer = '0'.repeat(maxDigits);\n return this.fractionDigits > 0\n ? `${integer}.${'0'.repeat(this.fractionDigits)}`\n : integer;\n }\n\n /**\n * Effective width reserver: the wider of the explicit `spaceReserver` and the\n * `maxDigits`/`fractionDigits`-derived reserve, so an explicit reserver can\n * never reserve *less* than the formatted value needs. Under tabular-nums the\n * rendered width is proportional to character count, so \"wider\" compares length.\n */\n private widerReserver(explicit: string | undefined, derived: string): string {\n if (!explicit) {\n return derived;\n }\n if (!derived) {\n return explicit;\n }\n return explicit.length >= derived.length ? explicit : derived;\n }\n\n private dataQualityClasses(): Record<string, boolean> {\n return {\n 'data-low-integrity':\n this.dataQuality === ReadoutBlockDataQuality.lowIntegrity,\n 'data-invalid': this.dataQuality === ReadoutBlockDataQuality.invalid,\n };\n }\n\n private onIconSlotChange = (event: Event): void => {\n // `slotchange` fires after the first render once content is (re)assigned,\n // so it covers the initial state without a firstUpdated re-render.\n this.hasAssignedIcon =\n (event.target as HTMLSlotElement).assignedElements({flatten: true})\n .length > 0;\n };\n\n private renderIcon(): TemplateResult | typeof nothing {\n // Value blocks only show an icon when asked; setpoint/advice always reserve\n // their marker. The role default is rendered as a direct child (so it sizes\n // via `.block-icon obi-*`) and hidden once an icon is assigned to the slot —\n // `{flatten: true}` sees through a forwarded-but-empty parent slot, so the\n // default still shows when the consumer overrides nothing.\n const showIcon = this.variant !== ReadoutBlockVariant.value || this.hasIcon;\n if (!showIcon) {\n return nothing;\n }\n let fallback: TemplateResult | typeof nothing = nothing;\n if (this.variant === ReadoutBlockVariant.setpoint) {\n fallback = html`<obi-input-right></obi-input-right>`;\n } else if (this.variant === ReadoutBlockVariant.advice) {\n fallback = this.adviceFallbackIcon();\n }\n return html`<span class=\"block-icon\" part=\"block-icon\" aria-hidden=\"true\">\n <slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot>\n ${this.hasAssignedIcon ? nothing : fallback}\n </span>`;\n }\n\n /**\n * The advice marker for the current category / triggered state. Resting\n * categories carry a neutral outline glyph (tinted via `currentColor`);\n * triggered alert categories swap to the filled IEC status icon rendered\n * with `useCssColor`, which selects the icon's token-coloured variant\n * (alert fill + on-alert glyph, e.g. `--alert-caution-color` +\n * `--on-caution-active-color`) — without it the same icon is a\n * single-colour `currentColor` silhouette. This mirrors `obc-alert-icon`.\n * The resting icons and the advice diamond deliberately stay on\n * `currentColor`: their css-colour variants hard-code\n * `--element-active-color`, which would defeat the neutral tint and the\n * optimal / eco triggered tint applied from CSS.\n */\n private adviceFallbackIcon(): TemplateResult {\n const active = this.active;\n switch (this.category) {\n case ReadoutAdviceCategory.caution:\n return active\n ? html`<obi-caution-color-iec useCssColor></obi-caution-color-iec>`\n : html`<obi-caution-google></obi-caution-google>`;\n case ReadoutAdviceCategory.warning:\n return active\n ? html`<obi-warning-unacknowledged-iec\n useCssColor\n ></obi-warning-unacknowledged-iec>`\n : html`<obi-warning-unacknowledged-outlined></obi-warning-unacknowledged-outlined>`;\n case ReadoutAdviceCategory.alarm:\n return active\n ? html`<obi-alarm-unacknowledged-iec\n useCssColor\n ></obi-alarm-unacknowledged-iec>`\n : html`<obi-alarm></obi-alarm>`;\n case ReadoutAdviceCategory.running:\n return active\n ? html`<obi-running-color-iec useCssColor></obi-running-color-iec>`\n : html`<obi-running></obi-running>`;\n default:\n // regular / optimal / eco share the advice diamond; the triggered tint\n // is applied via CSS on `.block-icon` (see `advice-*` classes).\n return active\n ? html`<obi-notification-advice-active></obi-notification-advice-active>`\n : html`<obi-notification-advice></obi-notification-advice>`;\n }\n }\n\n /**\n * A cap-height `°` column whose width scales with the number size. Inherits the\n * block's colour.\n */\n private renderDegreeGlyph(size: ObcTextboxSize): TemplateResult {\n return html`\n <span\n class=${classMap({\n 'degree-column': true,\n [`degree-${size}`]: true,\n 'degree-inherit': true,\n })}\n part=\"degree\"\n >\n <obc-textbox class=\"degree-glyph\" .size=${size} alignment=\"center\"\n >°</obc-textbox\n >\n </span>\n `;\n }\n\n protected override willUpdate(changed: Map<string, unknown>): void {\n super.willUpdate(changed);\n // Never gate this on `changed`: a throw clears Lit's changed map, so the\n // next update would skip the check and render the invalid value as a dash\n // (readout-components.md § 1, pinned by readout-block.spec.ts).\n assertReadoutValueType('obc-readout-block', this.value, this.valueType);\n assertReadoutFractionDigits('obc-readout-block', this.fractionDigits);\n }\n\n override render() {\n const valueSize = this.resolvedValueSize;\n const isAdvice = this.variant === ReadoutBlockVariant.advice;\n // Triggered regular/optimal/eco advice renders SemiBold (Figma 6.1); the\n // alert categories keep the caller's weight and change colour instead.\n const adviceSemibold =\n isAdvice &&\n this.active &&\n (this.category === ReadoutAdviceCategory.regular ||\n this.category === ReadoutAdviceCategory.optimal ||\n this.category === ReadoutAdviceCategory.eco);\n const weight = adviceSemibold ? ObcTextboxFontWeight.semibold : this.weight;\n const formatOptions = this.numericFormatOptions;\n const isTextMode = this.valueType === ReadoutValueType.text;\n // A missing digit knob makes the reading untrustworthy, so it resolves to\n // \"no reading\" and renders the dash (see `digitCountsMissing`). Text mode\n // is unaffected — it ignores the numeric knobs entirely.\n const valueForFormat = this.digitCountsMissing\n ? undefined\n : resolveReadoutNumericValue(this.value, this.valueType);\n const textValue = resolveReadoutTextValue(this.value, this.valueType);\n // Text mode renders verbatim and ignores the numeric format options; a\n // blank / missing text value still falls back to the unavailable dash.\n const text = this.off\n ? this.offText\n : isTextMode\n ? (textValue ?? READOUT_UNAVAILABLE_DASH)\n : formatNumericValue(valueForFormat, formatOptions);\n // Hinted zeros pad the INTEGER part up to `maxDigits`, independent of\n // `fractionDigits` (the decimal point and fraction digits never count toward\n // `maxDigits`). Negative / dashed values are not padded. Example: value 1.2,\n // maxDigits 3, fractionDigits 1 → \"001.2\".\n const hintCount =\n this.off ||\n isTextMode ||\n !this.hintedZeros ||\n valueForFormat === undefined ||\n valueForFormat < 0\n ? 0\n : Math.max(this.resolvedMaxDigits - readoutFormattedInteger(text), 0);\n const hinted = hintCount > 0 ? '0'.repeat(hintCount) : '';\n // Hinted zeros already fill to `maxDigits`, so they win over an explicit\n // `spaceReserver`; otherwise the wider of the two reserves wins. Text mode\n // honours only an explicit `spaceReserver` (readout-components.md § 4).\n const reserver = isTextMode\n ? (this.spaceReserver ?? '')\n : this.hintedZeros\n ? this.reserverText\n : this.widerReserver(this.spaceReserver, this.reserverText);\n\n const block = html`\n <div\n class=${classMap({\n block: true,\n [`block-${this.variant}`]: true,\n [`size-${this.size}`]: true,\n [`value-size-${valueSize}`]: true,\n [`advice-${this.category}`]: isAdvice,\n 'advice-active': isAdvice && this.active,\n 'tone-enhanced': this.enhanced,\n touching: this.touching,\n 'is-hiding': this.hidePhase === ReadoutBlockHidePhase.hiding,\n 'is-hidden': this.hidePhase === ReadoutBlockHidePhase.hidden,\n ...this.dataQualityClasses(),\n })}\n part=\"block block-${this.variant}\"\n >\n ${this.renderIcon()}\n <span class=\"block-content\" part=\"block-content\">\n <obc-textbox\n class=\"block-text\"\n part=\"block-text\"\n .size=${valueSize}\n .fontWeight=${weight}\n .alignment=${this.alignment}\n .tabularNums=${true}\n >\n ${hinted\n ? html`<span class=\"hinted-zero\" aria-hidden=\"true\"\n >${hinted}</span\n >`\n : nothing}${text}\n ${reserver ? html`<span slot=\"length\">${reserver}</span>` : nothing}\n </obc-textbox>\n ${this.hasDegree ? this.renderDegreeGlyph(valueSize) : nothing}\n </span>\n </div>\n `;\n return wrapWithAlertFrame(this.alert ?? false, block);\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-readout-block': ObcReadoutBlock;\n }\n}\n"],"names":["ReadoutBlockVariant","ReadoutBlockSize","ReadoutBlockDataQuality","ReadoutAdviceCategory","ReadoutBlockHidePhase"],"mappings":"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"}
@@ -58,7 +58,7 @@ export declare enum ObcTextboxFontWeight {
58
58
  *
59
59
  * @slot - The visible text content.
60
60
  * @slot length - Reserves a minimum width based on its content width.
61
- * @experimental
61
+ * @beta
62
62
  */
63
63
  export declare class ObcTextbox extends LitElement {
64
64
  alignment: ObcTextboxAlignment;
@@ -1 +1 @@
1
- {"version":3,"file":"textbox.js","sources":["../../../src/components/textbox/textbox.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './textbox.css?inline';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nexport enum ObcTextboxAlignment {\n Left = 'left',\n Center = 'center',\n Right = 'right',\n}\n\nexport enum ObcTextboxSize {\n xs = 'xs',\n s = 's',\n m = 'm',\n l = 'l',\n xl = 'xl',\n}\n\nexport enum ObcTextboxFontWeight {\n regular = 'regular',\n semibold = 'semibold',\n bold = 'bold',\n}\n\n/**\n * `<obc-textbox>` – A text container that renders inline text at a\n * precise, cap-height-trimmed size with configurable alignment and reservable\n * width.\n *\n * Use it to present short, read-only strings – such as values, labels, or\n * units – where vertical metrics must line up exactly across rows and the\n * horizontal footprint should stay stable while the text changes (for example\n * a numeric value that updates frequently). Synonyms: text container, value\n * box, label box.\n *\n * ## Features / Variants\n * - **Size:** `xs`, `s`, `m` (default), `l`, `xl` – each maps to a fixed box\n * height (16 / 20 / 24 / 32 / 40 px) with 4px padding above and below, giving\n * cap heights of 8 / 12 / 16 / 24 / 32 px so text aligns to a predictable\n * grid.\n * - **Font weight:** `regular` (default), `semibold`, `bold`.\n * - **Tabular numbers:** `tabularNums` (default off) renders digits as\n * fixed-width, lining numerals (`tabular-nums lining-nums` + the `ss04`/`tnum`/\n * `lnum` features) so numeric values stay column-aligned and stable in width\n * as they update – use it for readouts and other live numeric displays.\n * - **Alignment:** `left`, `center`, `right` (default) – positions the text\n * within the box's width when the box is wider than the content.\n * - **Reserved width:** content placed in the `length` slot reserves a minimum\n * width invisibly, so the box does not resize as the visible text changes.\n * The box always shows all content – it never crops.\n *\n * ## Usage Guidelines\n * - Pass the longest expected string to the `length` slot (e.g. `\"888.8\"` or\n * `\"Wind speed\"`) so the box reserves space and does not jump in width as the\n * visible value updates.\n * - This is a display primitive for static text – use an input component for\n * editable values.\n *\n * ## Slots\n * | Slot | Renders when… | Purpose |\n * |-----------|--------------------|------------------------------------------------------|\n * | (default) | Always | The visible text content. |\n * | `length` | Always (invisible) | Reserves a minimum width based on its content width. |\n *\n * @slot - The visible text content.\n * @slot length - Reserves a minimum width based on its content width.\n * @experimental\n */\n@customElement('obc-textbox')\nexport class ObcTextbox extends LitElement {\n @property({type: String}) alignment: ObcTextboxAlignment =\n ObcTextboxAlignment.Right;\n @property({type: String}) size: ObcTextboxSize = ObcTextboxSize.m;\n @property({type: String}) fontWeight: ObcTextboxFontWeight =\n ObcTextboxFontWeight.regular;\n @property({type: Boolean}) tabularNums = false;\n\n override render() {\n return html`\n <div\n class=${classMap({\n wrapper: true,\n [`alignment-${this.alignment}`]: true,\n [`size-${this.size}`]: true,\n [`font-weight-${this.fontWeight}`]: true,\n 'tabular-nums': this.tabularNums,\n })}\n >\n <div class=\"inner-wrapper\">\n <div class=\"content\">\n <slot></slot>\n </div>\n </div>\n <div class=\"length-spacer\" aria-hidden=\"true\">\n <slot name=\"length\"></slot>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-textbox': ObcTextbox;\n }\n}\n"],"names":["ObcTextboxAlignment","ObcTextboxSize","ObcTextboxFontWeight"],"mappings":";;;;;;;;;;;;;;;AAMO,IAAK,wCAAAA,yBAAL;AACLA,uBAAA,MAAA,IAAO;AACPA,uBAAA,QAAA,IAAS;AACTA,uBAAA,OAAA,IAAQ;AAHE,SAAAA;AAAA,GAAA,uBAAA,CAAA,CAAA;AAML,IAAK,mCAAAC,oBAAL;AACLA,kBAAA,IAAA,IAAK;AACLA,kBAAA,GAAA,IAAI;AACJA,kBAAA,GAAA,IAAI;AACJA,kBAAA,GAAA,IAAI;AACJA,kBAAA,IAAA,IAAK;AALK,SAAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAQL,IAAK,yCAAAC,0BAAL;AACLA,wBAAA,SAAA,IAAU;AACVA,wBAAA,UAAA,IAAW;AACXA,wBAAA,MAAA,IAAO;AAHG,SAAAA;AAAA,GAAA,wBAAA,CAAA,CAAA;AAmDL,IAAM,aAAN,cAAyB,WAAW;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,YACxB;AACwB,SAAA,OAAuB;AACvB,SAAA,aACxB;AACyB,SAAA,cAAc;AAAA,EAAA;AAAA,EAEhC,SAAS;AAChB,WAAO;AAAA;AAAA,gBAEK,SAAS;AAAA,MACf,SAAS;AAAA,MACT,CAAC,aAAa,KAAK,SAAS,EAAE,GAAG;AAAA,MACjC,CAAC,QAAQ,KAAK,IAAI,EAAE,GAAG;AAAA,MACvB,CAAC,eAAe,KAAK,UAAU,EAAE,GAAG;AAAA,MACpC,gBAAgB,KAAK;AAAA,IAAA,CACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYR;AAGF;AAhCa,WA+BK,SAAS,UAAU,cAAc;AA9BvB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,WACe,WAAA,aAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,WAGe,WAAA,QAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,WAIe,WAAA,cAAA,CAAA;AAEC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GANd,WAMgB,WAAA,eAAA,CAAA;AANhB,aAAN,gBAAA;AAAA,EADN,cAAc,aAAa;AAAA,GACf,UAAA;"}
1
+ {"version":3,"file":"textbox.js","sources":["../../../src/components/textbox/textbox.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './textbox.css?inline';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nexport enum ObcTextboxAlignment {\n Left = 'left',\n Center = 'center',\n Right = 'right',\n}\n\nexport enum ObcTextboxSize {\n xs = 'xs',\n s = 's',\n m = 'm',\n l = 'l',\n xl = 'xl',\n}\n\nexport enum ObcTextboxFontWeight {\n regular = 'regular',\n semibold = 'semibold',\n bold = 'bold',\n}\n\n/**\n * `<obc-textbox>` – A text container that renders inline text at a\n * precise, cap-height-trimmed size with configurable alignment and reservable\n * width.\n *\n * Use it to present short, read-only strings – such as values, labels, or\n * units – where vertical metrics must line up exactly across rows and the\n * horizontal footprint should stay stable while the text changes (for example\n * a numeric value that updates frequently). Synonyms: text container, value\n * box, label box.\n *\n * ## Features / Variants\n * - **Size:** `xs`, `s`, `m` (default), `l`, `xl` – each maps to a fixed box\n * height (16 / 20 / 24 / 32 / 40 px) with 4px padding above and below, giving\n * cap heights of 8 / 12 / 16 / 24 / 32 px so text aligns to a predictable\n * grid.\n * - **Font weight:** `regular` (default), `semibold`, `bold`.\n * - **Tabular numbers:** `tabularNums` (default off) renders digits as\n * fixed-width, lining numerals (`tabular-nums lining-nums` + the `ss04`/`tnum`/\n * `lnum` features) so numeric values stay column-aligned and stable in width\n * as they update – use it for readouts and other live numeric displays.\n * - **Alignment:** `left`, `center`, `right` (default) – positions the text\n * within the box's width when the box is wider than the content.\n * - **Reserved width:** content placed in the `length` slot reserves a minimum\n * width invisibly, so the box does not resize as the visible text changes.\n * The box always shows all content – it never crops.\n *\n * ## Usage Guidelines\n * - Pass the longest expected string to the `length` slot (e.g. `\"888.8\"` or\n * `\"Wind speed\"`) so the box reserves space and does not jump in width as the\n * visible value updates.\n * - This is a display primitive for static text – use an input component for\n * editable values.\n *\n * ## Slots\n * | Slot | Renders when… | Purpose |\n * |-----------|--------------------|------------------------------------------------------|\n * | (default) | Always | The visible text content. |\n * | `length` | Always (invisible) | Reserves a minimum width based on its content width. |\n *\n * @slot - The visible text content.\n * @slot length - Reserves a minimum width based on its content width.\n * @beta\n */\n@customElement('obc-textbox')\nexport class ObcTextbox extends LitElement {\n @property({type: String}) alignment: ObcTextboxAlignment =\n ObcTextboxAlignment.Right;\n @property({type: String}) size: ObcTextboxSize = ObcTextboxSize.m;\n @property({type: String}) fontWeight: ObcTextboxFontWeight =\n ObcTextboxFontWeight.regular;\n @property({type: Boolean}) tabularNums = false;\n\n override render() {\n return html`\n <div\n class=${classMap({\n wrapper: true,\n [`alignment-${this.alignment}`]: true,\n [`size-${this.size}`]: true,\n [`font-weight-${this.fontWeight}`]: true,\n 'tabular-nums': this.tabularNums,\n })}\n >\n <div class=\"inner-wrapper\">\n <div class=\"content\">\n <slot></slot>\n </div>\n </div>\n <div class=\"length-spacer\" aria-hidden=\"true\">\n <slot name=\"length\"></slot>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-textbox': ObcTextbox;\n }\n}\n"],"names":["ObcTextboxAlignment","ObcTextboxSize","ObcTextboxFontWeight"],"mappings":";;;;;;;;;;;;;;;AAMO,IAAK,wCAAAA,yBAAL;AACLA,uBAAA,MAAA,IAAO;AACPA,uBAAA,QAAA,IAAS;AACTA,uBAAA,OAAA,IAAQ;AAHE,SAAAA;AAAA,GAAA,uBAAA,CAAA,CAAA;AAML,IAAK,mCAAAC,oBAAL;AACLA,kBAAA,IAAA,IAAK;AACLA,kBAAA,GAAA,IAAI;AACJA,kBAAA,GAAA,IAAI;AACJA,kBAAA,GAAA,IAAI;AACJA,kBAAA,IAAA,IAAK;AALK,SAAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAQL,IAAK,yCAAAC,0BAAL;AACLA,wBAAA,SAAA,IAAU;AACVA,wBAAA,UAAA,IAAW;AACXA,wBAAA,MAAA,IAAO;AAHG,SAAAA;AAAA,GAAA,wBAAA,CAAA,CAAA;AAmDL,IAAM,aAAN,cAAyB,WAAW;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,YACxB;AACwB,SAAA,OAAuB;AACvB,SAAA,aACxB;AACyB,SAAA,cAAc;AAAA,EAAA;AAAA,EAEhC,SAAS;AAChB,WAAO;AAAA;AAAA,gBAEK,SAAS;AAAA,MACf,SAAS;AAAA,MACT,CAAC,aAAa,KAAK,SAAS,EAAE,GAAG;AAAA,MACjC,CAAC,QAAQ,KAAK,IAAI,EAAE,GAAG;AAAA,MACvB,CAAC,eAAe,KAAK,UAAU,EAAE,GAAG;AAAA,MACpC,gBAAgB,KAAK;AAAA,IAAA,CACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYR;AAGF;AAhCa,WA+BK,SAAS,UAAU,cAAc;AA9BvB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,WACe,WAAA,aAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,WAGe,WAAA,QAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,WAIe,WAAA,cAAA,CAAA;AAEC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GANd,WAMgB,WAAA,eAAA,CAAA;AANhB,aAAN,gBAAA;AAAA,EADN,cAAc,aAAa;AAAA,GACf,UAAA;"}
@@ -27,27 +27,28 @@ const compentStyle = css`* {
27
27
  height: var(--app-components-topbar-touch-target-tall);
28
28
  }
29
29
 
30
+ .wrapper.inactive {
31
+ padding-left: calc(
32
+ var(--app-components-topbar-margin-global) +
33
+ var(--app-components-topbar-padding-left-small)
34
+ ); /* no menu button: inset the title instead */
35
+ }
36
+
37
+ /* ---- One flex line ----
38
+ Flattened because a squeeze must reach the texts, not a group: a shrinkable
39
+ left group collapses under an unshrinkable alert and covers the menu button. */
40
+
30
41
  .group {
31
- display: flex;
32
- align-items: center;
42
+ display: contents;
33
43
  }
34
44
 
35
- .group.right {
36
- justify-content: flex-end;
37
- flex-grow: 1;
38
- }
39
-
40
45
  .settings .group.left > * {
41
46
  margin-right: 0;
42
47
  margin-left: 0;
43
48
  }
44
49
 
45
50
  .group.left .title {
46
- padding-right: var(--app-components-topbar-label-spacing);
47
- }
48
-
49
- .inactive .group.left {
50
- padding-left: var(--app-components-topbar-padding-left-small);
51
+ padding-right: var(--app-components-topbar-label-spacing);
51
52
  }
52
53
 
53
54
  .group.left .menu-button {
@@ -68,16 +69,40 @@ const compentStyle = css`* {
68
69
  color: var(--element-neutral-color);
69
70
  }
70
71
 
72
+ /* Controls never shrink: a squeeze reaches the texts, then overflows the end */
73
+
74
+ .menu-button,
75
+ .app-icon,
76
+ .left-more-button,
77
+ .dimming-button,
78
+ .user-button,
79
+ .apps-button,
80
+ ::slotted([slot="command-button"]),
81
+ ::slotted([slot="clock"]) {
82
+ flex-shrink: 0;
83
+ }
84
+
71
85
  .alert-container {
72
86
  display: flex;
73
- flex-grow: 1;
87
+ flex: 1 1 0; /* zero basis: fills what the texts leave, holds its min-content in a squeeze */
74
88
  gap: var(--app-components-topbar-label-spacing);
75
89
  align-items: center;
76
90
  justify-content: right;
77
91
  }
78
92
 
79
- .title {
93
+ /* ---- Text gives way first ---- */
94
+
95
+ .title,
96
+ .page-name {
97
+ overflow: hidden;
80
98
  color: var(--element-active-color, #1a1a1a);
99
+ }
100
+
101
+ .title {
102
+ flex-shrink: 3; /* the app title gives way before the page name */
103
+ min-width: 2em; /* room for "A…": narrower boxes paint a clipped glyph instead */
104
+ white-space: nowrap;
105
+ text-overflow: ellipsis;
81
106
  font-family: var(--global-typography-font-family);
82
107
  font-weight: var(--global-typography-ui-body-font-weight);
83
108
  font-size: var(--global-typography-ui-body-font-size);
@@ -89,7 +114,11 @@ const compentStyle = css`* {
89
114
  }
90
115
 
91
116
  .page-name {
92
- color: var(--element-active-color, #1a1a1a);
117
+ min-width: 0; /* shrink below the longest word instead of pushing buttons out */
118
+ display: -webkit-box; /* two lines, then an ellipsis */
119
+ -webkit-box-orient: vertical;
120
+ -webkit-line-clamp: 2;
121
+ line-clamp: 2;
93
122
  font-family: var(--global-typography-font-family);
94
123
  font-weight: var(--global-typography-ui-body-active-font-weight);
95
124
  font-size: var(--global-typography-ui-body-active-font-size);
@@ -1 +1 @@
1
- {"version":3,"file":"top-bar.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"top-bar.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -202,7 +202,7 @@ let ObcTopBar = class extends LitElement {
202
202
 
203
203
  @media (max-width: ${this.appTitleBreakpointPx}px) {
204
204
  .title {
205
- display: none;
205
+ display: none !important; /* the stylesheet's display wins over this inline rule otherwise */
206
206
  }
207
207
  }
208
208
 
@@ -1 +1 @@
1
- {"version":3,"file":"top-bar.js","sources":["../../../src/components/top-bar/top-bar.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport compentStyle from './top-bar.css?inline';\nimport '../icon-button/icon-button.js';\nimport '../clock/clock.js';\nimport '../divider/divider.js';\nimport '../breadcrumb/breadcrumb.js';\nimport '../../icons/icon-menu-iec.js';\nimport '../../icons/icon-home.js';\nimport '../../icons/icon-close-google.js';\nimport '../../icons/icon-arrow-left-google.js';\nimport '../../icons/icon-arrow-right-google.js';\nimport '../../icons/icon-palette-day-night-iec.js';\nimport '../../icons/icon-applications.js';\nimport '../../icons/icon-more-vertical-google.js';\nimport '../../icons/icon-user.js';\nimport {\n BreadcrumbClickEvent,\n BreadcrumbItem,\n} from '../breadcrumb/breadcrumb.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum ObcTopBarMenuButtonIcon {\n Menu = 'menu',\n Home = 'home',\n}\n\n/**\n * `<obc-top-bar>` – A responsive top navigation bar component for application layouts.\n *\n * Provides a flexible, highly configurable top bar for application interfaces, supporting navigation, context display, quick actions, and status indicators. The top bar adapts to screen size and can show or hide elements such as menu, app icon, breadcrumbs, user/profile, clock, and alert notifications.\n *\n * Appears at the top of the UI, organizing primary navigation and contextual actions in a single, persistent region. Designed for use as the main app bar or header in multi-pane or dashboard-style layouts.\n *\n * ## Features\n * - **Configurable Sections:** Supports left and right-aligned groups for navigation, context, and actions.\n * - **Menu Button:** Optional menu button for opening navigation drawers or sidebars; can be styled as wide or regular.\n * - **App Icon Slot:** Customizable slot for displaying an application or brand icon.\n * - **App Title & Page Name:** Displays the current application and page context.\n * - **Breadcrumbs:** Optional breadcrumb navigation for hierarchical context (in settings mode).\n * - **Command Button Slot:** Slot for inserting a primary command/action button.\n * - **Alert/Notification Area:** Slot for alert indicators, notification badges, or custom alert components.\n * - **Dimming Button:** Optional button for toggling display modes (e.g., day/night).\n * - **User/Profile Button:** Optional user icon for profile/account actions.\n * - **Apps Button:** Optional button for accessing additional applications or modules.\n * - **Clock & Date:** Optional digital clock and date display, responsive to screen size.\n * - **Responsive Layout:** Multiple breakpoint properties to control visibility and layout of elements based on viewport width.\n * - **Settings Mode:** Special mode with close, back, and forward navigation, breadcrumbs, and app title.\n * - **Tall Variant:** Optional increased height for touch or accessibility needs.\n * - **Inactive State:** Disables interactive elements and visually de-emphasizes the bar.\n *\n * ## Variants\n * - **Regular:** Standard top bar with menu, app icon, title, page name, and action slots.\n * - **Settings:** Shows close, back, forward buttons, breadcrumbs, and app title for configuration or settings screens.\n * - **Inactive:** Visually muted and disables interaction (e.g., when the app is locked or in a modal state).\n * - **Tall:** Increases the height of the bar for improved touch targets.\n *\n * ## Usage Guidelines\n * Use `<obc-top-bar>` as the persistent header for your application, providing navigation, context, and quick access to key actions or status. Configure which elements appear via boolean properties and slots. Adjust breakpoint properties to control responsive behavior for each section.\n *\n * - Place navigation, branding, and context (title, breadcrumbs) on the left; actions, alerts, and status (clock, user, apps) on the right.\n * - Use the `settings` property for configuration or setup screens to enable close/back/forward navigation and breadcrumbs.\n * - Use the `inactive` property to visually disable the bar and its actions when the app is not interactive.\n * - Insert custom icons or buttons using the `app-icon` and `command-button` slots.\n * - Use the `alerts` slot to display alert indicators, notification badges, or custom alert components.\n *\n * **TODO(designer):** Clarify recommended combinations of visible elements for different app contexts (e.g., when to show both user and apps buttons, or best practices for alert placement).\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |------------------|---------------------------------|----------------------------------------------------------------|\n * | `app-icon` | `showAppIcon` is true | Custom icon representing the application or brand. |\n * | `command-button` | Always (if provided) | Primary command or action button for the current context. |\n * | `alerts` | Always (if provided) | Area for alert indicators, notification badges, or alert items.|\n * | `clock` | Always (if provided) | Clock component for displaying the current time. |\n *\n * ## Properties and Attributes\n * - `appTitle` (string): Sets the main application title (default: \"App\").\n * - `pageName` (string): Sets the current page or section name (default: \"Page\").\n * - `menuButtonActivated` (boolean): Highlights the menu button as active.\n * - `dimmingButtonActivated` (boolean): Highlights the dimming button as active.\n * - `appsButtonActivated` (boolean): Highlights the apps button as active.\n * - `leftMoreButtonActivated` (boolean): Highlights the left more button as active.\n * - `userButtonActivated` (boolean): Highlights the user button as active.\n * - `tall` (boolean): Increases the bar height for larger touch targets.\n * - `wideMenuButton` (boolean): Expands the menu button for wide-rail layouts.\n * - `showAppsButton` (boolean): Shows/hides the apps button.\n * - `showDimmingButton` (boolean): Shows/hides the dimming (day/night) button.\n * - `showUserButton` (boolean): Shows/hides the user/profile button.\n * - `showClock` (boolean): Shows/hides the clock.\n * - `showDate` (boolean): Shows/hides the date in the clock.\n * - `showAppIcon` (boolean): Shows/hides the app icon slot.\n * - `inactive` (boolean): Disables interaction and visually de-emphasizes the bar.\n * - `settings` (boolean): Enables settings mode (shows close, back, forward, breadcrumbs).\n * - `breadcrumbItems` (BreadcrumbItem[]): Array of breadcrumb items for navigation.\n * - Breakpoint properties (`appButtonBreakpointPx`, `dimmingButtonBreakpointPx`, `appTitleBreakpointPx`, `userButtonBreakpointPx`, `appIconBreakpointPx`): Control responsive visibility of each section.\n *\n * ## Events\n * - `menu-button-clicked` – Fired when the menu button is clicked.\n * - `dimming-button-clicked` – Fired when the dimming (day/night) button is clicked.\n * - `apps-button-clicked` – Fired when the apps button is clicked.\n * - `left-more-button-clicked` – Fired when the left more button is clicked.\n * - `user-button-clicked` – Fired when the user/profile button is clicked.\n * - `close` – Fired in settings mode when the close button is clicked.\n * - `back` – Fired in settings mode when the back button is clicked.\n * - `forward` – Fired in settings mode when the forward button is clicked.\n * - `emergency-brightness-start` – Fired when the menu button is held for 500ms. This should increase the brightness of the screen slowly. Used when the screen is too dark.\n * - `emergency-brightness-stop` – Fired when the menu button is released.\n *\n * ## Best Practices and Constraints\n * - Only show interactive elements relevant to the current context to avoid clutter.\n * - Use the `alerts` slot for transient or critical notifications; persistent alerts may require a different component.\n * - For accessibility, ensure that all interactive elements have appropriate labels and focus handling.\n * - Adjust breakpoint properties to optimize the layout for different device sizes.\n * - In settings mode, use breadcrumbs to provide clear navigation context.\n *\n * ## Example\n *\n * ```html\n * <obc-top-bar\n * appTitle=\"My App\"\n * pageName=\"Dashboard\"\n * showAppsButton\n * showDimmingButton\n * showClock\n * showUserButton\n * showAppIcon\n * >\n * <obi-placeholder slot=\"app-icon\"></obi-placeholder>\n * <obc-command-button slot=\"command-button\"></obc-command-button>\n * <obc-topbar-message-item slot=\"alerts\"></obc-topbar-message-item>\n * <obc-clock slot=\"clock\"></obc-clock>\n * </obc-top-bar>\n * ```\n *\n * @availableWhen menuButtonIcon settings==false && inactive==false\n * @slot app-icon - Custom icon representing the application or brand (shown when `showAppIcon` is true)\n * @slot command-button - Primary command/action button for the current context\n * @slot alerts - Area for alert indicators, notification badges, or alert items\n * @slot clock - Clock component for displaying the current time (shown when `showClock` is true)\n * @fires menu-button-clicked - Fired when the menu button is clicked\n * @fires dimming-button-clicked - Fired when the dimming (day/night) button is clicked\n * @fires apps-button-clicked - Fired when the apps button is clicked\n * @fires left-more-button-clicked - Fired when the left more button is clicked\n * @fires user-button-clicked - Fired when the user/profile button is clicked\n * @fires close - Fired in settings mode when the close button is clicked\n * @fires back - Fired in settings mode when the back button is clicked\n * @fires emergency-brightness-start - Fired when the menu button is held for 500ms. This should increase the brightness of the screen slowly. Used when the screen is too dark.\n * @fires emergency-brightness-stop - Fired when the menu button is released.\n * @fires {BreadcrumbClickEvent} breadcrumb-click - Fired when a breadcrumb item is clicked.\n * @stable\n */\n@customElement('obc-top-bar')\nexport class ObcTopBar extends LitElement {\n /**\n * Sets the main application title displayed in the top bar.\n * @type {string}\n * @default \"App\"\n */\n @property({type: String}) appTitle = 'App';\n\n /**\n * Sets the current page or section name displayed in the top bar.\n * @type {string}\n * @default \"Page\"\n * @availableWhen settings==false\n */\n @property({type: String}) pageName = 'Page';\n\n @property({type: String}) menuButtonIcon = ObcTopBarMenuButtonIcon.Menu;\n\n /**\n * Highlights the menu button as active.\n * @type {boolean}\n * @default false\n * @availableWhen settings==false && inactive==false\n */\n @property({type: Boolean})\n menuButtonActivated = false;\n\n /**\n * Highlights the dimming (day/night) button as active.\n * @type {boolean}\n * @default false\n * @availableWhen showDimmingButton==true && inactive==false\n */\n @property({type: Boolean})\n dimmingButtonActivated = false;\n\n /**\n * Highlights the apps button as active.\n * @type {boolean}\n * @default false\n * @availableWhen showAppsButton==true && inactive==false\n */\n @property({type: Boolean})\n appsButtonActivated = false;\n\n /**\n * Highlights the left more button as active.\n * @type {boolean}\n * @default false\n * @availableWhen inactive==false\n */\n @property({type: Boolean})\n leftMoreButtonActivated = false;\n\n /**\n * Highlights the user/profile button as active.\n * @type {boolean}\n * @default false\n * @availableWhen showUserButton==true && inactive==false\n */\n @property({type: Boolean})\n userButtonActivated = false;\n\n /**\n * Disables the user/profile button.\n * @type {boolean}\n * @default false\n * @availableWhen showUserButton==true && inactive==false\n */\n @property({type: Boolean})\n userButtonDisabled = false;\n\n /**\n * Increases the height of the top bar for larger touch targets.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) tall = false;\n\n /**\n * Expands the menu button for wide-rail layouts.\n * @type {boolean}\n * @default false\n * @availableWhen settings==false && inactive==false\n */\n @property({type: Boolean}) wideMenuButton = false;\n\n /**\n * Shows or hides the apps button.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showAppsButton = false;\n\n /**\n * Shows or hides the dimming (day/night) button.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean})\n showDimmingButton = false;\n\n /**\n * Shows or hides the user/profile button.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showUserButton = false;\n\n /**\n * Shows or hides the clock.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showClock = false;\n\n /**\n * Shows or hides the date in the clock display.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showDate = false;\n\n /**\n * Shows or hides the app icon slot.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showAppIcon = false;\n\n /**\n * Disables interaction and visually de-emphasizes the bar.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) inactive = false;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the apps button.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n appButtonBreakpointPx = 500;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the dimming button.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n dimmingButtonBreakpointPx = 500;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the app title.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n appTitleBreakpointPx = 500;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the user button.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n userButtonBreakpointPx = 500;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the app icon.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n appIconBreakpointPx = 500;\n\n /**\n * Enables settings mode, displaying close, back buttons, breadcrumbs, and app title.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) settings = false;\n\n /**\n * Array of breadcrumb items for navigation (used in settings mode).\n * @type {BreadcrumbItem[]}\n * @default []\n * @availableWhen settings==true\n */\n @property({type: Array})\n breadcrumbItems: BreadcrumbItem[] = [];\n\n private dimmingButtonClicked() {\n /**\n * Fired when the dimming (day/night) button is clicked.\n * @event dimming-button-clicked\n */\n this.dispatchEvent(new CustomEvent('dimming-button-clicked'));\n }\n\n private appsButtonClicked() {\n /**\n * Fired when the apps button is clicked.\n * @event apps-button-clicked\n */\n this.dispatchEvent(new CustomEvent('apps-button-clicked'));\n }\n\n private leftMoreButtonClicked() {\n /**\n * Fired when the left more button is clicked.\n * @event left-more-button-clicked\n */\n this.dispatchEvent(new CustomEvent('left-more-button-clicked'));\n }\n\n private userButtonClicked() {\n /**\n * Fired when the user/profile button is clicked.\n * @event user-button-clicked\n */\n this.dispatchEvent(new CustomEvent('user-button-clicked'));\n }\n\n private leftButtonEvent: null | CustomEvent = null;\n private leftButtonTimeout: null | NodeJS.Timeout = null;\n private isLeftButtonDown = false;\n private isEmergencyBrightness = false;\n\n private leftButtonDown(event: CustomEvent) {\n this.leftButtonEvent = event;\n this.isLeftButtonDown = true;\n this.leftButtonTimeout = setTimeout(() => {\n this.leftButtonEvent = null;\n this.dispatchEvent(new CustomEvent('emergency-brightness-start'));\n this.isEmergencyBrightness = true;\n }, 500);\n }\n\n private leftButtonUp() {\n if (this.leftButtonEvent) {\n this.dispatchEvent(this.leftButtonEvent);\n this.leftButtonEvent = null;\n }\n if (this.leftButtonTimeout) {\n clearTimeout(this.leftButtonTimeout);\n this.leftButtonTimeout = null;\n }\n if (this.isEmergencyBrightness) {\n this.dispatchEvent(new CustomEvent('emergency-brightness-stop'));\n this.isEmergencyBrightness = false;\n }\n this.isLeftButtonDown = false;\n }\n\n private leftButtonLeave() {\n if (!this.isLeftButtonDown) return;\n if (this.leftButtonTimeout) {\n clearInterval(this.leftButtonTimeout);\n this.leftButtonTimeout = null;\n }\n if (this.isEmergencyBrightness) {\n this.dispatchEvent(new CustomEvent('emergency-brightness-stop'));\n this.isEmergencyBrightness = false;\n }\n this.isLeftButtonDown = false;\n }\n\n override render() {\n const leftGroup = [];\n if (this.settings) {\n leftGroup.push(\n html`<div class=\"menu-button\">\n <obc-icon-button\n variant=\"flat\"\n @pointerdown=${() => this.leftButtonDown(new CustomEvent('close'))}\n @pointerup=${() => this.leftButtonUp()}\n @pointerleave=${() => this.leftButtonLeave()}\n >\n <obi-close-google></obi-close-google>\n </obc-icon-button>\n </div>`\n );\n leftGroup.push(\n html`<obc-icon-button\n variant=\"flat\"\n @click=${() => this.dispatchEvent(new CustomEvent('back'))}\n >\n <obi-arrow-left-google></obi-arrow-left-google>\n </obc-icon-button>`\n );\n leftGroup.push(html`<div class=\"title\">${this.appTitle}</div>`);\n leftGroup.push(\n html`<obc-breadcrumb\n .items=${this.breadcrumbItems}\n @breadcrumb-click=${(e: BreadcrumbClickEvent) =>\n this.dispatchEvent(\n new CustomEvent('breadcrumb-click', {\n detail: e.detail,\n }) as BreadcrumbClickEvent\n )}\n ></obc-breadcrumb>`\n );\n } else {\n if (!this.inactive) {\n leftGroup.push(\n html`<div class=\"menu-button ${this.wideMenuButton ? 'wide' : null}\">\n <obc-icon-button\n variant=\"flat\"\n @pointerdown=${() =>\n this.leftButtonDown(new CustomEvent('menu-button-clicked'))}\n @pointerup=${() => this.leftButtonUp()}\n @pointerleave=${() => this.leftButtonLeave()}\n ?activated=${this.menuButtonActivated}\n >\n ${this.menuButtonIcon === ObcTopBarMenuButtonIcon.Menu\n ? html`<obi-menu-iec></obi-menu-iec>`\n : html`<obi-home></obi-home>`}\n </obc-icon-button>\n </div>`\n );\n }\n if (this.showAppIcon) {\n leftGroup.push(\n html`<div class=\"app-icon\"><slot name=\"app-icon\"></slot></div>`\n );\n }\n leftGroup.push(html`<div class=\"title\">${this.appTitle}</div>`);\n leftGroup.push(html`<div class=\"page-name\">${this.pageName}</div>`);\n leftGroup.push(html`<slot name=\"command-button\"></slot>`);\n }\n\n const breakpointMoreButton = Math.max(\n this.appButtonBreakpointPx,\n this.dimmingButtonBreakpointPx\n );\n\n return html`\n <style>\n @media (max-width: ${breakpointMoreButton}px) {\n .left-more-button {\n display: revert !important;\n }\n\n .group.left > * {\n margin-right: 4px;\n margin-left: 4px;\n }\n }\n\n @media (max-width: ${this.appButtonBreakpointPx}px) {\n .apps-button {\n display: none;\n }\n }\n\n @media (max-width: ${this.dimmingButtonBreakpointPx}px) {\n .dimming-button {\n display: none;\n }\n }\n\n @media (max-width: ${this.appTitleBreakpointPx}px) {\n .title {\n display: none;\n }\n }\n\n @media (max-width: ${this.userButtonBreakpointPx}px) {\n .user-button {\n display: none;\n }\n }\n\n @media (max-width: ${this.appIconBreakpointPx}px) {\n .app-icon {\n display: none;\n }\n }\n </style>\n <nav\n class=${classMap({\n wrapper: true,\n inactive: this.inactive,\n settings: this.settings,\n tall: this.tall,\n })}\n role=\"menubar\"\n >\n <div class=\"left group\">${leftGroup}</div>\n <div class=\"right group\">\n <div class=\"alert-container\">\n <slot name=\"alerts\"></slot>\n </div>\n ${this.showDimmingButton && !this.inactive\n ? html`<obc-icon-button\n class=\"dimming-button\"\n part=\"dimming-button\"\n variant=\"flat\"\n @click=${this.dimmingButtonClicked}\n ?activated=${this.dimmingButtonActivated}\n >\n <obi-palette-day-night-iec></obi-palette-day-night-iec>\n </obc-icon-button>`\n : null}\n ${this.showUserButton && !this.inactive\n ? html`<obc-icon-button\n class=\"user-button\"\n variant=\"flat\"\n part=\"user-button\"\n @click=${this.userButtonClicked}\n ?activated=${this.userButtonActivated}\n ?disabled=${this.userButtonDisabled}\n >\n <obi-user></obi-user>\n </obc-icon-button>`\n : null}\n ${this.showAppsButton && !this.inactive\n ? html`<obc-icon-button\n class=\"apps-button\"\n variant=\"flat\"\n part=\"apps-button\"\n @click=${this.appsButtonClicked}\n ?activated=${this.appsButtonActivated}\n >\n <obi-applications></obi-applications>\n </obc-icon-button>`\n : null}\n ${this.showClock ? html`<slot name=\"clock\"></slot>` : null}\n ${!this.inactive\n ? html`<obc-icon-button\n class=\"left-more-button\"\n part=\"left-more-button\"\n variant=\"flat\"\n @click=${this.leftMoreButtonClicked}\n ?activated=${this.leftMoreButtonActivated}\n >\n <obi-more-vertical-google></obi-more-vertical-google>\n </obc-icon-button>`\n : null}\n </div>\n </nav>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-top-bar': ObcTopBar;\n }\n}\n"],"names":["ObcTopBarMenuButtonIcon"],"mappings":"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"}
1
+ {"version":3,"file":"top-bar.js","sources":["../../../src/components/top-bar/top-bar.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport compentStyle from './top-bar.css?inline';\nimport '../icon-button/icon-button.js';\nimport '../clock/clock.js';\nimport '../divider/divider.js';\nimport '../breadcrumb/breadcrumb.js';\nimport '../../icons/icon-menu-iec.js';\nimport '../../icons/icon-home.js';\nimport '../../icons/icon-close-google.js';\nimport '../../icons/icon-arrow-left-google.js';\nimport '../../icons/icon-arrow-right-google.js';\nimport '../../icons/icon-palette-day-night-iec.js';\nimport '../../icons/icon-applications.js';\nimport '../../icons/icon-more-vertical-google.js';\nimport '../../icons/icon-user.js';\nimport {\n BreadcrumbClickEvent,\n BreadcrumbItem,\n} from '../breadcrumb/breadcrumb.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum ObcTopBarMenuButtonIcon {\n Menu = 'menu',\n Home = 'home',\n}\n\n/**\n * `<obc-top-bar>` – A responsive top navigation bar component for application layouts.\n *\n * Provides a flexible, highly configurable top bar for application interfaces, supporting navigation, context display, quick actions, and status indicators. The top bar adapts to screen size and can show or hide elements such as menu, app icon, breadcrumbs, user/profile, clock, and alert notifications.\n *\n * Appears at the top of the UI, organizing primary navigation and contextual actions in a single, persistent region. Designed for use as the main app bar or header in multi-pane or dashboard-style layouts.\n *\n * ## Features\n * - **Configurable Sections:** Supports left and right-aligned groups for navigation, context, and actions.\n * - **Menu Button:** Optional menu button for opening navigation drawers or sidebars; can be styled as wide or regular.\n * - **App Icon Slot:** Customizable slot for displaying an application or brand icon.\n * - **App Title & Page Name:** Displays the current application and page context.\n * - **Breadcrumbs:** Optional breadcrumb navigation for hierarchical context (in settings mode).\n * - **Command Button Slot:** Slot for inserting a primary command/action button.\n * - **Alert/Notification Area:** Slot for alert indicators, notification badges, or custom alert components.\n * - **Dimming Button:** Optional button for toggling display modes (e.g., day/night).\n * - **User/Profile Button:** Optional user icon for profile/account actions.\n * - **Apps Button:** Optional button for accessing additional applications or modules.\n * - **Clock & Date:** Optional digital clock and date display, responsive to screen size.\n * - **Responsive Layout:** Multiple breakpoint properties to control visibility and layout of elements based on viewport width.\n * - **Settings Mode:** Special mode with close, back, and forward navigation, breadcrumbs, and app title.\n * - **Tall Variant:** Optional increased height for touch or accessibility needs.\n * - **Inactive State:** Disables interactive elements and visually de-emphasizes the bar.\n *\n * ## Variants\n * - **Regular:** Standard top bar with menu, app icon, title, page name, and action slots.\n * - **Settings:** Shows close, back, forward buttons, breadcrumbs, and app title for configuration or settings screens.\n * - **Inactive:** Visually muted and disables interaction (e.g., when the app is locked or in a modal state).\n * - **Tall:** Increases the height of the bar for improved touch targets.\n *\n * ## Usage Guidelines\n * Use `<obc-top-bar>` as the persistent header for your application, providing navigation, context, and quick access to key actions or status. Configure which elements appear via boolean properties and slots. Adjust breakpoint properties to control responsive behavior for each section.\n *\n * - Place navigation, branding, and context (title, breadcrumbs) on the left; actions, alerts, and status (clock, user, apps) on the right.\n * - Use the `settings` property for configuration or setup screens to enable close/back/forward navigation and breadcrumbs.\n * - Use the `inactive` property to visually disable the bar and its actions when the app is not interactive.\n * - Insert custom icons or buttons using the `app-icon` and `command-button` slots.\n * - Use the `alerts` slot to display alert indicators, notification badges, or custom alert components.\n *\n * **TODO(designer):** Clarify recommended combinations of visible elements for different app contexts (e.g., when to show both user and apps buttons, or best practices for alert placement).\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |------------------|---------------------------------|----------------------------------------------------------------|\n * | `app-icon` | `showAppIcon` is true | Custom icon representing the application or brand. |\n * | `command-button` | Always (if provided) | Primary command or action button for the current context. |\n * | `alerts` | Always (if provided) | Area for alert indicators, notification badges, or alert items.|\n * | `clock` | Always (if provided) | Clock component for displaying the current time. |\n *\n * ## Properties and Attributes\n * - `appTitle` (string): Sets the main application title (default: \"App\").\n * - `pageName` (string): Sets the current page or section name (default: \"Page\").\n * - `menuButtonActivated` (boolean): Highlights the menu button as active.\n * - `dimmingButtonActivated` (boolean): Highlights the dimming button as active.\n * - `appsButtonActivated` (boolean): Highlights the apps button as active.\n * - `leftMoreButtonActivated` (boolean): Highlights the left more button as active.\n * - `userButtonActivated` (boolean): Highlights the user button as active.\n * - `tall` (boolean): Increases the bar height for larger touch targets.\n * - `wideMenuButton` (boolean): Expands the menu button for wide-rail layouts.\n * - `showAppsButton` (boolean): Shows/hides the apps button.\n * - `showDimmingButton` (boolean): Shows/hides the dimming (day/night) button.\n * - `showUserButton` (boolean): Shows/hides the user/profile button.\n * - `showClock` (boolean): Shows/hides the clock.\n * - `showDate` (boolean): Shows/hides the date in the clock.\n * - `showAppIcon` (boolean): Shows/hides the app icon slot.\n * - `inactive` (boolean): Disables interaction and visually de-emphasizes the bar.\n * - `settings` (boolean): Enables settings mode (shows close, back, forward, breadcrumbs).\n * - `breadcrumbItems` (BreadcrumbItem[]): Array of breadcrumb items for navigation.\n * - Breakpoint properties (`appButtonBreakpointPx`, `dimmingButtonBreakpointPx`, `appTitleBreakpointPx`, `userButtonBreakpointPx`, `appIconBreakpointPx`): Control responsive visibility of each section.\n *\n * ## Events\n * - `menu-button-clicked` – Fired when the menu button is clicked.\n * - `dimming-button-clicked` – Fired when the dimming (day/night) button is clicked.\n * - `apps-button-clicked` – Fired when the apps button is clicked.\n * - `left-more-button-clicked` – Fired when the left more button is clicked.\n * - `user-button-clicked` – Fired when the user/profile button is clicked.\n * - `close` – Fired in settings mode when the close button is clicked.\n * - `back` – Fired in settings mode when the back button is clicked.\n * - `forward` – Fired in settings mode when the forward button is clicked.\n * - `emergency-brightness-start` – Fired when the menu button is held for 500ms. This should increase the brightness of the screen slowly. Used when the screen is too dark.\n * - `emergency-brightness-stop` – Fired when the menu button is released.\n *\n * ## Best Practices and Constraints\n * - Only show interactive elements relevant to the current context to avoid clutter.\n * - Use the `alerts` slot for transient or critical notifications; persistent alerts may require a different component.\n * - For accessibility, ensure that all interactive elements have appropriate labels and focus handling.\n * - Adjust breakpoint properties to optimize the layout for different device sizes.\n * - In settings mode, use breadcrumbs to provide clear navigation context.\n *\n * ## Example\n *\n * ```html\n * <obc-top-bar\n * appTitle=\"My App\"\n * pageName=\"Dashboard\"\n * showAppsButton\n * showDimmingButton\n * showClock\n * showUserButton\n * showAppIcon\n * >\n * <obi-placeholder slot=\"app-icon\"></obi-placeholder>\n * <obc-command-button slot=\"command-button\"></obc-command-button>\n * <obc-topbar-message-item slot=\"alerts\"></obc-topbar-message-item>\n * <obc-clock slot=\"clock\"></obc-clock>\n * </obc-top-bar>\n * ```\n *\n * @availableWhen menuButtonIcon settings==false && inactive==false\n * @slot app-icon - Custom icon representing the application or brand (shown when `showAppIcon` is true)\n * @slot command-button - Primary command/action button for the current context\n * @slot alerts - Area for alert indicators, notification badges, or alert items\n * @slot clock - Clock component for displaying the current time (shown when `showClock` is true)\n * @fires menu-button-clicked - Fired when the menu button is clicked\n * @fires dimming-button-clicked - Fired when the dimming (day/night) button is clicked\n * @fires apps-button-clicked - Fired when the apps button is clicked\n * @fires left-more-button-clicked - Fired when the left more button is clicked\n * @fires user-button-clicked - Fired when the user/profile button is clicked\n * @fires close - Fired in settings mode when the close button is clicked\n * @fires back - Fired in settings mode when the back button is clicked\n * @fires emergency-brightness-start - Fired when the menu button is held for 500ms. This should increase the brightness of the screen slowly. Used when the screen is too dark.\n * @fires emergency-brightness-stop - Fired when the menu button is released.\n * @fires {BreadcrumbClickEvent} breadcrumb-click - Fired when a breadcrumb item is clicked.\n * @stable\n */\n@customElement('obc-top-bar')\nexport class ObcTopBar extends LitElement {\n /**\n * Sets the main application title displayed in the top bar.\n * @type {string}\n * @default \"App\"\n */\n @property({type: String}) appTitle = 'App';\n\n /**\n * Sets the current page or section name displayed in the top bar.\n * @type {string}\n * @default \"Page\"\n * @availableWhen settings==false\n */\n @property({type: String}) pageName = 'Page';\n\n @property({type: String}) menuButtonIcon = ObcTopBarMenuButtonIcon.Menu;\n\n /**\n * Highlights the menu button as active.\n * @type {boolean}\n * @default false\n * @availableWhen settings==false && inactive==false\n */\n @property({type: Boolean})\n menuButtonActivated = false;\n\n /**\n * Highlights the dimming (day/night) button as active.\n * @type {boolean}\n * @default false\n * @availableWhen showDimmingButton==true && inactive==false\n */\n @property({type: Boolean})\n dimmingButtonActivated = false;\n\n /**\n * Highlights the apps button as active.\n * @type {boolean}\n * @default false\n * @availableWhen showAppsButton==true && inactive==false\n */\n @property({type: Boolean})\n appsButtonActivated = false;\n\n /**\n * Highlights the left more button as active.\n * @type {boolean}\n * @default false\n * @availableWhen inactive==false\n */\n @property({type: Boolean})\n leftMoreButtonActivated = false;\n\n /**\n * Highlights the user/profile button as active.\n * @type {boolean}\n * @default false\n * @availableWhen showUserButton==true && inactive==false\n */\n @property({type: Boolean})\n userButtonActivated = false;\n\n /**\n * Disables the user/profile button.\n * @type {boolean}\n * @default false\n * @availableWhen showUserButton==true && inactive==false\n */\n @property({type: Boolean})\n userButtonDisabled = false;\n\n /**\n * Increases the height of the top bar for larger touch targets.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) tall = false;\n\n /**\n * Expands the menu button for wide-rail layouts.\n * @type {boolean}\n * @default false\n * @availableWhen settings==false && inactive==false\n */\n @property({type: Boolean}) wideMenuButton = false;\n\n /**\n * Shows or hides the apps button.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showAppsButton = false;\n\n /**\n * Shows or hides the dimming (day/night) button.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean})\n showDimmingButton = false;\n\n /**\n * Shows or hides the user/profile button.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showUserButton = false;\n\n /**\n * Shows or hides the clock.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showClock = false;\n\n /**\n * Shows or hides the date in the clock display.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showDate = false;\n\n /**\n * Shows or hides the app icon slot.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) showAppIcon = false;\n\n /**\n * Disables interaction and visually de-emphasizes the bar.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) inactive = false;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the apps button.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n appButtonBreakpointPx = 500;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the dimming button.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n dimmingButtonBreakpointPx = 500;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the app title.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n appTitleBreakpointPx = 500;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the user button.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n userButtonBreakpointPx = 500;\n\n /**\n * Controls the breakpoint (in px) for showing/hiding the app icon.\n * @type {number}\n * @default 500\n */\n @property({type: Number})\n appIconBreakpointPx = 500;\n\n /**\n * Enables settings mode, displaying close, back buttons, breadcrumbs, and app title.\n * @type {boolean}\n * @default false\n */\n @property({type: Boolean}) settings = false;\n\n /**\n * Array of breadcrumb items for navigation (used in settings mode).\n * @type {BreadcrumbItem[]}\n * @default []\n * @availableWhen settings==true\n */\n @property({type: Array})\n breadcrumbItems: BreadcrumbItem[] = [];\n\n private dimmingButtonClicked() {\n /**\n * Fired when the dimming (day/night) button is clicked.\n * @event dimming-button-clicked\n */\n this.dispatchEvent(new CustomEvent('dimming-button-clicked'));\n }\n\n private appsButtonClicked() {\n /**\n * Fired when the apps button is clicked.\n * @event apps-button-clicked\n */\n this.dispatchEvent(new CustomEvent('apps-button-clicked'));\n }\n\n private leftMoreButtonClicked() {\n /**\n * Fired when the left more button is clicked.\n * @event left-more-button-clicked\n */\n this.dispatchEvent(new CustomEvent('left-more-button-clicked'));\n }\n\n private userButtonClicked() {\n /**\n * Fired when the user/profile button is clicked.\n * @event user-button-clicked\n */\n this.dispatchEvent(new CustomEvent('user-button-clicked'));\n }\n\n private leftButtonEvent: null | CustomEvent = null;\n private leftButtonTimeout: null | NodeJS.Timeout = null;\n private isLeftButtonDown = false;\n private isEmergencyBrightness = false;\n\n private leftButtonDown(event: CustomEvent) {\n this.leftButtonEvent = event;\n this.isLeftButtonDown = true;\n this.leftButtonTimeout = setTimeout(() => {\n this.leftButtonEvent = null;\n this.dispatchEvent(new CustomEvent('emergency-brightness-start'));\n this.isEmergencyBrightness = true;\n }, 500);\n }\n\n private leftButtonUp() {\n if (this.leftButtonEvent) {\n this.dispatchEvent(this.leftButtonEvent);\n this.leftButtonEvent = null;\n }\n if (this.leftButtonTimeout) {\n clearTimeout(this.leftButtonTimeout);\n this.leftButtonTimeout = null;\n }\n if (this.isEmergencyBrightness) {\n this.dispatchEvent(new CustomEvent('emergency-brightness-stop'));\n this.isEmergencyBrightness = false;\n }\n this.isLeftButtonDown = false;\n }\n\n private leftButtonLeave() {\n if (!this.isLeftButtonDown) return;\n if (this.leftButtonTimeout) {\n clearInterval(this.leftButtonTimeout);\n this.leftButtonTimeout = null;\n }\n if (this.isEmergencyBrightness) {\n this.dispatchEvent(new CustomEvent('emergency-brightness-stop'));\n this.isEmergencyBrightness = false;\n }\n this.isLeftButtonDown = false;\n }\n\n override render() {\n const leftGroup = [];\n if (this.settings) {\n leftGroup.push(\n html`<div class=\"menu-button\">\n <obc-icon-button\n variant=\"flat\"\n @pointerdown=${() => this.leftButtonDown(new CustomEvent('close'))}\n @pointerup=${() => this.leftButtonUp()}\n @pointerleave=${() => this.leftButtonLeave()}\n >\n <obi-close-google></obi-close-google>\n </obc-icon-button>\n </div>`\n );\n leftGroup.push(\n html`<obc-icon-button\n variant=\"flat\"\n @click=${() => this.dispatchEvent(new CustomEvent('back'))}\n >\n <obi-arrow-left-google></obi-arrow-left-google>\n </obc-icon-button>`\n );\n leftGroup.push(html`<div class=\"title\">${this.appTitle}</div>`);\n leftGroup.push(\n html`<obc-breadcrumb\n .items=${this.breadcrumbItems}\n @breadcrumb-click=${(e: BreadcrumbClickEvent) =>\n this.dispatchEvent(\n new CustomEvent('breadcrumb-click', {\n detail: e.detail,\n }) as BreadcrumbClickEvent\n )}\n ></obc-breadcrumb>`\n );\n } else {\n if (!this.inactive) {\n leftGroup.push(\n html`<div class=\"menu-button ${this.wideMenuButton ? 'wide' : null}\">\n <obc-icon-button\n variant=\"flat\"\n @pointerdown=${() =>\n this.leftButtonDown(new CustomEvent('menu-button-clicked'))}\n @pointerup=${() => this.leftButtonUp()}\n @pointerleave=${() => this.leftButtonLeave()}\n ?activated=${this.menuButtonActivated}\n >\n ${this.menuButtonIcon === ObcTopBarMenuButtonIcon.Menu\n ? html`<obi-menu-iec></obi-menu-iec>`\n : html`<obi-home></obi-home>`}\n </obc-icon-button>\n </div>`\n );\n }\n if (this.showAppIcon) {\n leftGroup.push(\n html`<div class=\"app-icon\"><slot name=\"app-icon\"></slot></div>`\n );\n }\n leftGroup.push(html`<div class=\"title\">${this.appTitle}</div>`);\n leftGroup.push(html`<div class=\"page-name\">${this.pageName}</div>`);\n leftGroup.push(html`<slot name=\"command-button\"></slot>`);\n }\n\n const breakpointMoreButton = Math.max(\n this.appButtonBreakpointPx,\n this.dimmingButtonBreakpointPx\n );\n\n return html`\n <style>\n @media (max-width: ${breakpointMoreButton}px) {\n .left-more-button {\n display: revert !important;\n }\n\n .group.left > * {\n margin-right: 4px;\n margin-left: 4px;\n }\n }\n\n @media (max-width: ${this.appButtonBreakpointPx}px) {\n .apps-button {\n display: none;\n }\n }\n\n @media (max-width: ${this.dimmingButtonBreakpointPx}px) {\n .dimming-button {\n display: none;\n }\n }\n\n @media (max-width: ${this.appTitleBreakpointPx}px) {\n .title {\n display: none !important; /* the stylesheet's display wins over this inline rule otherwise */\n }\n }\n\n @media (max-width: ${this.userButtonBreakpointPx}px) {\n .user-button {\n display: none;\n }\n }\n\n @media (max-width: ${this.appIconBreakpointPx}px) {\n .app-icon {\n display: none;\n }\n }\n </style>\n <nav\n class=${classMap({\n wrapper: true,\n inactive: this.inactive,\n settings: this.settings,\n tall: this.tall,\n })}\n role=\"menubar\"\n >\n <div class=\"left group\">${leftGroup}</div>\n <div class=\"right group\">\n <div class=\"alert-container\">\n <slot name=\"alerts\"></slot>\n </div>\n ${this.showDimmingButton && !this.inactive\n ? html`<obc-icon-button\n class=\"dimming-button\"\n part=\"dimming-button\"\n variant=\"flat\"\n @click=${this.dimmingButtonClicked}\n ?activated=${this.dimmingButtonActivated}\n >\n <obi-palette-day-night-iec></obi-palette-day-night-iec>\n </obc-icon-button>`\n : null}\n ${this.showUserButton && !this.inactive\n ? html`<obc-icon-button\n class=\"user-button\"\n variant=\"flat\"\n part=\"user-button\"\n @click=${this.userButtonClicked}\n ?activated=${this.userButtonActivated}\n ?disabled=${this.userButtonDisabled}\n >\n <obi-user></obi-user>\n </obc-icon-button>`\n : null}\n ${this.showAppsButton && !this.inactive\n ? html`<obc-icon-button\n class=\"apps-button\"\n variant=\"flat\"\n part=\"apps-button\"\n @click=${this.appsButtonClicked}\n ?activated=${this.appsButtonActivated}\n >\n <obi-applications></obi-applications>\n </obc-icon-button>`\n : null}\n ${this.showClock ? html`<slot name=\"clock\"></slot>` : null}\n ${!this.inactive\n ? html`<obc-icon-button\n class=\"left-more-button\"\n part=\"left-more-button\"\n variant=\"flat\"\n @click=${this.leftMoreButtonClicked}\n ?activated=${this.leftMoreButtonActivated}\n >\n <obi-more-vertical-google></obi-more-vertical-google>\n </obc-icon-button>`\n : null}\n </div>\n </nav>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-top-bar': ObcTopBar;\n }\n}\n"],"names":["ObcTopBarMenuButtonIcon"],"mappings":"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"}
@@ -226,7 +226,7 @@ export interface ReadoutSourceOptions extends ReadoutSrcOptions {
226
226
  * @slot src-picker-content - Provides the source picker context menu content.
227
227
  * @fires {CustomEvent<{value: string, label?: string}>} source-change - Fired when a source picker option is selected.
228
228
  * @fires {CustomEvent<{src: string}>} source-flyout-click - Fired when the source row is clicked while `srcOptions.interaction == 'flyout'`.
229
- * @experimental
229
+ * @beta
230
230
  */
231
231
  export declare class ObcReadout extends LitElement {
232
232
  label?: string;