@oicl/openbridge-webcomponents 2.1.0-next.9 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/openbridge-webcomponents.bundle.js +23 -32
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +42 -42
- package/dist/components/alert-menu/alert-menu.d.ts +5 -5
- package/dist/components/alert-menu/alert-menu.js.map +1 -1
- package/dist/components/app-menu/app-menu.d.ts +5 -5
- package/dist/components/app-menu/app-menu.js.map +1 -1
- package/dist/components/brilliance-menu/brilliance-menu.d.ts +5 -5
- package/dist/components/brilliance-menu/brilliance-menu.js.map +1 -1
- package/dist/components/command-menu/command-menu.d.ts +5 -5
- package/dist/components/command-menu/command-menu.js.map +1 -1
- package/dist/components/context-menu-input/context-menu-input.d.ts +5 -5
- package/dist/components/context-menu-input/context-menu-input.js.map +1 -1
- package/dist/components/navigation-menu/navigation-menu.d.ts +5 -5
- package/dist/components/navigation-menu/navigation-menu.js.map +1 -1
- package/dist/components/slide-button/slide-button.d.ts.map +1 -1
- package/dist/components/slide-button/slide-button.js +1 -1
- package/dist/components/slide-button/slide-button.js.map +1 -1
- package/dist/components/start-stop-switch/start-stop-switch.d.ts.map +1 -1
- package/dist/components/start-stop-switch/start-stop-switch.js +3 -10
- package/dist/components/start-stop-switch/start-stop-switch.js.map +1 -1
- package/dist/components/system-menu/system-menu.d.ts +5 -5
- package/dist/components/system-menu/system-menu.js.map +1 -1
- package/dist/components/user-menu/user-menu.d.ts +5 -5
- package/dist/components/user-menu/user-menu.js.map +1 -1
- package/dist/internal/popover-controller.d.ts +4 -0
- package/dist/internal/popover-controller.d.ts.map +1 -1
- package/dist/internal/popover-controller.js +4 -0
- package/dist/internal/popover-controller.js.map +1 -1
- package/dist/navigation-instruments/readout/readout.css.js +5 -4
- package/dist/navigation-instruments/readout/readout.css.js.map +1 -1
- package/dist/navigation-instruments/readout/readout.d.ts +3 -4
- package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout.js +3 -4
- package/dist/navigation-instruments/readout/readout.js.map +1 -1
- package/dist/navigation-instruments/readout-list/readout-list.css.js +3 -5
- package/dist/navigation-instruments/readout-list/readout-list.css.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +4 -4
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +8 -7
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js +4 -4
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
- package/dist/openbridge.css +389 -263
- package/package.json +1 -1
|
@@ -114,8 +114,8 @@ export type ObcLinkBrightnessChangeEvent = CustomEvent<{
|
|
|
114
114
|
* @property brightnessInputVariant - The variant of the brightness input.
|
|
115
115
|
* @property showScreenControlLink - If true, displays the screen control link.
|
|
116
116
|
* @property showAdditionalScreenControls - If true, displays the additional screen controls slot.
|
|
117
|
-
* @property softDismiss -
|
|
118
|
-
* @property open - Whether the menu is showing.
|
|
117
|
+
* @property softDismiss - Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself.
|
|
118
|
+
* @property open - Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.
|
|
119
119
|
* @availableWhen open softDismiss==true
|
|
120
120
|
* @slot additional-screen-controls - Consumer-defined controls, placed after the screen control link; rendered when `showAdditionalScreenControls` is true
|
|
121
121
|
* @fires {ObcPaletteChangeEvent} palette-changed - When the palette is changed
|
|
@@ -123,13 +123,13 @@ export type ObcLinkBrightnessChangeEvent = CustomEvent<{
|
|
|
123
123
|
* @fires {ObcLinkPaletteChangeEvent} link-palette-changed - When the link palette toggle is changed
|
|
124
124
|
* @fires {ObcLinkBrightnessChangeEvent} link-brightness-changed - When the link brightness toggle is changed
|
|
125
125
|
* @fires {CustomEvent} screen-control-link-clicked - When the screen control link is clicked
|
|
126
|
-
* @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.
|
|
126
|
+
* @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives; reset the flag you bind to `open` here, or the next click on the button finds it still set and asks a closed menu to close.
|
|
127
127
|
*/
|
|
128
128
|
export declare class ObcBrillianceMenu extends LitElement {
|
|
129
|
-
/**
|
|
129
|
+
/** Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself. */
|
|
130
130
|
softDismiss: boolean;
|
|
131
131
|
/**
|
|
132
|
-
* Whether the menu is showing.
|
|
132
|
+
* Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.
|
|
133
133
|
*
|
|
134
134
|
* Available when `softDismiss==true`.
|
|
135
135
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brilliance-menu.js","names":[],"sources":["../../../src/components/brilliance-menu/brilliance-menu.ts"],"sourcesContent":["import {HTMLTemplateResult, LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport componentStyle from './brilliance-menu.css?inline';\nimport '../button/button.js';\nimport '../slider/slider.js';\nimport '../toggle-switch/toggle-switch.js';\nimport '../toggle-button-group/toggle-button-group.js';\nimport '../toggle-button-option/toggle-button-option.js';\nimport '../../icons/icon-display-brilliance-low.js';\nimport '../../icons/icon-display-brilliance-proposal.js';\nimport '../../icons/icon-palette-night.js';\nimport '../../icons/icon-palette-dusk.js';\nimport '../../icons/icon-palette-day.js';\nimport '../../icons/icon-palette-day-bright.js';\nimport '../../icons/icon-link.js';\nimport '../../icons/icon-chevron-double-right-google.js';\nimport '../../icons/icon-chevron-double-left-google.js';\nimport '../../icons/icon-chevron-left-google.js';\nimport '../../icons/icon-chevron-right-google.js';\nimport '../../icons/icon-screen-desk.js';\n\nimport {localized, msg} from '@lit/localize';\nimport {customElement} from '../../decorator.js';\nimport {\n ObcToggleButtonOptionType,\n ObcToggleButtonOptionVariant,\n} from '../toggle-button-option/toggle-button-option.js';\nimport {ObcSliderVariant} from '../slider/slider.js';\nimport {ObcToggleSwitch} from '../toggle-switch/toggle-switch.js';\nimport '../progress-indicator-dots/progress-indicator-dots.js';\nimport '../navigation-item/navigation-item.js';\nimport '../app-button/app-button.js';\nimport '../user-button/user-button.js';\nimport '../tab-row/tab-row.js';\nimport type {TabData} from '../tab-row/tab-row.js';\nimport {stopPropagation} from '../../internal/events.js';\nimport '../../icons/icon-display-brilliance-iec.js';\nimport '../../icons/icon-palette-day-night-iec.js';\nimport {clamp} from '../../svghelpers/math.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\nimport {ObcPalette} from '../../charthelpers/theme.js';\n\nexport {ObcPalette};\n\nexport enum ObcBrillianceMenuVariant {\n normal = 'normal',\n compact = 'compact',\n tabbed = 'tabbed',\n}\n\nexport enum ObcBrillianceInputVariant {\n buttons = 'buttons',\n slider = 'slider',\n}\n\nexport type ObcPaletteChangeEvent = CustomEvent<{value: ObcPalette}>;\nexport type ObcBrightnessChangeEvent = CustomEvent<{value: number}>;\nexport type ObcLinkPaletteChangeEvent = CustomEvent<{value: boolean}>;\nexport type ObcLinkBrightnessChangeEvent = CustomEvent<{value: boolean}>;\n\nconst BRILLIANCE_TAB_ID = 'brilliance';\nconst PALETTE_TAB_ID = 'palette';\n\n/**\n * Event fired when the palette is changed.\n * @typedef {CustomEvent<{value: ObcPalette}>} ObcPaletteChangeEvent\n */\n\n/**\n * Event fired when the brightness is changed.\n * @typedef {CustomEvent<{value: number}>} ObcBrightnessChangeEvent\n */\n\n/**\n * `<obc-brilliance-menu>` – A settings menu component for adjusting display palette and brightness.\n *\n * Provides a combined interface for users to select a color palette (night, dusk, day, bright) and adjust screen brightness. Includes options for toggling automatic palette and brightness modes. Designed for quick access to visual environment controls in applications where adaptable display settings are important.\n *\n * ### Features\n * - **Palette Selection:** Choose between four preset palettes: night, dusk, day, and bright. Each palette is represented by an icon.\n * - **Brightness Control:** Adjustable slider for fine-tuning brightness from 0 to 100. Optionally displays left/right icons for low and high brilliance.\n * - **Auto Modes:** Optional toggles for enabling automatic palette switching and automatic brightness adjustment.\n * - **Configurable Visibility:** Brightness controls and auto toggles can be shown or hidden via properties.\n * - **Responsive Layout:** Arranged in a card-style panel for use in settings menus or overlays.\n *\n * ### Variants\n * - **Palette:** Four options—`night`, `dusk`, `day`, `bright`. Each is visually distinct and selectable via toggle button group.\n * - **Auto Toggles:** `showAutoBrightness` and `showAutoPalette` properties control the presence of auto mode switches.\n * - **Show Brightness:** The `showBrightness` property controls whether the brightness slider and auto brightness toggle are visible.\n *\n * ### Usage Guidelines\n * Use `obc-brilliance-menu` in settings panels or overlays where users need to quickly adjust display appearance. Ideal for scenarios requiring rapid adaptation to changing lighting conditions or user preferences.\n * **TODO(designer):** Confirm if there are recommended default palette/brightness settings, and clarify intended use cases for auto toggles versus manual controls.\n *\n * ### Properties and Configuration\n * - `palette` (`ObcPalette`): The currently selected palette. Accepts `'night'`, `'dusk'`, `'day'`, or `'bright'`. Defaults to `'day'`.\n * - `brightness` (`number`): Current brightness value (0–100). Defaults to `50`.\n * - `showAutoBrightness` (`boolean`): If true, displays the auto brightness toggle.\n * - `showAutoPalette` (`boolean`): If true, displays the auto palette toggle.\n * - `showBrightness` (`boolean`): If true, shows the brightness slider and auto brightness toggle.\n *\n * ### Events\n * - `palette-changed` – Fired when the user selects a new palette. Event detail: `{ value: ObcPalette }`\n * - `brightness-changed` – Fired when the brightness slider is adjusted. Event detail: `{ value: number }`\n *\n * ### Example\n * ```html\n * <obc-brilliance-menu\n * palette=\"dusk\"\n * brightness=\"75\"\n * showAutoBrightness\n * showAutoPalette\n * ></obc-brilliance-menu>\n * ```\n * In this example, both auto toggles are visible, the palette is set to dusk, and brightness is set to 75.\n *\n * @property palette - The currently selected palette. Possible values: `'night'`, `'dusk'`, `'day'`, `'bright'`.\n * Defaults to `'day'`.\n * @property brightness - The current brightness value (0–100). Defaults to `50`.\n * @property showLinkBrightness - If true, displays the link brightness toggle below the brightness slider.\n * @property showLinkPalette - If true, displays the link palette toggle below the palette selector.\n * @property showBrightness - If true, shows the brightness slider and auto brightness toggle in the menu.\n * @property showPalette - If true, shows the palette selector and link palette toggle in the menu.\n * @property variant - The variant of the menu. Possible values: `'normal'`, `'compact'`, `'tabbed'`.\n * Defaults to `'normal'`.\n * @property brightnessUnit - The unit of the brightness value.\n * @property brightnessMax - The maximum value of the brightness slider.\n * @property brightnessMinorStep - The minor step of the brightness slider.\n * @property brightnessMajorStep - The major step of the brightness slider.\n * @property brightnessInputVariant - The variant of the brightness input.\n * @property showScreenControlLink - If true, displays the screen control link.\n * @property showAdditionalScreenControls - If true, displays the additional screen controls slot.\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot additional-screen-controls - Consumer-defined controls, placed after the screen control link; rendered when `showAdditionalScreenControls` is true\n * @fires {ObcPaletteChangeEvent} palette-changed - When the palette is changed\n * @fires {ObcBrightnessChangeEvent} brightness-changed - When the brightness is changed\n * @fires {ObcLinkPaletteChangeEvent} link-palette-changed - When the link palette toggle is changed\n * @fires {ObcLinkBrightnessChangeEvent} link-brightness-changed - When the link brightness toggle is changed\n * @fires {CustomEvent} screen-control-link-clicked - When the screen control link is clicked\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.\n */\n@localized()\n/**\n * @stable\n */\n@customElement('obc-brilliance-menu')\nexport class ObcBrillianceMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: String}) palette: ObcPalette = ObcPalette.day;\n\n @property({type: Number}) brightness = 50;\n\n @property({type: Boolean})\n showLinkBrightness = false;\n\n @property({type: Boolean}) showLinkPalette = false;\n\n @property({type: Boolean, attribute: false}) showBrightness = true;\n\n @property({type: Boolean, attribute: false}) showPalette = true;\n\n @property({type: Boolean, attribute: false}) showNightPalette = true;\n @property({type: Boolean, attribute: false}) showDuskPalette = true;\n @property({type: Boolean, attribute: false}) showDayPalette = true;\n @property({type: Boolean, attribute: false}) showBrightPalette = true;\n\n @property({type: String}) variant = ObcBrillianceMenuVariant.normal;\n\n @property({type: String}) brightnessUnit = '%';\n\n @property({type: Number}) brightnessMax = 100;\n\n @property({type: Number}) brightnessMinorStep = 5;\n\n @property({type: Number}) brightnessMajorStep = 25;\n\n @property({type: String}) brightnessInputVariant =\n ObcBrillianceInputVariant.buttons;\n\n @property({type: Boolean}) showScreenControlLink = false;\n\n @property({type: Boolean}) showAdditionalScreenControls = false;\n\n override willUpdate(_changed: Map<string, unknown>) {\n if (this.showPalette) {\n const available = this.availablePalettes;\n if (available.length > 0 && !available.includes(this.palette)) {\n this.palette = available[0];\n this.dispatchEvent(\n new CustomEvent('palette-changed', {\n detail: {value: this.palette},\n })\n );\n }\n }\n }\n\n /**\n * Handles palette selection changes and emits `palette-changed`.\n * @fires palette-changed\n * @param {CustomEvent} event\n */\n onPaletteChanged(event: CustomEvent) {\n this.palette = event.detail.value;\n this.dispatchEvent(\n new CustomEvent('palette-changed', {\n detail: {value: event.detail.value},\n })\n );\n }\n\n /**\n * Handles brightness slider changes and emits `brightness-changed`.\n * @fires brightness-changed\n * @param {CustomEvent} event\n */\n handleBrightnessChanged(event: CustomEvent) {\n this.brightness = event.detail;\n this.dispatchEvent(\n new CustomEvent('brightness-changed', {\n detail: {value: event.detail},\n })\n );\n }\n\n increaseBrightness(step: number) {\n this.brightness = clamp(\n this.brightness + step,\n 0,\n Math.max(0, this.brightnessMax)\n );\n this.dispatchEvent(\n new CustomEvent('brightness-changed', {\n detail: {value: this.brightness},\n })\n );\n }\n\n get canIncreaseBrightness() {\n return this.brightness < this.brightnessMax;\n }\n\n get canDecreaseBrightness() {\n return this.brightness > 0;\n }\n\n /**\n * Handles link palette changes and emits `link-palette-changed`.\n * @fires link-palette-changed\n * @param {CustomEvent} event\n */\n onLinkPaletteChanged(event: CustomEvent) {\n this.dispatchEvent(\n new CustomEvent('link-palette-changed', {\n detail: {value: (event.target as ObcToggleSwitch).checked},\n })\n );\n }\n\n /**\n * Handles link brightness changes and emits `link-brightness-changed`.\n * @fires link-brightness-changed\n * @param {CustomEvent} event\n */\n onLinkBrightnessChanged(event: CustomEvent) {\n this.dispatchEvent(\n new CustomEvent('link-brightness-changed', {\n detail: {value: (event.target as ObcToggleSwitch).checked},\n })\n );\n }\n\n get availablePalettes(): ObcPalette[] {\n const palettes: ObcPalette[] = [];\n if (this.showNightPalette) palettes.push(ObcPalette.night);\n if (this.showDuskPalette) palettes.push(ObcPalette.dusk);\n if (this.showDayPalette) palettes.push(ObcPalette.day);\n if (this.showBrightPalette) palettes.push(ObcPalette.bright);\n return palettes;\n }\n\n get canIncreasePalette() {\n const palettes = this.availablePalettes;\n const idx = palettes.indexOf(this.palette);\n return idx >= 0 && idx < palettes.length - 1;\n }\n\n get canDecreasePalette() {\n const palettes = this.availablePalettes;\n const idx = palettes.indexOf(this.palette);\n return idx > 0;\n }\n\n @state() private selectedTabId = BRILLIANCE_TAB_ID;\n\n private onTabSelected(event: CustomEvent<{id: string}>) {\n event.stopPropagation();\n this.selectedTabId = event.detail.id;\n }\n\n private get tabs(): TabData[] {\n return [\n {\n id: BRILLIANCE_TAB_ID,\n title: msg('Brilliance'),\n hasLeadingIcon: true,\n },\n {\n id: PALETTE_TAB_ID,\n title: `${msg('Day')}/${msg('Night')}`,\n hasLeadingIcon: true,\n },\n ];\n }\n\n nextPalette() {\n if (this.canIncreasePalette) {\n const palettes = this.availablePalettes;\n const idx = palettes.indexOf(this.palette);\n this.palette = palettes[idx + 1];\n this.dispatchEvent(\n new CustomEvent('palette-changed', {\n detail: {value: this.palette},\n })\n );\n }\n }\n\n previousPalette() {\n if (this.canDecreasePalette) {\n const palettes = this.availablePalettes;\n const idx = palettes.indexOf(this.palette);\n this.palette = palettes[idx - 1];\n this.dispatchEvent(\n new CustomEvent('palette-changed', {\n detail: {value: this.palette},\n })\n );\n }\n }\n\n renderBrightness() {\n const title =\n this.variant === ObcBrillianceMenuVariant.tabbed\n ? nothing\n : html`<div class=\"title-container\">\n <h3>${msg('Brilliance')}</h3>\n </div>`;\n const valueLength =\n this.brightness.toString().length + 0.5 * this.brightnessUnit.length;\n\n return html`${title}\n <div class=\"content-container brilliance\">\n ${\n this.variant === ObcBrillianceMenuVariant.compact\n ? html` <obc-slider\n value=${this.brightness}\n @value=${this.handleBrightnessChanged}\n min=\"0\"\n max=${this.brightnessMax}\n variant=${ObcSliderVariant.Normal}\n haslefticon\n hasrighticon\n >\n <obi-display-brilliance-low\n slot=\"icon-left\"\n ></obi-display-brilliance-low>\n <obi-display-brilliance-proposal\n slot=\"icon-right\"\n ></obi-display-brilliance-proposal>\n </obc-slider>`\n : html`\n <div class=\"value-container\">\n <div class=\"value-label-container\">\n <obi-display-brilliance-proposal\n class=\"icon\"\n ></obi-display-brilliance-proposal>\n <div\n class=\"label-container\"\n style=\"width: ${valueLength}ch\"\n >\n <div class=\"value\">${this.brightness.toFixed(0)}</div>\n <div class=\"unit\">${this.brightnessUnit}</div>\n </div>\n </div>\n <div class=\"value-slider-container\">\n ${\n this.brightnessInputVariant ===\n ObcBrillianceInputVariant.buttons\n ? html`\n <obc-slider\n value=${this.brightness}\n variant=${ObcSliderVariant.NoInput}\n min=\"0\"\n max=${this.brightnessMax}\n ></obc-slider>\n `\n : html`\n <obc-slider\n value=${this.brightness}\n variant=${ObcSliderVariant.Enhanced}\n @value=${this.handleBrightnessChanged}\n min=\"0\"\n max=${this.brightnessMax}\n ></obc-slider>\n `\n }\n </div>\n </div>\n ${\n this.brightnessInputVariant ===\n ObcBrillianceInputVariant.buttons\n ? html`\n <div class=\"icon-button-container\">\n <obc-button\n segmentPosition=\"start\"\n fullWidth\n ?disabled=${!this.canDecreaseBrightness}\n class=${this.canDecreaseBrightness ? '' : 'disabled'}\n @click=${() =>\n this.increaseBrightness(\n -this.brightnessMajorStep\n )}\n >\n <obi-chevron-double-left-google\n class=\"btn-icon\"\n ></obi-chevron-double-left-google>\n </obc-button>\n <obc-button\n segmentPosition=\"middle\"\n fullWidth\n ?disabled=${!this.canDecreaseBrightness}\n class=${this.canDecreaseBrightness ? '' : 'disabled'}\n @click=${() =>\n this.increaseBrightness(\n -this.brightnessMinorStep\n )}\n >\n <obi-chevron-left-google\n class=\"btn-icon\"\n ></obi-chevron-left-google>\n </obc-button>\n <obc-button\n segmentPosition=\"middle\"\n fullWidth\n ?disabled=${!this.canIncreaseBrightness}\n class=${this.canIncreaseBrightness ? '' : 'disabled'}\n @click=${() =>\n this.increaseBrightness(this.brightnessMinorStep)}\n >\n <obi-chevron-right-google\n class=\"btn-icon\"\n ></obi-chevron-right-google>\n </obc-button>\n <obc-button\n segmentPosition=\"end\"\n fullWidth\n ?disabled=${!this.canIncreaseBrightness}\n class=${this.canIncreaseBrightness ? '' : 'disabled'}\n @click=${() =>\n this.increaseBrightness(this.brightnessMajorStep)}\n >\n <obi-chevron-double-right-google\n class=\"btn-icon\"\n ></obi-chevron-double-right-google>\n </obc-button>\n </div>\n `\n : nothing\n }\n `\n }\n ${\n this.showLinkBrightness\n ? html`<obc-toggle-switch\n .label=\"${msg('Link')}\"\n hasicon\n @input=${this.onLinkBrightnessChanged}\n >\n <obi-link slot=\"icon\"></obi-link>\n </obc-toggle-switch>`\n : nothing\n }\n </div>`;\n }\n\n get effectivePalette() {\n const palettes = this.availablePalettes;\n return palettes.includes(this.palette) ? this.palette : palettes[0];\n }\n\n get paletteIcon() {\n if (this.effectivePalette === ObcPalette.night) {\n return html`<obi-palette-night class=\"icon\"></obi-palette-night>`;\n } else if (this.effectivePalette === ObcPalette.dusk) {\n return html`<obi-palette-dusk class=\"icon\"></obi-palette-dusk>`;\n } else if (this.effectivePalette === ObcPalette.day) {\n return html`<obi-palette-day class=\"icon\"></obi-palette-day>`;\n } else if (this.effectivePalette === ObcPalette.bright) {\n return html`<obi-palette-day-bright\n class=\"icon\"\n ></obi-palette-day-bright>`;\n } else {\n return nothing;\n }\n }\n\n private paletteOptions(): HTMLTemplateResult[] {\n const out = [];\n if (this.showNightPalette)\n out.push(\n html`<obc-toggle-button-option value=\"night\" type=\"icon\">\n <obi-palette-night slot=\"icon\"></obi-palette-night>\n </obc-toggle-button-option>`\n );\n if (this.showDuskPalette)\n out.push(\n html`<obc-toggle-button-option value=\"dusk\" type=\"icon\">\n <obi-palette-dusk slot=\"icon\"></obi-palette-dusk>\n </obc-toggle-button-option>`\n );\n if (this.showDayPalette)\n out.push(\n html`<obc-toggle-button-option value=\"day\" type=\"icon\">\n <obi-palette-day slot=\"icon\"></obi-palette-day>\n </obc-toggle-button-option>`\n );\n if (this.showBrightPalette)\n out.push(\n html`<obc-toggle-button-option value=\"bright\" type=\"icon\">\n <obi-palette-day-bright slot=\"icon\"></obi-palette-day-bright>\n </obc-toggle-button-option>`\n );\n return out;\n }\n\n renderPalette() {\n const palettes = this.availablePalettes;\n if (palettes.length === 0) return nothing;\n\n const paletteNames: Record<ObcPalette, string> = {\n [ObcPalette.night]: msg('Night'),\n [ObcPalette.dusk]: msg('Dusk'),\n [ObcPalette.day]: msg('Day'),\n [ObcPalette.bright]: msg('Bright'),\n };\n const currentPaletteName = paletteNames[this.effectivePalette];\n const valueLength = currentPaletteName.length;\n const index = palettes.indexOf(this.effectivePalette);\n const nextIndex = Math.min(index + 1, palettes.length - 1);\n const previousIndex = Math.max(index - 1, 0);\n const nextPalette = paletteNames[palettes[nextIndex]];\n const previousPalette = paletteNames[palettes[previousIndex]];\n\n return html`\n ${\n this.variant === ObcBrillianceMenuVariant.tabbed\n ? nothing\n : html`\n <div class=\"title-container\">\n <h3>${msg('Day')}/${msg('Night')}</h3>\n </div>\n `\n }\n <div\n class=\"content-container palette ${\n this.showLinkPalette ? 'with-link' : 'without-link'\n }\"\n >\n ${\n this.variant === ObcBrillianceMenuVariant.compact\n ? html` <obc-toggle-button-group\n aria-label=${`${msg('Day')}/${msg('Night')}`}\n value=${this.effectivePalette}\n @value=${this.onPaletteChanged}\n variant=${ObcToggleButtonOptionVariant.regular}\n type=${ObcToggleButtonOptionType.icon}\n >\n ${this.paletteOptions()}\n </obc-toggle-button-group>`\n : html`\n <div class=\"value-container\">\n <div class=\"value-label-container\">\n ${this.paletteIcon}\n <div\n class=\"label-container\"\n style=\"width: ${valueLength}ch\"\n >\n <div class=\"value\">${currentPaletteName}</div>\n </div>\n </div>\n <obc-progress-indicator-dots\n .totalSteps=${palettes.length}\n .currentStep=${index + 1}\n ></obc-progress-indicator-dots>\n </div>\n <div class=\"icon-button-container\">\n <obc-button\n segmentPosition=\"start\"\n fullWidth\n showLeadingIcon\n ?disabled=${!this.canDecreasePalette}\n class=${this.canDecreasePalette ? '' : 'disabled'}\n @click=${() => this.previousPalette()}\n >\n ${previousPalette}\n <obi-chevron-left-google\n slot=\"leading-icon\"\n ></obi-chevron-left-google>\n </obc-button>\n\n <obc-button\n segmentPosition=\"end\"\n fullWidth\n showTrailingIcon\n ?disabled=${!this.canIncreasePalette}\n class=${this.canIncreasePalette ? '' : 'disabled'}\n @click=${() => this.nextPalette()}\n >\n ${nextPalette}\n <obi-chevron-right-google\n slot=\"trailing-icon\"\n ></obi-chevron-right-google>\n </obc-button>\n </div>\n `\n }\n ${\n this.showLinkPalette\n ? html`<obc-toggle-switch\n .label=\"${msg('Link')}\"\n hasicon\n @input=${this.onLinkPaletteChanged}\n >\n <obi-link slot=\"icon\"></obi-link>\n </obc-toggle-switch>`\n : nothing\n }\n </div>\n `;\n }\n\n renderScreenControlLink() {\n if (this.showScreenControlLink || this.showAdditionalScreenControls) {\n return html`\n <div class=\"footer\">\n ${\n this.showScreenControlLink\n ? html`\n <obc-navigation-item\n .label=\"${msg('Screen Control')}\"\n @click=${() => this.handleScreenControlLinkClicked()}\n hasicon\n >\n <obc-user-button\n slot=\"icon\"\n static\n variant=\"icon\"\n styleType=\"normal\"\n >\n <obi-screen-desk slot=\"icon\"></obi-screen-desk>\n </obc-user-button>\n </obc-navigation-item>\n `\n : nothing\n }\n ${\n this.showAdditionalScreenControls\n ? html`<slot name=\"additional-screen-controls\"></slot>`\n : nothing\n }\n </div>\n `;\n }\n return nothing;\n }\n\n override render() {\n if (this.variant === ObcBrillianceMenuVariant.tabbed) {\n return html`\n <div class=\"card tabbed\">\n <obc-tab-row\n .tabs=${this.tabs}\n .selectedTabId=${this.selectedTabId}\n .centerContent=${true}\n .hasPanels=${true}\n .label=${msg('Display')}\n @tab-selected=${this.onTabSelected}\n @tab-closed=${stopPropagation}\n @add-new-tab=${stopPropagation}\n >\n <obi-display-brilliance-iec\n slot=\"tab-${BRILLIANCE_TAB_ID}-icon\"\n ></obi-display-brilliance-iec>\n <obi-palette-day-night-iec\n slot=\"tab-${PALETTE_TAB_ID}-icon\"\n ></obi-palette-day-night-iec>\n <div slot=\"tab-${BRILLIANCE_TAB_ID}-panel\">\n ${this.renderBrightness()}\n </div>\n <div slot=\"tab-${PALETTE_TAB_ID}-panel\">\n ${this.renderPalette()}\n </div>\n </obc-tab-row>\n ${this.renderScreenControlLink()}\n </div>\n `;\n } else {\n return html`\n <div class=\"card ${this.variant}\">\n ${this.showBrightness ? this.renderBrightness() : nothing}\n ${\n this.showBrightness && this.showPalette\n ? html`<div class=\"divider\"></div>`\n : nothing\n }\n ${this.showPalette ? this.renderPalette() : nothing}\n ${this.renderScreenControlLink()}\n </div>\n `;\n }\n }\n\n handleScreenControlLinkClicked() {\n this.dispatchEvent(new CustomEvent('screen-control-link-clicked'));\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-brilliance-menu': ObcBrillianceMenu;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"brilliance-menu.js","names":[],"sources":["../../../src/components/brilliance-menu/brilliance-menu.ts"],"sourcesContent":["import {HTMLTemplateResult, LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport componentStyle from './brilliance-menu.css?inline';\nimport '../button/button.js';\nimport '../slider/slider.js';\nimport '../toggle-switch/toggle-switch.js';\nimport '../toggle-button-group/toggle-button-group.js';\nimport '../toggle-button-option/toggle-button-option.js';\nimport '../../icons/icon-display-brilliance-low.js';\nimport '../../icons/icon-display-brilliance-proposal.js';\nimport '../../icons/icon-palette-night.js';\nimport '../../icons/icon-palette-dusk.js';\nimport '../../icons/icon-palette-day.js';\nimport '../../icons/icon-palette-day-bright.js';\nimport '../../icons/icon-link.js';\nimport '../../icons/icon-chevron-double-right-google.js';\nimport '../../icons/icon-chevron-double-left-google.js';\nimport '../../icons/icon-chevron-left-google.js';\nimport '../../icons/icon-chevron-right-google.js';\nimport '../../icons/icon-screen-desk.js';\n\nimport {localized, msg} from '@lit/localize';\nimport {customElement} from '../../decorator.js';\nimport {\n ObcToggleButtonOptionType,\n ObcToggleButtonOptionVariant,\n} from '../toggle-button-option/toggle-button-option.js';\nimport {ObcSliderVariant} from '../slider/slider.js';\nimport {ObcToggleSwitch} from '../toggle-switch/toggle-switch.js';\nimport '../progress-indicator-dots/progress-indicator-dots.js';\nimport '../navigation-item/navigation-item.js';\nimport '../app-button/app-button.js';\nimport '../user-button/user-button.js';\nimport '../tab-row/tab-row.js';\nimport type {TabData} from '../tab-row/tab-row.js';\nimport {stopPropagation} from '../../internal/events.js';\nimport '../../icons/icon-display-brilliance-iec.js';\nimport '../../icons/icon-palette-day-night-iec.js';\nimport {clamp} from '../../svghelpers/math.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\nimport {ObcPalette} from '../../charthelpers/theme.js';\n\nexport {ObcPalette};\n\nexport enum ObcBrillianceMenuVariant {\n normal = 'normal',\n compact = 'compact',\n tabbed = 'tabbed',\n}\n\nexport enum ObcBrillianceInputVariant {\n buttons = 'buttons',\n slider = 'slider',\n}\n\nexport type ObcPaletteChangeEvent = CustomEvent<{value: ObcPalette}>;\nexport type ObcBrightnessChangeEvent = CustomEvent<{value: number}>;\nexport type ObcLinkPaletteChangeEvent = CustomEvent<{value: boolean}>;\nexport type ObcLinkBrightnessChangeEvent = CustomEvent<{value: boolean}>;\n\nconst BRILLIANCE_TAB_ID = 'brilliance';\nconst PALETTE_TAB_ID = 'palette';\n\n/**\n * Event fired when the palette is changed.\n * @typedef {CustomEvent<{value: ObcPalette}>} ObcPaletteChangeEvent\n */\n\n/**\n * Event fired when the brightness is changed.\n * @typedef {CustomEvent<{value: number}>} ObcBrightnessChangeEvent\n */\n\n/**\n * `<obc-brilliance-menu>` – A settings menu component for adjusting display palette and brightness.\n *\n * Provides a combined interface for users to select a color palette (night, dusk, day, bright) and adjust screen brightness. Includes options for toggling automatic palette and brightness modes. Designed for quick access to visual environment controls in applications where adaptable display settings are important.\n *\n * ### Features\n * - **Palette Selection:** Choose between four preset palettes: night, dusk, day, and bright. Each palette is represented by an icon.\n * - **Brightness Control:** Adjustable slider for fine-tuning brightness from 0 to 100. Optionally displays left/right icons for low and high brilliance.\n * - **Auto Modes:** Optional toggles for enabling automatic palette switching and automatic brightness adjustment.\n * - **Configurable Visibility:** Brightness controls and auto toggles can be shown or hidden via properties.\n * - **Responsive Layout:** Arranged in a card-style panel for use in settings menus or overlays.\n *\n * ### Variants\n * - **Palette:** Four options—`night`, `dusk`, `day`, `bright`. Each is visually distinct and selectable via toggle button group.\n * - **Auto Toggles:** `showAutoBrightness` and `showAutoPalette` properties control the presence of auto mode switches.\n * - **Show Brightness:** The `showBrightness` property controls whether the brightness slider and auto brightness toggle are visible.\n *\n * ### Usage Guidelines\n * Use `obc-brilliance-menu` in settings panels or overlays where users need to quickly adjust display appearance. Ideal for scenarios requiring rapid adaptation to changing lighting conditions or user preferences.\n * **TODO(designer):** Confirm if there are recommended default palette/brightness settings, and clarify intended use cases for auto toggles versus manual controls.\n *\n * ### Properties and Configuration\n * - `palette` (`ObcPalette`): The currently selected palette. Accepts `'night'`, `'dusk'`, `'day'`, or `'bright'`. Defaults to `'day'`.\n * - `brightness` (`number`): Current brightness value (0–100). Defaults to `50`.\n * - `showAutoBrightness` (`boolean`): If true, displays the auto brightness toggle.\n * - `showAutoPalette` (`boolean`): If true, displays the auto palette toggle.\n * - `showBrightness` (`boolean`): If true, shows the brightness slider and auto brightness toggle.\n *\n * ### Events\n * - `palette-changed` – Fired when the user selects a new palette. Event detail: `{ value: ObcPalette }`\n * - `brightness-changed` – Fired when the brightness slider is adjusted. Event detail: `{ value: number }`\n *\n * ### Example\n * ```html\n * <obc-brilliance-menu\n * palette=\"dusk\"\n * brightness=\"75\"\n * showAutoBrightness\n * showAutoPalette\n * ></obc-brilliance-menu>\n * ```\n * In this example, both auto toggles are visible, the palette is set to dusk, and brightness is set to 75.\n *\n * @property palette - The currently selected palette. Possible values: `'night'`, `'dusk'`, `'day'`, `'bright'`.\n * Defaults to `'day'`.\n * @property brightness - The current brightness value (0–100). Defaults to `50`.\n * @property showLinkBrightness - If true, displays the link brightness toggle below the brightness slider.\n * @property showLinkPalette - If true, displays the link palette toggle below the palette selector.\n * @property showBrightness - If true, shows the brightness slider and auto brightness toggle in the menu.\n * @property showPalette - If true, shows the palette selector and link palette toggle in the menu.\n * @property variant - The variant of the menu. Possible values: `'normal'`, `'compact'`, `'tabbed'`.\n * Defaults to `'normal'`.\n * @property brightnessUnit - The unit of the brightness value.\n * @property brightnessMax - The maximum value of the brightness slider.\n * @property brightnessMinorStep - The minor step of the brightness slider.\n * @property brightnessMajorStep - The major step of the brightness slider.\n * @property brightnessInputVariant - The variant of the brightness input.\n * @property showScreenControlLink - If true, displays the screen control link.\n * @property showAdditionalScreenControls - If true, displays the additional screen controls slot.\n * @property softDismiss - Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself.\n * @property open - Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.\n * @availableWhen open softDismiss==true\n * @slot additional-screen-controls - Consumer-defined controls, placed after the screen control link; rendered when `showAdditionalScreenControls` is true\n * @fires {ObcPaletteChangeEvent} palette-changed - When the palette is changed\n * @fires {ObcBrightnessChangeEvent} brightness-changed - When the brightness is changed\n * @fires {ObcLinkPaletteChangeEvent} link-palette-changed - When the link palette toggle is changed\n * @fires {ObcLinkBrightnessChangeEvent} link-brightness-changed - When the link brightness toggle is changed\n * @fires {CustomEvent} screen-control-link-clicked - When the screen control link is clicked\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives; reset the flag you bind to `open` here, or the next click on the button finds it still set and asks a closed menu to close.\n */\n@localized()\n/**\n * @stable\n */\n@customElement('obc-brilliance-menu')\nexport class ObcBrillianceMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: String}) palette: ObcPalette = ObcPalette.day;\n\n @property({type: Number}) brightness = 50;\n\n @property({type: Boolean})\n showLinkBrightness = false;\n\n @property({type: Boolean}) showLinkPalette = false;\n\n @property({type: Boolean, attribute: false}) showBrightness = true;\n\n @property({type: Boolean, attribute: false}) showPalette = true;\n\n @property({type: Boolean, attribute: false}) showNightPalette = true;\n @property({type: Boolean, attribute: false}) showDuskPalette = true;\n @property({type: Boolean, attribute: false}) showDayPalette = true;\n @property({type: Boolean, attribute: false}) showBrightPalette = true;\n\n @property({type: String}) variant = ObcBrillianceMenuVariant.normal;\n\n @property({type: String}) brightnessUnit = '%';\n\n @property({type: Number}) brightnessMax = 100;\n\n @property({type: Number}) brightnessMinorStep = 5;\n\n @property({type: Number}) brightnessMajorStep = 25;\n\n @property({type: String}) brightnessInputVariant =\n ObcBrillianceInputVariant.buttons;\n\n @property({type: Boolean}) showScreenControlLink = false;\n\n @property({type: Boolean}) showAdditionalScreenControls = false;\n\n override willUpdate(_changed: Map<string, unknown>) {\n if (this.showPalette) {\n const available = this.availablePalettes;\n if (available.length > 0 && !available.includes(this.palette)) {\n this.palette = available[0];\n this.dispatchEvent(\n new CustomEvent('palette-changed', {\n detail: {value: this.palette},\n })\n );\n }\n }\n }\n\n /**\n * Handles palette selection changes and emits `palette-changed`.\n * @fires palette-changed\n * @param {CustomEvent} event\n */\n onPaletteChanged(event: CustomEvent) {\n this.palette = event.detail.value;\n this.dispatchEvent(\n new CustomEvent('palette-changed', {\n detail: {value: event.detail.value},\n })\n );\n }\n\n /**\n * Handles brightness slider changes and emits `brightness-changed`.\n * @fires brightness-changed\n * @param {CustomEvent} event\n */\n handleBrightnessChanged(event: CustomEvent) {\n this.brightness = event.detail;\n this.dispatchEvent(\n new CustomEvent('brightness-changed', {\n detail: {value: event.detail},\n })\n );\n }\n\n increaseBrightness(step: number) {\n this.brightness = clamp(\n this.brightness + step,\n 0,\n Math.max(0, this.brightnessMax)\n );\n this.dispatchEvent(\n new CustomEvent('brightness-changed', {\n detail: {value: this.brightness},\n })\n );\n }\n\n get canIncreaseBrightness() {\n return this.brightness < this.brightnessMax;\n }\n\n get canDecreaseBrightness() {\n return this.brightness > 0;\n }\n\n /**\n * Handles link palette changes and emits `link-palette-changed`.\n * @fires link-palette-changed\n * @param {CustomEvent} event\n */\n onLinkPaletteChanged(event: CustomEvent) {\n this.dispatchEvent(\n new CustomEvent('link-palette-changed', {\n detail: {value: (event.target as ObcToggleSwitch).checked},\n })\n );\n }\n\n /**\n * Handles link brightness changes and emits `link-brightness-changed`.\n * @fires link-brightness-changed\n * @param {CustomEvent} event\n */\n onLinkBrightnessChanged(event: CustomEvent) {\n this.dispatchEvent(\n new CustomEvent('link-brightness-changed', {\n detail: {value: (event.target as ObcToggleSwitch).checked},\n })\n );\n }\n\n get availablePalettes(): ObcPalette[] {\n const palettes: ObcPalette[] = [];\n if (this.showNightPalette) palettes.push(ObcPalette.night);\n if (this.showDuskPalette) palettes.push(ObcPalette.dusk);\n if (this.showDayPalette) palettes.push(ObcPalette.day);\n if (this.showBrightPalette) palettes.push(ObcPalette.bright);\n return palettes;\n }\n\n get canIncreasePalette() {\n const palettes = this.availablePalettes;\n const idx = palettes.indexOf(this.palette);\n return idx >= 0 && idx < palettes.length - 1;\n }\n\n get canDecreasePalette() {\n const palettes = this.availablePalettes;\n const idx = palettes.indexOf(this.palette);\n return idx > 0;\n }\n\n @state() private selectedTabId = BRILLIANCE_TAB_ID;\n\n private onTabSelected(event: CustomEvent<{id: string}>) {\n event.stopPropagation();\n this.selectedTabId = event.detail.id;\n }\n\n private get tabs(): TabData[] {\n return [\n {\n id: BRILLIANCE_TAB_ID,\n title: msg('Brilliance'),\n hasLeadingIcon: true,\n },\n {\n id: PALETTE_TAB_ID,\n title: `${msg('Day')}/${msg('Night')}`,\n hasLeadingIcon: true,\n },\n ];\n }\n\n nextPalette() {\n if (this.canIncreasePalette) {\n const palettes = this.availablePalettes;\n const idx = palettes.indexOf(this.palette);\n this.palette = palettes[idx + 1];\n this.dispatchEvent(\n new CustomEvent('palette-changed', {\n detail: {value: this.palette},\n })\n );\n }\n }\n\n previousPalette() {\n if (this.canDecreasePalette) {\n const palettes = this.availablePalettes;\n const idx = palettes.indexOf(this.palette);\n this.palette = palettes[idx - 1];\n this.dispatchEvent(\n new CustomEvent('palette-changed', {\n detail: {value: this.palette},\n })\n );\n }\n }\n\n renderBrightness() {\n const title =\n this.variant === ObcBrillianceMenuVariant.tabbed\n ? nothing\n : html`<div class=\"title-container\">\n <h3>${msg('Brilliance')}</h3>\n </div>`;\n const valueLength =\n this.brightness.toString().length + 0.5 * this.brightnessUnit.length;\n\n return html`${title}\n <div class=\"content-container brilliance\">\n ${\n this.variant === ObcBrillianceMenuVariant.compact\n ? html` <obc-slider\n value=${this.brightness}\n @value=${this.handleBrightnessChanged}\n min=\"0\"\n max=${this.brightnessMax}\n variant=${ObcSliderVariant.Normal}\n haslefticon\n hasrighticon\n >\n <obi-display-brilliance-low\n slot=\"icon-left\"\n ></obi-display-brilliance-low>\n <obi-display-brilliance-proposal\n slot=\"icon-right\"\n ></obi-display-brilliance-proposal>\n </obc-slider>`\n : html`\n <div class=\"value-container\">\n <div class=\"value-label-container\">\n <obi-display-brilliance-proposal\n class=\"icon\"\n ></obi-display-brilliance-proposal>\n <div\n class=\"label-container\"\n style=\"width: ${valueLength}ch\"\n >\n <div class=\"value\">${this.brightness.toFixed(0)}</div>\n <div class=\"unit\">${this.brightnessUnit}</div>\n </div>\n </div>\n <div class=\"value-slider-container\">\n ${\n this.brightnessInputVariant ===\n ObcBrillianceInputVariant.buttons\n ? html`\n <obc-slider\n value=${this.brightness}\n variant=${ObcSliderVariant.NoInput}\n min=\"0\"\n max=${this.brightnessMax}\n ></obc-slider>\n `\n : html`\n <obc-slider\n value=${this.brightness}\n variant=${ObcSliderVariant.Enhanced}\n @value=${this.handleBrightnessChanged}\n min=\"0\"\n max=${this.brightnessMax}\n ></obc-slider>\n `\n }\n </div>\n </div>\n ${\n this.brightnessInputVariant ===\n ObcBrillianceInputVariant.buttons\n ? html`\n <div class=\"icon-button-container\">\n <obc-button\n segmentPosition=\"start\"\n fullWidth\n ?disabled=${!this.canDecreaseBrightness}\n class=${this.canDecreaseBrightness ? '' : 'disabled'}\n @click=${() =>\n this.increaseBrightness(\n -this.brightnessMajorStep\n )}\n >\n <obi-chevron-double-left-google\n class=\"btn-icon\"\n ></obi-chevron-double-left-google>\n </obc-button>\n <obc-button\n segmentPosition=\"middle\"\n fullWidth\n ?disabled=${!this.canDecreaseBrightness}\n class=${this.canDecreaseBrightness ? '' : 'disabled'}\n @click=${() =>\n this.increaseBrightness(\n -this.brightnessMinorStep\n )}\n >\n <obi-chevron-left-google\n class=\"btn-icon\"\n ></obi-chevron-left-google>\n </obc-button>\n <obc-button\n segmentPosition=\"middle\"\n fullWidth\n ?disabled=${!this.canIncreaseBrightness}\n class=${this.canIncreaseBrightness ? '' : 'disabled'}\n @click=${() =>\n this.increaseBrightness(this.brightnessMinorStep)}\n >\n <obi-chevron-right-google\n class=\"btn-icon\"\n ></obi-chevron-right-google>\n </obc-button>\n <obc-button\n segmentPosition=\"end\"\n fullWidth\n ?disabled=${!this.canIncreaseBrightness}\n class=${this.canIncreaseBrightness ? '' : 'disabled'}\n @click=${() =>\n this.increaseBrightness(this.brightnessMajorStep)}\n >\n <obi-chevron-double-right-google\n class=\"btn-icon\"\n ></obi-chevron-double-right-google>\n </obc-button>\n </div>\n `\n : nothing\n }\n `\n }\n ${\n this.showLinkBrightness\n ? html`<obc-toggle-switch\n .label=\"${msg('Link')}\"\n hasicon\n @input=${this.onLinkBrightnessChanged}\n >\n <obi-link slot=\"icon\"></obi-link>\n </obc-toggle-switch>`\n : nothing\n }\n </div>`;\n }\n\n get effectivePalette() {\n const palettes = this.availablePalettes;\n return palettes.includes(this.palette) ? this.palette : palettes[0];\n }\n\n get paletteIcon() {\n if (this.effectivePalette === ObcPalette.night) {\n return html`<obi-palette-night class=\"icon\"></obi-palette-night>`;\n } else if (this.effectivePalette === ObcPalette.dusk) {\n return html`<obi-palette-dusk class=\"icon\"></obi-palette-dusk>`;\n } else if (this.effectivePalette === ObcPalette.day) {\n return html`<obi-palette-day class=\"icon\"></obi-palette-day>`;\n } else if (this.effectivePalette === ObcPalette.bright) {\n return html`<obi-palette-day-bright\n class=\"icon\"\n ></obi-palette-day-bright>`;\n } else {\n return nothing;\n }\n }\n\n private paletteOptions(): HTMLTemplateResult[] {\n const out = [];\n if (this.showNightPalette)\n out.push(\n html`<obc-toggle-button-option value=\"night\" type=\"icon\">\n <obi-palette-night slot=\"icon\"></obi-palette-night>\n </obc-toggle-button-option>`\n );\n if (this.showDuskPalette)\n out.push(\n html`<obc-toggle-button-option value=\"dusk\" type=\"icon\">\n <obi-palette-dusk slot=\"icon\"></obi-palette-dusk>\n </obc-toggle-button-option>`\n );\n if (this.showDayPalette)\n out.push(\n html`<obc-toggle-button-option value=\"day\" type=\"icon\">\n <obi-palette-day slot=\"icon\"></obi-palette-day>\n </obc-toggle-button-option>`\n );\n if (this.showBrightPalette)\n out.push(\n html`<obc-toggle-button-option value=\"bright\" type=\"icon\">\n <obi-palette-day-bright slot=\"icon\"></obi-palette-day-bright>\n </obc-toggle-button-option>`\n );\n return out;\n }\n\n renderPalette() {\n const palettes = this.availablePalettes;\n if (palettes.length === 0) return nothing;\n\n const paletteNames: Record<ObcPalette, string> = {\n [ObcPalette.night]: msg('Night'),\n [ObcPalette.dusk]: msg('Dusk'),\n [ObcPalette.day]: msg('Day'),\n [ObcPalette.bright]: msg('Bright'),\n };\n const currentPaletteName = paletteNames[this.effectivePalette];\n const valueLength = currentPaletteName.length;\n const index = palettes.indexOf(this.effectivePalette);\n const nextIndex = Math.min(index + 1, palettes.length - 1);\n const previousIndex = Math.max(index - 1, 0);\n const nextPalette = paletteNames[palettes[nextIndex]];\n const previousPalette = paletteNames[palettes[previousIndex]];\n\n return html`\n ${\n this.variant === ObcBrillianceMenuVariant.tabbed\n ? nothing\n : html`\n <div class=\"title-container\">\n <h3>${msg('Day')}/${msg('Night')}</h3>\n </div>\n `\n }\n <div\n class=\"content-container palette ${\n this.showLinkPalette ? 'with-link' : 'without-link'\n }\"\n >\n ${\n this.variant === ObcBrillianceMenuVariant.compact\n ? html` <obc-toggle-button-group\n aria-label=${`${msg('Day')}/${msg('Night')}`}\n value=${this.effectivePalette}\n @value=${this.onPaletteChanged}\n variant=${ObcToggleButtonOptionVariant.regular}\n type=${ObcToggleButtonOptionType.icon}\n >\n ${this.paletteOptions()}\n </obc-toggle-button-group>`\n : html`\n <div class=\"value-container\">\n <div class=\"value-label-container\">\n ${this.paletteIcon}\n <div\n class=\"label-container\"\n style=\"width: ${valueLength}ch\"\n >\n <div class=\"value\">${currentPaletteName}</div>\n </div>\n </div>\n <obc-progress-indicator-dots\n .totalSteps=${palettes.length}\n .currentStep=${index + 1}\n ></obc-progress-indicator-dots>\n </div>\n <div class=\"icon-button-container\">\n <obc-button\n segmentPosition=\"start\"\n fullWidth\n showLeadingIcon\n ?disabled=${!this.canDecreasePalette}\n class=${this.canDecreasePalette ? '' : 'disabled'}\n @click=${() => this.previousPalette()}\n >\n ${previousPalette}\n <obi-chevron-left-google\n slot=\"leading-icon\"\n ></obi-chevron-left-google>\n </obc-button>\n\n <obc-button\n segmentPosition=\"end\"\n fullWidth\n showTrailingIcon\n ?disabled=${!this.canIncreasePalette}\n class=${this.canIncreasePalette ? '' : 'disabled'}\n @click=${() => this.nextPalette()}\n >\n ${nextPalette}\n <obi-chevron-right-google\n slot=\"trailing-icon\"\n ></obi-chevron-right-google>\n </obc-button>\n </div>\n `\n }\n ${\n this.showLinkPalette\n ? html`<obc-toggle-switch\n .label=\"${msg('Link')}\"\n hasicon\n @input=${this.onLinkPaletteChanged}\n >\n <obi-link slot=\"icon\"></obi-link>\n </obc-toggle-switch>`\n : nothing\n }\n </div>\n `;\n }\n\n renderScreenControlLink() {\n if (this.showScreenControlLink || this.showAdditionalScreenControls) {\n return html`\n <div class=\"footer\">\n ${\n this.showScreenControlLink\n ? html`\n <obc-navigation-item\n .label=\"${msg('Screen Control')}\"\n @click=${() => this.handleScreenControlLinkClicked()}\n hasicon\n >\n <obc-user-button\n slot=\"icon\"\n static\n variant=\"icon\"\n styleType=\"normal\"\n >\n <obi-screen-desk slot=\"icon\"></obi-screen-desk>\n </obc-user-button>\n </obc-navigation-item>\n `\n : nothing\n }\n ${\n this.showAdditionalScreenControls\n ? html`<slot name=\"additional-screen-controls\"></slot>`\n : nothing\n }\n </div>\n `;\n }\n return nothing;\n }\n\n override render() {\n if (this.variant === ObcBrillianceMenuVariant.tabbed) {\n return html`\n <div class=\"card tabbed\">\n <obc-tab-row\n .tabs=${this.tabs}\n .selectedTabId=${this.selectedTabId}\n .centerContent=${true}\n .hasPanels=${true}\n .label=${msg('Display')}\n @tab-selected=${this.onTabSelected}\n @tab-closed=${stopPropagation}\n @add-new-tab=${stopPropagation}\n >\n <obi-display-brilliance-iec\n slot=\"tab-${BRILLIANCE_TAB_ID}-icon\"\n ></obi-display-brilliance-iec>\n <obi-palette-day-night-iec\n slot=\"tab-${PALETTE_TAB_ID}-icon\"\n ></obi-palette-day-night-iec>\n <div slot=\"tab-${BRILLIANCE_TAB_ID}-panel\">\n ${this.renderBrightness()}\n </div>\n <div slot=\"tab-${PALETTE_TAB_ID}-panel\">\n ${this.renderPalette()}\n </div>\n </obc-tab-row>\n ${this.renderScreenControlLink()}\n </div>\n `;\n } else {\n return html`\n <div class=\"card ${this.variant}\">\n ${this.showBrightness ? this.renderBrightness() : nothing}\n ${\n this.showBrightness && this.showPalette\n ? html`<div class=\"divider\"></div>`\n : nothing\n }\n ${this.showPalette ? this.renderPalette() : nothing}\n ${this.renderScreenControlLink()}\n </div>\n `;\n }\n }\n\n handleScreenControlLinkClicked() {\n this.dispatchEvent(new CustomEvent('screen-control-link-clicked'));\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-brilliance-menu': ObcBrillianceMenu;\n }\n}\n"],"mappings":"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"}
|
|
@@ -82,8 +82,8 @@ export type ObcCommandMenuChangeEvent = CustomEvent<{
|
|
|
82
82
|
* Controls the toggle and visual state.
|
|
83
83
|
* @property showLocation - Whether to display the location slot.
|
|
84
84
|
* If false, the location is omitted from the menu.
|
|
85
|
-
* @property softDismiss -
|
|
86
|
-
* @property open - Whether the menu is showing.
|
|
85
|
+
* @property softDismiss - Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself.
|
|
86
|
+
* @property open - Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.
|
|
87
87
|
* @availableWhen open softDismiss==true
|
|
88
88
|
* @slot command-icon - Main icon representing the current command state.
|
|
89
89
|
* @slot command-status - Status label (e.g., "Joystick", "NO CMD").
|
|
@@ -95,14 +95,14 @@ export type ObcCommandMenuChangeEvent = CustomEvent<{
|
|
|
95
95
|
* @slot toogle-state-no-command-label - Status label when in "no command" state.
|
|
96
96
|
* @slot toogle-state-in-command-icon - Icon for the "in command" state (defaults to `<obi-command-in>`).
|
|
97
97
|
* @fires {CustomEvent<{inCommand: boolean}>} change - Fired when the command state is toggled.
|
|
98
|
-
* @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.
|
|
98
|
+
* @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives; reset the flag you bind to `open` here, or the next click on the button finds it still set and asks a closed menu to close.
|
|
99
99
|
* @beta
|
|
100
100
|
*/
|
|
101
101
|
export declare class ObcCommandMenu extends LitElement {
|
|
102
|
-
/**
|
|
102
|
+
/** Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself. */
|
|
103
103
|
softDismiss: boolean;
|
|
104
104
|
/**
|
|
105
|
-
* Whether the menu is showing.
|
|
105
|
+
* Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.
|
|
106
106
|
*
|
|
107
107
|
* Available when `softDismiss==true`.
|
|
108
108
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-menu.js","names":[],"sources":["../../../src/components/command-menu/command-menu.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './command-menu.css?inline';\nimport '../start-stop-switch/start-stop-switch.js';\nimport '../../icons/icon-command-in.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {ObcStartStopSwitchChangeEvent} from '../start-stop-switch/start-stop-switch.js';\nimport {customElement} from '../../decorator.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\nexport type ObcCommandMenuChangeEvent = CustomEvent<{inCommand: boolean}>;\n\n/**\n * `<obc-command-menu>` – A toggleable command status menu for switching between \"in command\" and \"no command\" states.\n *\n * Displays the current command status, description, and (optionally) location, along with a prominent toggle control for taking or releasing command. The component is designed for scenarios where a user needs to view and change the active command state for a system or station.\n *\n * ---\n *\n * ### Features\n * - **Command State Toggle:** Switch between \"in command\" and \"no command\" states using an integrated toggle (based on `obc-start-stop-switch`).\n * - **Status Display:** Shows a customizable status label, description, and optional location for the current command.\n * - **Icon Support:** Accepts custom icons for command state via slots.\n * - **Customizable Labels:** All action and state labels for the toggle can be customized via slots.\n * - **Visual Feedback:** The component visually distinguishes between \"in command\" and \"no command\" states, including color and icon changes.\n * - **Location Support:** Optionally displays the location of the command if `showLocation` is true.\n *\n * ---\n *\n * ### Usage Guidelines\n * Use `<obc-command-menu>` to present and manage the active command state for a system, device, or station. It is ideal when users need to clearly see the current command status and quickly toggle control. The component is suitable for dashboards, control panels, or any interface where command handover is required.\n *\n * **TODO(designer):** Confirm if there are recommended icons, color schemes, or text length limits for status/description. Clarify if there are any constraints on when to use this component versus other status/toggle components.\n *\n * ---\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |---------------------------------------|-------------------------------|-----------------------------------------------------------------|\n * | `command-icon` | Always | Main icon representing the current command state. |\n * | `command-status` | Always | Status label (e.g., \"Joystick\", \"NO CMD\"). |\n * | `command-description` | Always | Description of the command state (e.g., \"DP\", \"CMD at DP\"). |\n * | `command-location` | `showLocation` is true | Location label for the command (e.g., \"Aft Bridge\"). |\n * | `toogle-action-to-in-command-label` | Always | Label for the action to take command (toggle to \"in command\"). |\n * | `toogle-action-to-no-command-label` | Always | Label for the action to release command (toggle to \"no command\").|\n * | `toogle-state-in-command-label` | Always | Status label when in \"in command\" state. |\n * | `toogle-state-no-command-label` | Always | Status label when in \"no command\" state. |\n * | `toogle-state-in-command-icon` | Always | Icon for the \"in command\" state (defaults to `<obi-command-in>`).|\n *\n * ---\n *\n * ### Properties and Attributes\n * - **`inCommand`** (`boolean`): Whether the menu is in the \"in command\" state. Controls the toggle and visual state. (Default: `false`)\n * - **`showLocation`** (`boolean`): Whether to display the location slot. If `false`, the location is omitted. (Default: `true`)\n *\n * ---\n *\n * ### Events\n * - **`change`** – Fired when the command state is toggled. The event detail contains `{inCommand: boolean}` indicating the new state.\n *\n * ---\n *\n * ### Best Practices & Constraints\n * - Use clear, concise labels for status and actions to ensure quick recognition.\n * - Only display the location if it is relevant to the command context.\n * - Keep only one command menu active per system at a time, so the states cannot conflict.\n * - For accessibility, provide meaningful icons and text in all slots.\n * - **TODO(designer):** Specify if there are any timing, animation, or accessibility requirements for the toggle interaction.\n *\n * ---\n *\n * ### Example\n * ```html\n * <obc-command-menu .inCommand=${true}>\n * <div slot=\"command-icon\"><obi-joystick></obi-joystick></div>\n * <div slot=\"command-status\">Joystick</div>\n * <div slot=\"command-description\">DP</div>\n * <div slot=\"command-location\">Aft Bridge</div>\n * <div slot=\"toogle-action-to-in-command-label\">Take</div>\n * <div slot=\"toogle-action-to-no-command-label\">Release</div>\n * <div slot=\"toogle-state-in-command-label\">In CMD</div>\n * <div slot=\"toogle-state-no-command-label\">DP Aft Bridge</div>\n * </obc-command-menu>\n * ```\n *\n * @property inCommand - Whether the menu is in the \"in command\" state.\n * Controls the toggle and visual state.\n * @property showLocation - Whether to display the location slot.\n * If false, the location is omitted from the menu.\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot command-icon - Main icon representing the current command state.\n * @slot command-status - Status label (e.g., \"Joystick\", \"NO CMD\").\n * @slot command-description - Description of the command state.\n * @slot command-location - Location label for the command (shown if `showLocation` is true).\n * @slot toogle-action-to-in-command-label - Label for the action to take command.\n * @slot toogle-action-to-no-command-label - Label for the action to release command.\n * @slot toogle-state-in-command-label - Status label when in \"in command\" state.\n * @slot toogle-state-no-command-label - Status label when in \"no command\" state.\n * @slot toogle-state-in-command-icon - Icon for the \"in command\" state (defaults to `<obi-command-in>`).\n * @fires {CustomEvent<{inCommand: boolean}>} change - Fired when the command state is toggled.\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.\n * @beta\n */\n@customElement('obc-command-menu')\nexport class ObcCommandMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: Boolean}) inCommand = false;\n\n @property({type: Boolean, attribute: false}) showLocation: boolean = true;\n\n override render() {\n return html`\n <div\n class=${classMap({\n card: true,\n 'in-command': this.inCommand,\n 'no-command': !this.inCommand,\n 'has-location': this.showLocation,\n })}\n >\n <div class=\"title-container\">Command</div>\n <div class=\"command-container\">\n <div class=\"value-container\">\n <div class=\"icon command\">\n <slot name=\"command-icon\"></slot>\n </div>\n <div class=\"value\">\n <div class=\"status\">\n <slot name=\"command-status\"></slot>\n </div>\n <div class=\"description\">\n <div class=\"command-description\">\n <slot name=\"command-description\"></slot>\n </div>\n ${\n this.showLocation\n ? html` <div class=\"divider\"></div>\n <div class=\"command-location\">\n <slot name=\"command-location\"></slot>\n </div>`\n : nothing\n }\n </div>\n </div>\n </div>\n <div class=\"action-container\">\n <obc-start-stop-switch\n @change=${this.onChange}\n .checked=${this.inCommand}\n .size=${'large'}\n >\n <div slot=\"to-checked-action-label\">\n <slot name=\"toogle-action-to-in-command-label\"></slot>\n </div>\n <div slot=\"to-unchecked-action-label\">\n <slot name=\"toogle-action-to-no-command-label\"></slot>\n </div>\n <div slot=\"checked-state-label\">\n <slot name=\"toogle-state-in-command-label\"></slot>\n </div>\n <div slot=\"checked-state-icon\">\n <slot name=\"toogle-state-in-command-icon\">\n <obi-command-in></obi-command-in>\n </slot>\n </div>\n <div slot=\"unchecked-state-label\">\n <slot name=\"toogle-state-no-command-label\"></slot>\n </div>\n </obc-start-stop-switch>\n </div>\n </div>\n </div>\n `;\n }\n\n /**\n * Handles the toggle change event from the start-stop switch and emits a `change` event with the new command state.\n *\n * @fires change\n */\n private onChange(event: ObcStartStopSwitchChangeEvent) {\n // Stop the start-stop-switch's composed event from leaking through\n // our shadow DOM — consumers should only see command-menu's own event.\n event.stopPropagation();\n const newValue = event.detail.checked;\n this.inCommand = newValue;\n this.dispatchEvent(\n new CustomEvent<{inCommand: boolean}>('change', {\n detail: {inCommand: newValue},\n bubbles: true,\n composed: true,\n })\n );\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-command-menu': ObcCommandMenu;\n }\n}\n"],"mappings":";;;;;;;;;;AA0GO,IAAM,iBAAN,MAAM,uBAAuB,WAAW;;;EACJ,KAAA,cAAA;EAEP,KAAA,OAAA;EAES,KAAA,wBAAA,IAAI,kBAAkB,IAAI;EAE9B,KAAA,YAAA;EAE8B,KAAA,eAAA;;CAErE,SAAkB;EAChB,OAAO,IAAI;;gBAEC,SAAS;GACf,MAAM;GACN,cAAc,KAAK;GACnB,cAAc,CAAC,KAAK;GACpB,gBAAgB,KAAK;EACvB,CAAC,EAAE;;;;;;;;;;;;;;;;kBAiBO,KAAK,eACD,IAAI;;;kCAIJ,QACL;;;;;;wBAMO,KAAK,SAAS;yBACb,KAAK,UAAU;sBAClB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;CAwB5B;;;;;;CAOA,SAAiB,OAAsC;EAGrD,MAAM,gBAAgB;EACtB,MAAM,WAAW,MAAM,OAAO;EAC9B,KAAK,YAAY;EACjB,KAAK,cACH,IAAI,YAAkC,UAAU;GAC9C,QAAQ,EAAC,WAAW,SAAQ;GAC5B,SAAS;GACT,UAAU;EACZ,CAAC,CACH;CACF;;EAEyB,KAAA,SAAA,UAAU,oBAAY;;AACjD;AAhGG,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,eAAA,WAAA,eAAA,KAAA,CAAA;AAExB,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,eAAA,WAAA,QAAA,KAAA,CAAA;AAIxB,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,eAAA,WAAA,aAAA,KAAA,CAAA;AAExB,WAAA,CAAA,SAAS;CAAC,MAAM;CAAS,WAAW;AAAK,CAAC,CAAA,GAAA,eAAA,WAAA,gBAAA,KAAA,CAAA;AAV5C,iBAAA,WAAA,CAAA,cAAc,kBAAkB,CAAA,GAAA,cAAA"}
|
|
1
|
+
{"version":3,"file":"command-menu.js","names":[],"sources":["../../../src/components/command-menu/command-menu.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './command-menu.css?inline';\nimport '../start-stop-switch/start-stop-switch.js';\nimport '../../icons/icon-command-in.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {ObcStartStopSwitchChangeEvent} from '../start-stop-switch/start-stop-switch.js';\nimport {customElement} from '../../decorator.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\nexport type ObcCommandMenuChangeEvent = CustomEvent<{inCommand: boolean}>;\n\n/**\n * `<obc-command-menu>` – A toggleable command status menu for switching between \"in command\" and \"no command\" states.\n *\n * Displays the current command status, description, and (optionally) location, along with a prominent toggle control for taking or releasing command. The component is designed for scenarios where a user needs to view and change the active command state for a system or station.\n *\n * ---\n *\n * ### Features\n * - **Command State Toggle:** Switch between \"in command\" and \"no command\" states using an integrated toggle (based on `obc-start-stop-switch`).\n * - **Status Display:** Shows a customizable status label, description, and optional location for the current command.\n * - **Icon Support:** Accepts custom icons for command state via slots.\n * - **Customizable Labels:** All action and state labels for the toggle can be customized via slots.\n * - **Visual Feedback:** The component visually distinguishes between \"in command\" and \"no command\" states, including color and icon changes.\n * - **Location Support:** Optionally displays the location of the command if `showLocation` is true.\n *\n * ---\n *\n * ### Usage Guidelines\n * Use `<obc-command-menu>` to present and manage the active command state for a system, device, or station. It is ideal when users need to clearly see the current command status and quickly toggle control. The component is suitable for dashboards, control panels, or any interface where command handover is required.\n *\n * **TODO(designer):** Confirm if there are recommended icons, color schemes, or text length limits for status/description. Clarify if there are any constraints on when to use this component versus other status/toggle components.\n *\n * ---\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |---------------------------------------|-------------------------------|-----------------------------------------------------------------|\n * | `command-icon` | Always | Main icon representing the current command state. |\n * | `command-status` | Always | Status label (e.g., \"Joystick\", \"NO CMD\"). |\n * | `command-description` | Always | Description of the command state (e.g., \"DP\", \"CMD at DP\"). |\n * | `command-location` | `showLocation` is true | Location label for the command (e.g., \"Aft Bridge\"). |\n * | `toogle-action-to-in-command-label` | Always | Label for the action to take command (toggle to \"in command\"). |\n * | `toogle-action-to-no-command-label` | Always | Label for the action to release command (toggle to \"no command\").|\n * | `toogle-state-in-command-label` | Always | Status label when in \"in command\" state. |\n * | `toogle-state-no-command-label` | Always | Status label when in \"no command\" state. |\n * | `toogle-state-in-command-icon` | Always | Icon for the \"in command\" state (defaults to `<obi-command-in>`).|\n *\n * ---\n *\n * ### Properties and Attributes\n * - **`inCommand`** (`boolean`): Whether the menu is in the \"in command\" state. Controls the toggle and visual state. (Default: `false`)\n * - **`showLocation`** (`boolean`): Whether to display the location slot. If `false`, the location is omitted. (Default: `true`)\n *\n * ---\n *\n * ### Events\n * - **`change`** – Fired when the command state is toggled. The event detail contains `{inCommand: boolean}` indicating the new state.\n *\n * ---\n *\n * ### Best Practices & Constraints\n * - Use clear, concise labels for status and actions to ensure quick recognition.\n * - Only display the location if it is relevant to the command context.\n * - Keep only one command menu active per system at a time, so the states cannot conflict.\n * - For accessibility, provide meaningful icons and text in all slots.\n * - **TODO(designer):** Specify if there are any timing, animation, or accessibility requirements for the toggle interaction.\n *\n * ---\n *\n * ### Example\n * ```html\n * <obc-command-menu .inCommand=${true}>\n * <div slot=\"command-icon\"><obi-joystick></obi-joystick></div>\n * <div slot=\"command-status\">Joystick</div>\n * <div slot=\"command-description\">DP</div>\n * <div slot=\"command-location\">Aft Bridge</div>\n * <div slot=\"toogle-action-to-in-command-label\">Take</div>\n * <div slot=\"toogle-action-to-no-command-label\">Release</div>\n * <div slot=\"toogle-state-in-command-label\">In CMD</div>\n * <div slot=\"toogle-state-no-command-label\">DP Aft Bridge</div>\n * </obc-command-menu>\n * ```\n *\n * @property inCommand - Whether the menu is in the \"in command\" state.\n * Controls the toggle and visual state.\n * @property showLocation - Whether to display the location slot.\n * If false, the location is omitted from the menu.\n * @property softDismiss - Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself.\n * @property open - Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.\n * @availableWhen open softDismiss==true\n * @slot command-icon - Main icon representing the current command state.\n * @slot command-status - Status label (e.g., \"Joystick\", \"NO CMD\").\n * @slot command-description - Description of the command state.\n * @slot command-location - Location label for the command (shown if `showLocation` is true).\n * @slot toogle-action-to-in-command-label - Label for the action to take command.\n * @slot toogle-action-to-no-command-label - Label for the action to release command.\n * @slot toogle-state-in-command-label - Status label when in \"in command\" state.\n * @slot toogle-state-no-command-label - Status label when in \"no command\" state.\n * @slot toogle-state-in-command-icon - Icon for the \"in command\" state (defaults to `<obi-command-in>`).\n * @fires {CustomEvent<{inCommand: boolean}>} change - Fired when the command state is toggled.\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives; reset the flag you bind to `open` here, or the next click on the button finds it still set and asks a closed menu to close.\n * @beta\n */\n@customElement('obc-command-menu')\nexport class ObcCommandMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: Boolean}) inCommand = false;\n\n @property({type: Boolean, attribute: false}) showLocation: boolean = true;\n\n override render() {\n return html`\n <div\n class=${classMap({\n card: true,\n 'in-command': this.inCommand,\n 'no-command': !this.inCommand,\n 'has-location': this.showLocation,\n })}\n >\n <div class=\"title-container\">Command</div>\n <div class=\"command-container\">\n <div class=\"value-container\">\n <div class=\"icon command\">\n <slot name=\"command-icon\"></slot>\n </div>\n <div class=\"value\">\n <div class=\"status\">\n <slot name=\"command-status\"></slot>\n </div>\n <div class=\"description\">\n <div class=\"command-description\">\n <slot name=\"command-description\"></slot>\n </div>\n ${\n this.showLocation\n ? html` <div class=\"divider\"></div>\n <div class=\"command-location\">\n <slot name=\"command-location\"></slot>\n </div>`\n : nothing\n }\n </div>\n </div>\n </div>\n <div class=\"action-container\">\n <obc-start-stop-switch\n @change=${this.onChange}\n .checked=${this.inCommand}\n .size=${'large'}\n >\n <div slot=\"to-checked-action-label\">\n <slot name=\"toogle-action-to-in-command-label\"></slot>\n </div>\n <div slot=\"to-unchecked-action-label\">\n <slot name=\"toogle-action-to-no-command-label\"></slot>\n </div>\n <div slot=\"checked-state-label\">\n <slot name=\"toogle-state-in-command-label\"></slot>\n </div>\n <div slot=\"checked-state-icon\">\n <slot name=\"toogle-state-in-command-icon\">\n <obi-command-in></obi-command-in>\n </slot>\n </div>\n <div slot=\"unchecked-state-label\">\n <slot name=\"toogle-state-no-command-label\"></slot>\n </div>\n </obc-start-stop-switch>\n </div>\n </div>\n </div>\n `;\n }\n\n /**\n * Handles the toggle change event from the start-stop switch and emits a `change` event with the new command state.\n *\n * @fires change\n */\n private onChange(event: ObcStartStopSwitchChangeEvent) {\n // Stop the start-stop-switch's composed event from leaking through\n // our shadow DOM — consumers should only see command-menu's own event.\n event.stopPropagation();\n const newValue = event.detail.checked;\n this.inCommand = newValue;\n this.dispatchEvent(\n new CustomEvent<{inCommand: boolean}>('change', {\n detail: {inCommand: newValue},\n bubbles: true,\n composed: true,\n })\n );\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-command-menu': ObcCommandMenu;\n }\n}\n"],"mappings":";;;;;;;;;;AA0GO,IAAM,iBAAN,MAAM,uBAAuB,WAAW;;;EACJ,KAAA,cAAA;EAEP,KAAA,OAAA;EAES,KAAA,wBAAA,IAAI,kBAAkB,IAAI;EAE9B,KAAA,YAAA;EAE8B,KAAA,eAAA;;CAErE,SAAkB;EAChB,OAAO,IAAI;;gBAEC,SAAS;GACf,MAAM;GACN,cAAc,KAAK;GACnB,cAAc,CAAC,KAAK;GACpB,gBAAgB,KAAK;EACvB,CAAC,EAAE;;;;;;;;;;;;;;;;kBAiBO,KAAK,eACD,IAAI;;;kCAIJ,QACL;;;;;;wBAMO,KAAK,SAAS;yBACb,KAAK,UAAU;sBAClB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;CAwB5B;;;;;;CAOA,SAAiB,OAAsC;EAGrD,MAAM,gBAAgB;EACtB,MAAM,WAAW,MAAM,OAAO;EAC9B,KAAK,YAAY;EACjB,KAAK,cACH,IAAI,YAAkC,UAAU;GAC9C,QAAQ,EAAC,WAAW,SAAQ;GAC5B,SAAS;GACT,UAAU;EACZ,CAAC,CACH;CACF;;EAEyB,KAAA,SAAA,UAAU,oBAAY;;AACjD;AAhGG,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,eAAA,WAAA,eAAA,KAAA,CAAA;AAExB,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,eAAA,WAAA,QAAA,KAAA,CAAA;AAIxB,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,eAAA,WAAA,aAAA,KAAA,CAAA;AAExB,WAAA,CAAA,SAAS;CAAC,MAAM;CAAS,WAAW;AAAK,CAAC,CAAA,GAAA,eAAA,WAAA,gBAAA,KAAA,CAAA;AAV5C,iBAAA,WAAA,CAAA,cAAc,kBAAkB,CAAA,GAAA,cAAA"}
|
|
@@ -221,20 +221,20 @@ export declare enum ContextMenuType {
|
|
|
221
221
|
* @property options - Menu options, each with a unique `value` and a `label`, and optionally an
|
|
222
222
|
* `icon` template for the leading icon, a `level` giving the nesting depth
|
|
223
223
|
* for nested checkboxes, and `children` for a flyout or nested menu.
|
|
224
|
-
* @property softDismiss -
|
|
225
|
-
* @property open - Whether the menu is showing.
|
|
224
|
+
* @property softDismiss - Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself.
|
|
225
|
+
* @property open - Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.
|
|
226
226
|
* @availableWhen open softDismiss==true
|
|
227
227
|
* @slot - Optionally used for custom icons in options (e.g., `<obi-placeholder slot="icon"></obi-placeholder>`)
|
|
228
228
|
* @fires {ObcContextMenuInputChangeEvent} change - Fired when the selection changes.
|
|
229
229
|
* @fires {ObcContextMenuInputItemClickEvent} item-click - Fired when a menu item is clicked.
|
|
230
|
-
* @fires {CustomEvent<void>} close - Fired when the close button is clicked, on `Escape`, and, with `softDismiss` on, when the menu closed on its own from a click outside or another menu opening.
|
|
230
|
+
* @fires {CustomEvent<void>} close - Fired when the close button is clicked, on `Escape`, and, with `softDismiss` on, when the menu closed on its own from a click outside or another menu opening. Reset the flag you bind to `open` here in every case: after a self-dismissal `open` is already `false`, while the close button and `Escape` without `softDismiss` leave `open` as it was and only ask.
|
|
231
231
|
* @beta
|
|
232
232
|
*/
|
|
233
233
|
export declare class ObcContextMenuInput extends LitElement {
|
|
234
|
-
/**
|
|
234
|
+
/** Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself. */
|
|
235
235
|
softDismiss: boolean;
|
|
236
236
|
/**
|
|
237
|
-
* Whether the menu is showing.
|
|
237
|
+
* Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.
|
|
238
238
|
*
|
|
239
239
|
* Available when `softDismiss==true`.
|
|
240
240
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-menu-input.js","names":[],"sources":["../../../src/components/context-menu-input/context-menu-input.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing, TemplateResult} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './context-menu-input.css?inline';\nimport '../../icons/icon-arrow-flyout-google.js';\nimport '../../icons/icon-close-google.js';\nimport '../checkbox-item/checkbox-item.js';\nimport '../navigation-item/navigation-item.js';\nimport {NavigationItemRole} from '../navigation-item/navigation-item.js';\nimport {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';\nimport {customElement} from '../../decorator.js';\nimport {RovingNavigator} from '../../internal/roving-navigator.js';\nimport {clamp} from '../../svghelpers/math.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../icon-button/icon-button.js';\nimport '../navigation-item-group/navigation-item-group.js';\nimport {ObcNavigationItemGroup} from '../navigation-item-group/navigation-item-group.js';\nimport {stopPropagation} from '../../internal/events.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\n/**\n * Event fired when the selection changes in `<obc-context-menu-input>`.\n *\n * @event\n */\nexport type ObcContextMenuInputChangeEvent = CustomEvent<{\n selectedValues: string[];\n selectedOptions: Array<ContextMenuOption>;\n}>;\n\n/**\n * Event fired when a menu item is clicked in `<obc-context-menu-input>`.\n *\n * @event\n */\nexport type ObcContextMenuInputItemClickEvent = CustomEvent<{\n value: string;\n option: ContextMenuOption;\n}>;\n\n/**\n * Represents a single option in the context menu.\n */\nexport interface ContextMenuOption {\n /** Unique value for the option. */\n value: string;\n /** Display label for the option. */\n label: string;\n /** Optional nesting level (for hierarchical/nested options). */\n level?: number;\n /** Optional icon (TemplateResult, e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>`). */\n icon?: TemplateResult;\n /** Optional array of child options (for flyout/nested menus). */\n children?: ContextMenuOption[];\n}\n\n/**\n * Represents a group of columns for multi-with-subtitles variant.\n */\nexport interface ColumnGroup {\n /** Title for the group (displayed as subtitle/header). */\n title: string;\n /** Number of columns in this group. */\n columns: number;\n /** Array of options for this group. */\n options: ContextMenuOption[];\n}\n\n/**\n * Enum of available context menu variants for `<obc-context-menu-input>`.\n * - `Regular`: Single-select navigation menu.\n * - `Checkboxes`: Multi-select with checkboxes.\n * - `NestedCheckboxes`: Multi-select with nested/hierarchical checkboxes.\n * - `Flyout`: Menu with expandable/cascading groups.\n * - `Multi`: Multi-column menu.\n * - `MultiWithSubtitles`: Multi-column menu with group subtitles.\n */\n/** A menu row: `obc-navigation-item` or `obc-checkbox-item`, both with the roving hook. */\ntype MenuItemElement = HTMLElement & {focusable: boolean};\n\nexport enum ContextMenuType {\n Regular = 'regular',\n Checkboxes = 'checkboxes',\n NestedCheckboxes = 'nested-checkboxes',\n Flyout = 'flyout',\n Multi = 'multi',\n MultiWithSubtitles = 'multi-with-subtitles',\n}\n\n/**\n * `<obc-context-menu-input>` – A flexible context menu component for presenting selectable lists, actions, or multi-column menus with support for single or multiple selection, checkboxes, flyout groups, and icons.\n *\n * This component provides a highly configurable menu surface for displaying options, actions, or grouped selections. It supports several variants including regular single-select menus, checkbox lists, nested checkboxes, flyout (cascading) groups, and multi-column layouts with or without group subtitles. Options can include icons and hierarchical nesting.\n *\n * Appears as a popover or dropdown menu, allowing users to select one or more items from a list, optionally organized into columns or groups. Suitable for use as a context menu, dropdown, action menu, or feature selector.\n *\n * ## Features\n *\n * - **Variants:**\n * - **Regular:** Single-select menu with navigation items (optionally with icons).\n * - **Checkboxes:** List of options with checkboxes for multi-selection.\n * - **NestedCheckboxes:** Checkbox list supporting hierarchical/nested options (with indentation).\n * - **Flyout:** Menu with expandable/cascading groups; supports both single and multi-select, and group/child icons.\n * - **Multi:** Multi-column menu for large option sets; supports single or multi-select per column.\n * - **MultiWithSubtitles:** Multi-column menu with group subtitles/headers; each group can have its own set of options and columns.\n *\n * - **Selection Modes:**\n * - Single-select, multi-select, or per-group/column single-select (configurable via `multiSelect` and `selectPerGroup`).\n * - Persistent selection (selected items remain highlighted after interaction).\n *\n * - **Icons:**\n * - Options can display leading icons (e.g., `<obi-placeholder></obi-placeholder>`).\n * - Group headers in flyout and multi-column modes can also include icons.\n *\n * - **Title Bar:**\n * - Optional title bar with customizable text and a close button.\n *\n * - **Column Grouping:**\n * - Multi-column layouts can be grouped with subtitles and custom column counts per group.\n *\n * - **Nested Options:**\n * - Nested checkboxes and flyout groups support hierarchical option structures.\n *\n * - **Accessibility:**\n * - Uses ARIA roles for menu and menuitem.\n *\n * ## Usage Guidelines\n *\n * Use `<obc-context-menu-input>` when you need to present a list of actions or options in a popover, dropdown, or context menu format, especially when:\n * - Options may require icons, grouping, or hierarchical structure.\n * - You need to support both single and multiple selection, including per-group or per-column selection.\n * - The menu may contain a large number of options, requiring multi-column or grouped layouts.\n * - You want to provide a familiar menu or action sheet experience with optional checkboxes or flyout groups.\n *\n * Common use cases include: context menus, dropdown selectors, feature pickers, action menus, filter menus, or any scenario where users need to choose from a structured list of options.\n *\n * **Do not use** for persistent navigation (use a sidebar or navigation menu instead), or for simple single-action buttons.\n *\n * **TODO(designer):** Confirm if there are recommended limits for the number of columns/groups, or best practices for deeply nested options.\n *\n * ## Features and Variants\n *\n * - **Regular:**\n * - Single-select, navigation-style menu with optional icons.\n * - **Checkboxes:**\n * - Multi-select list with checkboxes. Each option can be toggled independently.\n * - **NestedCheckboxes:**\n * - Multi-select with hierarchical/nested options. Indentation reflects nesting level.\n * - **Flyout:**\n * - Groups of options expand into submenus (flyouts). Supports both single and multi-select. Group and child options can have icons.\n * - **Multi:**\n * - Options are distributed across multiple columns. Can be single or multi-select. Optionally restrict to one selection per column.\n * - **MultiWithSubtitles:**\n * - Like Multi, but columns are grouped under subtitles/headers. Each group can have its own column count and options.\n *\n * ## Properties\n *\n * - `type` (`ContextMenuType`): Sets the menu variant. Defaults to `'regular'`.\n * - `options` (`ContextMenuOption[]`): Array of menu options. Each option can have `value`, `label`, optional `icon`, `level` (for nesting), and `children` (for flyout/nested).\n * - `selectedValues` (string[]): Array of currently selected option values.\n * - `hasTitleBar` (boolean): If true, displays a title bar with close button.\n * - `title` (string): Text for the title bar (shown if `hasTitleBar` is true).\n * - `columnGroups` (ColumnGroup[]): Used for `multi-with-subtitles` variant to define groupings and columns.\n * - `itemsPerColumn` (number): Number of options per column in multi-column layouts.\n * - `multiSelect` (boolean): If true, allows multiple selections. Defaults based on variant.\n * - `selectPerGroup` (boolean): If true, restricts selection to one per group/column (used in flyout and multi-column).\n * - `persistSelection` (boolean): If true, keeps selected items highlighted after interaction.\n *\n * ## Keyboard\n * [APG Menu](https://www.w3.org/WAI/ARIA/apg/patterns/menu/): the menu is one\n * tab stop, entered on the selected item or the first one; `Up` and `Down`\n * move between items and stop at the ends, `Home` and `End` jump to them,\n * `Enter` and `Space` select through the item, and `Escape` fires `close`, which\n * is also why the title bar's close button stays out of the tab sequence.\n * Single-select items are `menuitemradio` with `aria-checked` on their\n * control, not on the host; checkbox menus\n * keep their checkboxes and move between them the same way.\n *\n * Left out: wrapping at the ends, and type-ahead. The checkbox variants put\n * `role=\"checkbox\"` items in the menu where the pattern asks for\n * `menuitemcheckbox`. A flyout's header is a plain button without\n * `aria-haspopup` or `aria-expanded`, its children sit in a `group` rather\n * than a nested `menu`, and `Right` and `Left` do not open and close it.\n *\n * ## Events\n *\n * - `change` – Fired when the selection changes.\n * Detail includes the selected values array and the selected option objects.\n * - `item-click` – Fired when a menu item is clicked (even if not changing selection).\n * Detail includes the clicked value and its option object.\n * - `close` – Fired when the close button in the title bar is clicked.\n *\n * ## Best Practices and Constraints\n *\n * - Use icons to help users quickly identify options, especially in long or complex menus.\n * - For multi-column layouts, keep the number of columns manageable to avoid overwhelming users.\n * - Use the `multi-with-subtitles` variant for grouped feature selection or when options need to be categorized.\n * - For nested checkboxes, avoid excessive nesting for clarity.\n * - In flyout menus, use group icons to visually distinguish categories.\n * - Only use the close button if the menu is presented as a modal or overlay that requires explicit dismissal.\n * - For accessibility, ensure all options have clear labels.\n *\n * ## Example\n *\n * ```html\n * <obc-context-menu-input\n * type=\"flyout\"\n * .options=${[\n * {\n * value: 'file',\n * label: 'File',\n * icon: html`<obi-placeholder slot=\"icon\"></obi-placeholder>`,\n * children: [\n * { value: 'new', label: 'New' },\n * { value: 'open', label: 'Open' },\n * { value: 'save', label: 'Save' }\n * ]\n * },\n * { value: 'edit', label: 'Edit' }\n * ]}\n * .selectedValues=${['save']}\n * hasTitleBar\n * title=\"Menu\"\n * ></obc-context-menu-input>\n * ```\n *\n * In this example, a flyout menu is shown with a title bar, group icons, and a selected child option.\n *\n * @property title - Title text displayed in the title bar (if `hasTitleBar` is true).\n * @availableWhen title hasTitleBar==true\n * @property selectedValues - Array of currently selected option values.\n * For multi-select variants, can contain multiple values. For single-select, contains at most one value.\n * @property hasTitleBar - Whether to show a title bar with close button at the top of the menu.\n * If true, displays the `title` property and a close icon button.\n * @property columnGroups - Array of column groups for the `multi-with-subtitles` layout.\n * Each group defines a `title`, `columns` (number of columns in the group), and `options` (array of options for that group).\n * @availableWhen columnGroups type==MultiWithSubtitles\n * @property itemsPerColumn - Number of items per column in multi-column layouts.\n * Used in `multi` and `multi-with-subtitles` variants to control column splitting.\n * @availableWhen itemsPerColumn type in [Multi, MultiWithSubtitles]\n * @property multiSelect - Whether multiple selections are allowed.\n * If not set, defaults to true for checkbox/multi variants, false for regular/flyout.\n * @property selectPerGroup - If true, restricts selection to one option per group or column (used in flyout and multi-column).\n * When enabled, only one option can be selected in each group or column.\n * @property type - Menu variant: `regular` (default) is a single-select navigation menu,\n * `checkboxes` and `nested-checkboxes` are flat and hierarchical\n * multi-select, `flyout` has expandable cascading groups, and `multi` and\n * `multi-with-subtitles` lay the menu out in columns, the latter with group\n * subtitles.\n * @property options - Menu options, each with a unique `value` and a `label`, and optionally an\n * `icon` template for the leading icon, a `level` giving the nesting depth\n * for nested checkboxes, and `children` for a flyout or nested menu.\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot - Optionally used for custom icons in options (e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>`)\n * @fires {ObcContextMenuInputChangeEvent} change - Fired when the selection changes.\n * @fires {ObcContextMenuInputItemClickEvent} item-click - Fired when a menu item is clicked.\n * @fires {CustomEvent<void>} close - Fired when the close button is clicked, on `Escape`, and, with `softDismiss` on, when the menu closed on its own from a click outside or another menu opening.\n * @beta\n */\n@customElement('obc-context-menu-input')\nexport class ObcContextMenuInput extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: String})\n type: ContextMenuType = ContextMenuType.Regular;\n\n @property({type: Array}) options: ContextMenuOption[] = [];\n\n @property({type: Array}) selectedValues: string[] = [];\n\n @property({type: Boolean}) hasTitleBar = false;\n\n @property({type: String}) override title = '';\n\n @property({type: Array}) columnGroups: ColumnGroup[] = [];\n\n @property({type: Number}) itemsPerColumn = 5;\n\n @property({type: Boolean}) multiSelect?: boolean;\n\n @property({type: Boolean, reflect: true}) selectPerGroup?: boolean;\n\n private readonly navigator = new RovingNavigator<MenuItemElement>(\n {\n items: () => this.getMenuItems(),\n preferred: () => this.selectedMenuItem(),\n setFocusable: (item, focusable) => {\n item.focusable = focusable;\n },\n },\n {orientation: 'vertical', wrap: false}\n );\n\n override updated() {\n this.navigator.refresh();\n }\n\n private getMenuItems(): MenuItemElement[] {\n return Array.from(\n this.renderRoot.querySelectorAll<MenuItemElement>(\n '[data-menu-item=\"true\"]'\n )\n ).filter((item) => item.getClientRects().length > 0);\n }\n\n private selectedMenuItem(): MenuItemElement | undefined {\n const items = this.getMenuItems();\n return this.selectedValues\n .map((value) =>\n items.find((item) => item.getAttribute('data-menu-value') === value)\n )\n .find((item): item is MenuItemElement => item !== undefined);\n }\n\n private focusMenuItem(index: number) {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n const item = items[clamp(index, 0, items.length - 1)];\n this.navigator.setActive(item, true);\n item.scrollIntoView({block: 'nearest'});\n }\n\n public focusFirstItem() {\n this.focusMenuItem(0);\n }\n\n public focusLastItem() {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n this.focusMenuItem(items.length - 1);\n }\n\n public focusSelectedItem() {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n const selectedItem = this.selectedMenuItem();\n if (selectedItem !== undefined) {\n this.navigator.setActive(selectedItem, true);\n selectedItem.scrollIntoView({block: 'nearest'});\n return;\n }\n\n this.focusFirstItem();\n }\n\n private handleKeydown(event: KeyboardEvent) {\n if (this.navigator.handleKeydown(event)) {\n event.preventDefault();\n this.navigator.activeItem?.scrollIntoView({block: 'nearest'});\n return;\n }\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n // Focus is on the menu itself, not on an item: the arrows enter the list.\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.focusFirstItem();\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusLastItem();\n break;\n case 'Home':\n event.preventDefault();\n this.focusFirstItem();\n break;\n case 'End':\n event.preventDefault();\n this.focusLastItem();\n break;\n case 'Escape':\n // With softDismiss on, the browser closes the menu on Escape by\n // itself. Blocking the default here would stop that and leave the\n // menu open.\n if (this.softDismiss) break;\n event.preventDefault();\n this.dispatchEvent(new CustomEvent('close'));\n break;\n default:\n break;\n }\n }\n\n private get isMultiSelect(): boolean {\n if (this.multiSelect !== undefined) return this.multiSelect;\n return [\n ContextMenuType.Checkboxes,\n ContextMenuType.NestedCheckboxes,\n ContextMenuType.Multi,\n ContextMenuType.MultiWithSubtitles,\n ].includes(this.type);\n }\n\n private get isPerGroupSingleSelect(): boolean {\n if (this.isMultiSelect) return false;\n if (this.selectPerGroup !== undefined) return this.selectPerGroup;\n return this.type === ContextMenuType.Flyout;\n }\n\n /**\n * Returns a unique group-key for each option:\n * - In multi-with-subtitles: group title + subcolumn index (each subcolumn is a group)\n * - In multi: column index (each column is a group)\n */\n private getGroupForValue(value: string): string | undefined {\n if (\n this.type === ContextMenuType.MultiWithSubtitles &&\n this.columnGroups.length\n ) {\n for (const group of this.columnGroups) {\n const totalCols = Math.max(\n group.columns,\n Math.ceil(group.options.length / this.itemsPerColumn)\n );\n const distributed = this.chunkArray(\n group.options,\n this.itemsPerColumn,\n totalCols\n );\n for (let subColIdx = 0; subColIdx < distributed.length; ++subColIdx) {\n if (distributed[subColIdx].some((opt) => opt.value === value)) {\n return `${group.title}___${subColIdx}`;\n }\n }\n }\n return undefined;\n }\n if (this.type === ContextMenuType.Multi && this.itemsPerColumn > 0) {\n const columns = this.chunkArray(this.options, this.itemsPerColumn);\n for (let colIdx = 0; colIdx < columns.length; ++colIdx) {\n if (columns[colIdx].some((opt) => opt.value === value)) {\n return `column-${colIdx}`;\n }\n }\n return undefined;\n }\n if (this.type === ContextMenuType.Flyout && this.options.length) {\n for (const group of this.options) {\n if (group.children?.some((child) => child.value === value)) {\n return group.value;\n }\n if (group.value === value) return group.value;\n }\n return undefined;\n }\n return undefined;\n }\n\n private handleCheckboxChange(option: ContextMenuOption, e: Event) {\n const {status} = (e as CustomEvent<{status: 'checked' | 'unchecked'}>)\n .detail;\n let next: string[];\n\n // Enable \"one per group/column\" for multi-column layouts as well\n if (\n this.selectPerGroup &&\n (this.type === ContextMenuType.Multi ||\n this.type === ContextMenuType.MultiWithSubtitles)\n ) {\n const groupKey = this.getGroupForValue(option.value);\n next = [\n ...this.selectedValues.filter(\n (val) => this.getGroupForValue(val) !== groupKey\n ),\n ...(status === 'checked' ? [option.value] : []),\n ];\n } else {\n next =\n status === 'checked'\n ? [...this.selectedValues, option.value]\n : this.selectedValues.filter((v) => v !== option.value);\n }\n\n if (!arraysEqual(this.selectedValues, next)) this.updateSelection(next);\n }\n\n private handleMenuItemClick(option: ContextMenuOption, event: Event) {\n event.preventDefault();\n\n // Always fire item-click event, even for groups\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputItemClickEvent['detail']>(\n 'item-click',\n {\n detail: {value: option.value, option},\n }\n )\n );\n\n // Don't process selection for navigation groups in flyout menus or multi\n if (option.children?.length) return;\n\n let newSelectedValues: string[];\n\n if (this.isPerGroupSingleSelect) {\n // Get the group key for this value (column or group)\n const groupKey = this.getGroupForValue\n ? this.getGroupForValue(option.value)\n : undefined;\n\n // Find currently selected in this group\n const selectedInGroup = this.selectedValues.find(\n (val) => this.getGroupForValue(val) === groupKey\n );\n\n // If the clicked option is already selected in this group, unselect it\n if (selectedInGroup === option.value) {\n newSelectedValues = this.selectedValues.filter(\n (val) => val !== option.value\n );\n } else {\n // Otherwise, replace any existing selection in the group with this one\n newSelectedValues = [\n ...this.selectedValues.filter(\n (val) => this.getGroupForValue(val) !== groupKey\n ),\n option.value,\n ];\n }\n } else {\n // REGULAR (single select, non-grouped): toggle if already selected\n if (this.selectedValues.includes(option.value)) {\n newSelectedValues = [];\n } else {\n newSelectedValues = [option.value];\n }\n }\n\n if (!arraysEqual(this.selectedValues, newSelectedValues))\n this.updateSelection(newSelectedValues);\n }\n\n private updateSelection(vals: string[]) {\n this.selectedValues = vals;\n const selectedOptions: ContextMenuOption[] = [];\n const collect = (arr: ContextMenuOption[]) =>\n arr.forEach((o) => {\n if (vals.includes(o.value)) selectedOptions.push(o);\n if (o.children) collect(o.children);\n });\n collect(this.options);\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputChangeEvent['detail']>('change', {\n detail: {selectedValues: vals, selectedOptions},\n })\n );\n }\n\n private handleCloseClick(e: Event) {\n e.preventDefault();\n this.dispatchEvent(new CustomEvent('close'));\n }\n\n private isOptionSelected(v: string) {\n return this.selectedValues.includes(v);\n }\n\n private renderTitleBar() {\n if (!this.hasTitleBar) return nothing;\n return html`\n <div class=\"title-container\">\n <div class=\"title-content\">\n <div class=\"title-text\">${this.title}</div>\n </div>\n <obc-icon-button\n variant=\"flat\"\n @click=${this.handleCloseClick}\n aria-label=\"Close menu\"\n .focusable=${false}\n >\n <obi-close-google></obi-close-google>\n </obc-icon-button>\n </div>\n `;\n }\n\n private renderRegularItems() {\n return this.options.map((o) => this.renderNavItem(o));\n }\n\n private renderCheckboxItems() {\n return this.options.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n const isNested =\n this.type === ContextMenuType.NestedCheckboxes &&\n o.level &&\n o.level > 1;\n const indent = isNested ? (o.level! - 1) * 16 : 0;\n return html`<div\n class=\"menu-item checkbox-item-wrapper\"\n style=${indent ? `padding-left:${indent}px` : ''}\n >\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(o, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n\n private renderNavItem(o: ContextMenuOption) {\n const isSelected = this.isOptionSelected(o.value);\n const indent = o.level ? (o.level - 1) * 16 : 0;\n return html`<div\n class=\"menu-item navigation-item-wrapper\"\n style=${indent ? `padding-left:${indent}px` : ''}\n >\n <obc-navigation-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n @click=${(e: Event) => this.handleMenuItemClick(o, e)}\n .itemRole=${NavigationItemRole.MenuItemRadio}\n ?hasIcon=${!!o.icon}\n >\n ${o.icon ? html`<div slot=\"icon\">${o.icon}</div>` : nothing}\n </obc-navigation-item>\n </div>`;\n }\n\n // Renders checkboxes for children if multi, otherwise navigation items\n private renderFlyoutChildren(children: ContextMenuOption[]) {\n if (this.isMultiSelect) {\n return children.map((c) => {\n const isSelected = this.isOptionSelected(c.value);\n return html`<div class=\"menu-item checkbox-item-wrapper\">\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${c.value}\n .label=${c.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(c, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n return children.map((c) => {\n const isSelected = this.isOptionSelected(c.value);\n return html`<obc-navigation-item\n data-menu-item=\"true\"\n data-menu-value=${c.value}\n .label=${c.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n @click=${(e: Event) => this.handleMenuItemClick(c, e)}\n .itemRole=${NavigationItemRole.MenuItemRadio}\n ?hasIcon=${!!c.icon}\n >\n ${c.icon ? html`<div slot=\"icon\">${c.icon}</div>` : nothing}\n </obc-navigation-item>`;\n });\n }\n\n /**\n * Rows a group shows or hides join or leave the roving set only once the\n * group has rendered; until then a newly shown row is its own tab stop.\n */\n private async refreshAfterDisclosure(group: ObcNavigationItemGroup) {\n await group.updateComplete;\n await this.updateComplete;\n this.navigator.refresh();\n }\n\n private handleFlyoutGroupClick(option: ContextMenuOption, event: Event) {\n event.preventDefault();\n this.refreshAfterDisclosure(event.currentTarget as ObcNavigationItemGroup);\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputItemClickEvent['detail']>(\n 'item-click',\n {\n detail: {value: option.value, option},\n }\n )\n );\n // Don't fire a change event for navigation groups\n }\n\n private renderFlyoutItems() {\n return this.options.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n if (o.children?.length) {\n return html`<obc-navigation-item-group\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n .hug=${true}\n .hasIcon=${!!o.icon}\n @click=${(e: Event) => this.handleFlyoutGroupClick(o, e)}\n @open=${(e: Event) => {\n this.shadowRoot\n ?.querySelectorAll('obc-navigation-item-group')\n .forEach((g) => {\n const group = g as ObcNavigationItemGroup;\n if (group.label !== o.label) group.close();\n });\n this.refreshAfterDisclosure(\n e.currentTarget as ObcNavigationItemGroup\n );\n }}\n >\n ${o.icon ? html`<div slot=\"icon\">${o.icon}</div>` : nothing}\n ${this.renderFlyoutChildren(o.children)}\n </obc-navigation-item-group>`;\n }\n return this.renderNavItem(o);\n });\n }\n\n // --------- MULTI COLUMN ---------\n\n private renderMultiColumnItems() {\n const renderColumn = (columnOptions: ContextMenuOption[]) => {\n if (!columnOptions.length) return nothing;\n\n // True multi-select: checkboxes\n if (this.isMultiSelect && !this.selectPerGroup) {\n return columnOptions.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n return html`<div class=\"menu-item checkbox-item-wrapper\">\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(o, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n // fallback: nav item\n return columnOptions.map((opt) => this.renderNavItem(opt));\n };\n\n if (this.type === ContextMenuType.MultiWithSubtitles) {\n if (!this.columnGroups.length) {\n // Fallback – evenly spread across columns\n const cols = this.chunkArray(this.options, this.itemsPerColumn);\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n <div class=\"columns-container\">\n ${cols.map(\n (col, idx) =>\n html`<div\n class=\"column-with-header ${idx ? 'column-divider' : ''}\"\n >\n <div class=\"column-header\">\n <div class=\"subtitle-container\">\n <div class=\"subtitle-text\">Group ${idx + 1}</div>\n </div>\n </div>\n <div class=\"column-content\">${renderColumn(col)}</div>\n </div>`\n )}\n </div>\n </div>\n </div>`;\n }\n\n interface ColumnInfo {\n options: ContextMenuOption[];\n groupTitle: string;\n isFirstInGroup: boolean;\n isFirstGroup: boolean;\n colIdx: number;\n }\n\n const allCols: ColumnInfo[] = [];\n this.columnGroups.forEach((g, gIdx) => {\n const calculatedCols = Math.ceil(\n g.options.length / this.itemsPerColumn\n );\n const actualCols = Math.max(g.columns, calculatedCols);\n const distributed = this.chunkArray(\n g.options,\n this.itemsPerColumn,\n actualCols\n );\n distributed.forEach((opts, idx) => {\n allCols.push({\n options: opts,\n groupTitle: g.title,\n isFirstInGroup: idx === 0,\n isFirstGroup: gIdx === 0,\n colIdx: idx,\n });\n });\n });\n\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n <div class=\"columns-container\">\n ${allCols.map(\n (c) =>\n html`<div\n class=\"column-with-header ${\n !c.isFirstGroup && c.isFirstInGroup ? 'column-divider' : ''\n }\"\n >\n ${\n c.isFirstInGroup\n ? html`<div class=\"column-header\">\n <div class=\"subtitle-container\">\n <div class=\"subtitle-text\">${c.groupTitle}</div>\n </div>\n </div>`\n : html`<div class=\"column-header-spacer\"></div>`\n }\n <div class=\"column-content\">${renderColumn(c.options)}</div>\n </div>`\n )}\n </div>\n </div>\n </div>`;\n }\n\n // Simple multi (no subtitles)\n const columns = this.chunkArray(this.options, this.itemsPerColumn);\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n ${columns.map(\n (col, idx) =>\n html`<div class=\"column ${idx ? 'column-divider' : ''}\">\n ${renderColumn(col)}\n </div>`\n )}\n </div>\n </div>`;\n }\n\n private chunkArray<T>(arr: T[], size: number, forcedColumns?: number): T[][] {\n if (forcedColumns) {\n const out: T[][] = Array.from({length: forcedColumns}, () => []);\n arr.forEach((item, idx) => out[Math.floor(idx / size)].push(item));\n return out;\n }\n const result: T[][] = [];\n for (let i = 0; i < arr.length; i += size)\n result.push(arr.slice(i + 0, i + size));\n return result;\n }\n\n private renderMenuContent() {\n switch (this.type) {\n case ContextMenuType.Checkboxes:\n case ContextMenuType.NestedCheckboxes:\n return this.renderCheckboxItems();\n case ContextMenuType.Flyout:\n return this.renderFlyoutItems();\n case ContextMenuType.Multi:\n case ContextMenuType.MultiWithSubtitles:\n return this.renderMultiColumnItems();\n default:\n return this.renderRegularItems();\n }\n }\n\n override render() {\n return html`<div\n class=${classMap({\n 'context-menu': true,\n [`type-${this.type}`]: true,\n 'has-title': this.hasTitleBar,\n })}\n tabindex=\"-1\"\n role=\"menu\"\n aria-label=${this.hasTitleBar ? this.title : 'Context menu'}\n @keydown=${this.handleKeydown}\n @focusin=${(event: Event) => this.navigator.handleFocusin(event)}\n >\n ${this.renderTitleBar()}\n <div class=\"menu-content\">${this.renderMenuContent()}</div>\n </div>`;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\nfunction arraysEqual(a: string[], b: string[]) {\n if (a.length !== b.length) return false;\n const setA = new Set(a);\n return b.every((v) => setA.has(v));\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-context-menu-input': ObcContextMenuInput;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"context-menu-input.js","names":[],"sources":["../../../src/components/context-menu-input/context-menu-input.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing, TemplateResult} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './context-menu-input.css?inline';\nimport '../../icons/icon-arrow-flyout-google.js';\nimport '../../icons/icon-close-google.js';\nimport '../checkbox-item/checkbox-item.js';\nimport '../navigation-item/navigation-item.js';\nimport {NavigationItemRole} from '../navigation-item/navigation-item.js';\nimport {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';\nimport {customElement} from '../../decorator.js';\nimport {RovingNavigator} from '../../internal/roving-navigator.js';\nimport {clamp} from '../../svghelpers/math.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../icon-button/icon-button.js';\nimport '../navigation-item-group/navigation-item-group.js';\nimport {ObcNavigationItemGroup} from '../navigation-item-group/navigation-item-group.js';\nimport {stopPropagation} from '../../internal/events.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\n/**\n * Event fired when the selection changes in `<obc-context-menu-input>`.\n *\n * @event\n */\nexport type ObcContextMenuInputChangeEvent = CustomEvent<{\n selectedValues: string[];\n selectedOptions: Array<ContextMenuOption>;\n}>;\n\n/**\n * Event fired when a menu item is clicked in `<obc-context-menu-input>`.\n *\n * @event\n */\nexport type ObcContextMenuInputItemClickEvent = CustomEvent<{\n value: string;\n option: ContextMenuOption;\n}>;\n\n/**\n * Represents a single option in the context menu.\n */\nexport interface ContextMenuOption {\n /** Unique value for the option. */\n value: string;\n /** Display label for the option. */\n label: string;\n /** Optional nesting level (for hierarchical/nested options). */\n level?: number;\n /** Optional icon (TemplateResult, e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>`). */\n icon?: TemplateResult;\n /** Optional array of child options (for flyout/nested menus). */\n children?: ContextMenuOption[];\n}\n\n/**\n * Represents a group of columns for multi-with-subtitles variant.\n */\nexport interface ColumnGroup {\n /** Title for the group (displayed as subtitle/header). */\n title: string;\n /** Number of columns in this group. */\n columns: number;\n /** Array of options for this group. */\n options: ContextMenuOption[];\n}\n\n/**\n * Enum of available context menu variants for `<obc-context-menu-input>`.\n * - `Regular`: Single-select navigation menu.\n * - `Checkboxes`: Multi-select with checkboxes.\n * - `NestedCheckboxes`: Multi-select with nested/hierarchical checkboxes.\n * - `Flyout`: Menu with expandable/cascading groups.\n * - `Multi`: Multi-column menu.\n * - `MultiWithSubtitles`: Multi-column menu with group subtitles.\n */\n/** A menu row: `obc-navigation-item` or `obc-checkbox-item`, both with the roving hook. */\ntype MenuItemElement = HTMLElement & {focusable: boolean};\n\nexport enum ContextMenuType {\n Regular = 'regular',\n Checkboxes = 'checkboxes',\n NestedCheckboxes = 'nested-checkboxes',\n Flyout = 'flyout',\n Multi = 'multi',\n MultiWithSubtitles = 'multi-with-subtitles',\n}\n\n/**\n * `<obc-context-menu-input>` – A flexible context menu component for presenting selectable lists, actions, or multi-column menus with support for single or multiple selection, checkboxes, flyout groups, and icons.\n *\n * This component provides a highly configurable menu surface for displaying options, actions, or grouped selections. It supports several variants including regular single-select menus, checkbox lists, nested checkboxes, flyout (cascading) groups, and multi-column layouts with or without group subtitles. Options can include icons and hierarchical nesting.\n *\n * Appears as a popover or dropdown menu, allowing users to select one or more items from a list, optionally organized into columns or groups. Suitable for use as a context menu, dropdown, action menu, or feature selector.\n *\n * ## Features\n *\n * - **Variants:**\n * - **Regular:** Single-select menu with navigation items (optionally with icons).\n * - **Checkboxes:** List of options with checkboxes for multi-selection.\n * - **NestedCheckboxes:** Checkbox list supporting hierarchical/nested options (with indentation).\n * - **Flyout:** Menu with expandable/cascading groups; supports both single and multi-select, and group/child icons.\n * - **Multi:** Multi-column menu for large option sets; supports single or multi-select per column.\n * - **MultiWithSubtitles:** Multi-column menu with group subtitles/headers; each group can have its own set of options and columns.\n *\n * - **Selection Modes:**\n * - Single-select, multi-select, or per-group/column single-select (configurable via `multiSelect` and `selectPerGroup`).\n * - Persistent selection (selected items remain highlighted after interaction).\n *\n * - **Icons:**\n * - Options can display leading icons (e.g., `<obi-placeholder></obi-placeholder>`).\n * - Group headers in flyout and multi-column modes can also include icons.\n *\n * - **Title Bar:**\n * - Optional title bar with customizable text and a close button.\n *\n * - **Column Grouping:**\n * - Multi-column layouts can be grouped with subtitles and custom column counts per group.\n *\n * - **Nested Options:**\n * - Nested checkboxes and flyout groups support hierarchical option structures.\n *\n * - **Accessibility:**\n * - Uses ARIA roles for menu and menuitem.\n *\n * ## Usage Guidelines\n *\n * Use `<obc-context-menu-input>` when you need to present a list of actions or options in a popover, dropdown, or context menu format, especially when:\n * - Options may require icons, grouping, or hierarchical structure.\n * - You need to support both single and multiple selection, including per-group or per-column selection.\n * - The menu may contain a large number of options, requiring multi-column or grouped layouts.\n * - You want to provide a familiar menu or action sheet experience with optional checkboxes or flyout groups.\n *\n * Common use cases include: context menus, dropdown selectors, feature pickers, action menus, filter menus, or any scenario where users need to choose from a structured list of options.\n *\n * **Do not use** for persistent navigation (use a sidebar or navigation menu instead), or for simple single-action buttons.\n *\n * **TODO(designer):** Confirm if there are recommended limits for the number of columns/groups, or best practices for deeply nested options.\n *\n * ## Features and Variants\n *\n * - **Regular:**\n * - Single-select, navigation-style menu with optional icons.\n * - **Checkboxes:**\n * - Multi-select list with checkboxes. Each option can be toggled independently.\n * - **NestedCheckboxes:**\n * - Multi-select with hierarchical/nested options. Indentation reflects nesting level.\n * - **Flyout:**\n * - Groups of options expand into submenus (flyouts). Supports both single and multi-select. Group and child options can have icons.\n * - **Multi:**\n * - Options are distributed across multiple columns. Can be single or multi-select. Optionally restrict to one selection per column.\n * - **MultiWithSubtitles:**\n * - Like Multi, but columns are grouped under subtitles/headers. Each group can have its own column count and options.\n *\n * ## Properties\n *\n * - `type` (`ContextMenuType`): Sets the menu variant. Defaults to `'regular'`.\n * - `options` (`ContextMenuOption[]`): Array of menu options. Each option can have `value`, `label`, optional `icon`, `level` (for nesting), and `children` (for flyout/nested).\n * - `selectedValues` (string[]): Array of currently selected option values.\n * - `hasTitleBar` (boolean): If true, displays a title bar with close button.\n * - `title` (string): Text for the title bar (shown if `hasTitleBar` is true).\n * - `columnGroups` (ColumnGroup[]): Used for `multi-with-subtitles` variant to define groupings and columns.\n * - `itemsPerColumn` (number): Number of options per column in multi-column layouts.\n * - `multiSelect` (boolean): If true, allows multiple selections. Defaults based on variant.\n * - `selectPerGroup` (boolean): If true, restricts selection to one per group/column (used in flyout and multi-column).\n * - `persistSelection` (boolean): If true, keeps selected items highlighted after interaction.\n *\n * ## Keyboard\n * [APG Menu](https://www.w3.org/WAI/ARIA/apg/patterns/menu/): the menu is one\n * tab stop, entered on the selected item or the first one; `Up` and `Down`\n * move between items and stop at the ends, `Home` and `End` jump to them,\n * `Enter` and `Space` select through the item, and `Escape` fires `close`, which\n * is also why the title bar's close button stays out of the tab sequence.\n * Single-select items are `menuitemradio` with `aria-checked` on their\n * control, not on the host; checkbox menus\n * keep their checkboxes and move between them the same way.\n *\n * Left out: wrapping at the ends, and type-ahead. The checkbox variants put\n * `role=\"checkbox\"` items in the menu where the pattern asks for\n * `menuitemcheckbox`. A flyout's header is a plain button without\n * `aria-haspopup` or `aria-expanded`, its children sit in a `group` rather\n * than a nested `menu`, and `Right` and `Left` do not open and close it.\n *\n * ## Events\n *\n * - `change` – Fired when the selection changes.\n * Detail includes the selected values array and the selected option objects.\n * - `item-click` – Fired when a menu item is clicked (even if not changing selection).\n * Detail includes the clicked value and its option object.\n * - `close` – Fired when the close button in the title bar is clicked.\n *\n * ## Best Practices and Constraints\n *\n * - Use icons to help users quickly identify options, especially in long or complex menus.\n * - For multi-column layouts, keep the number of columns manageable to avoid overwhelming users.\n * - Use the `multi-with-subtitles` variant for grouped feature selection or when options need to be categorized.\n * - For nested checkboxes, avoid excessive nesting for clarity.\n * - In flyout menus, use group icons to visually distinguish categories.\n * - Only use the close button if the menu is presented as a modal or overlay that requires explicit dismissal.\n * - For accessibility, ensure all options have clear labels.\n *\n * ## Example\n *\n * ```html\n * <obc-context-menu-input\n * type=\"flyout\"\n * .options=${[\n * {\n * value: 'file',\n * label: 'File',\n * icon: html`<obi-placeholder slot=\"icon\"></obi-placeholder>`,\n * children: [\n * { value: 'new', label: 'New' },\n * { value: 'open', label: 'Open' },\n * { value: 'save', label: 'Save' }\n * ]\n * },\n * { value: 'edit', label: 'Edit' }\n * ]}\n * .selectedValues=${['save']}\n * hasTitleBar\n * title=\"Menu\"\n * ></obc-context-menu-input>\n * ```\n *\n * In this example, a flyout menu is shown with a title bar, group icons, and a selected child option.\n *\n * @property title - Title text displayed in the title bar (if `hasTitleBar` is true).\n * @availableWhen title hasTitleBar==true\n * @property selectedValues - Array of currently selected option values.\n * For multi-select variants, can contain multiple values. For single-select, contains at most one value.\n * @property hasTitleBar - Whether to show a title bar with close button at the top of the menu.\n * If true, displays the `title` property and a close icon button.\n * @property columnGroups - Array of column groups for the `multi-with-subtitles` layout.\n * Each group defines a `title`, `columns` (number of columns in the group), and `options` (array of options for that group).\n * @availableWhen columnGroups type==MultiWithSubtitles\n * @property itemsPerColumn - Number of items per column in multi-column layouts.\n * Used in `multi` and `multi-with-subtitles` variants to control column splitting.\n * @availableWhen itemsPerColumn type in [Multi, MultiWithSubtitles]\n * @property multiSelect - Whether multiple selections are allowed.\n * If not set, defaults to true for checkbox/multi variants, false for regular/flyout.\n * @property selectPerGroup - If true, restricts selection to one option per group or column (used in flyout and multi-column).\n * When enabled, only one option can be selected in each group or column.\n * @property type - Menu variant: `regular` (default) is a single-select navigation menu,\n * `checkboxes` and `nested-checkboxes` are flat and hierarchical\n * multi-select, `flyout` has expandable cascading groups, and `multi` and\n * `multi-with-subtitles` lay the menu out in columns, the latter with group\n * subtitles.\n * @property options - Menu options, each with a unique `value` and a `label`, and optionally an\n * `icon` template for the leading icon, a `level` giving the nesting depth\n * for nested checkboxes, and `children` for a flyout or nested menu.\n * @property softDismiss - Lets the menu close itself on a click outside it, on `Escape`, or when another menu opens. The page is covered while the menu is open, so the closing click reaches nothing there; only the top bar's strip stays clickable, which is how its buttons switch or close menus in one click. Wire it with three bindings: set `softDismiss`, bind `open` to a flag you keep, and reset that flag on `close`. The button that opens the menu needs no wiring of its own: flip the flag from its click, or from the button event of `obc-top-bar` or `obc-integration-bar`. The user menu's *Soft Dismiss From A Bar Button* story shows that wiring, the brilliance menu's *Soft Dismiss* story the one for a button you hold yourself (`bindPopoverTrigger`), and the vue demo runs its top bar this way. Leave it off to show and hide the menu yourself.\n * @property open - Whether the menu is showing. Bind it to a flag you keep rather than toggling it from the menu's own value: when the menu closes itself, `open` is written back to `false` before the button's click reaches your handler, so `menu.open = !menu.open` gets out of step. Reset the flag on `close`.\n * @availableWhen open softDismiss==true\n * @slot - Optionally used for custom icons in options (e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>`)\n * @fires {ObcContextMenuInputChangeEvent} change - Fired when the selection changes.\n * @fires {ObcContextMenuInputItemClickEvent} item-click - Fired when a menu item is clicked.\n * @fires {CustomEvent<void>} close - Fired when the close button is clicked, on `Escape`, and, with `softDismiss` on, when the menu closed on its own from a click outside or another menu opening. Reset the flag you bind to `open` here in every case: after a self-dismissal `open` is already `false`, while the close button and `Escape` without `softDismiss` leave `open` as it was and only ask.\n * @beta\n */\n@customElement('obc-context-menu-input')\nexport class ObcContextMenuInput extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: String})\n type: ContextMenuType = ContextMenuType.Regular;\n\n @property({type: Array}) options: ContextMenuOption[] = [];\n\n @property({type: Array}) selectedValues: string[] = [];\n\n @property({type: Boolean}) hasTitleBar = false;\n\n @property({type: String}) override title = '';\n\n @property({type: Array}) columnGroups: ColumnGroup[] = [];\n\n @property({type: Number}) itemsPerColumn = 5;\n\n @property({type: Boolean}) multiSelect?: boolean;\n\n @property({type: Boolean, reflect: true}) selectPerGroup?: boolean;\n\n private readonly navigator = new RovingNavigator<MenuItemElement>(\n {\n items: () => this.getMenuItems(),\n preferred: () => this.selectedMenuItem(),\n setFocusable: (item, focusable) => {\n item.focusable = focusable;\n },\n },\n {orientation: 'vertical', wrap: false}\n );\n\n override updated() {\n this.navigator.refresh();\n }\n\n private getMenuItems(): MenuItemElement[] {\n return Array.from(\n this.renderRoot.querySelectorAll<MenuItemElement>(\n '[data-menu-item=\"true\"]'\n )\n ).filter((item) => item.getClientRects().length > 0);\n }\n\n private selectedMenuItem(): MenuItemElement | undefined {\n const items = this.getMenuItems();\n return this.selectedValues\n .map((value) =>\n items.find((item) => item.getAttribute('data-menu-value') === value)\n )\n .find((item): item is MenuItemElement => item !== undefined);\n }\n\n private focusMenuItem(index: number) {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n const item = items[clamp(index, 0, items.length - 1)];\n this.navigator.setActive(item, true);\n item.scrollIntoView({block: 'nearest'});\n }\n\n public focusFirstItem() {\n this.focusMenuItem(0);\n }\n\n public focusLastItem() {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n this.focusMenuItem(items.length - 1);\n }\n\n public focusSelectedItem() {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n const selectedItem = this.selectedMenuItem();\n if (selectedItem !== undefined) {\n this.navigator.setActive(selectedItem, true);\n selectedItem.scrollIntoView({block: 'nearest'});\n return;\n }\n\n this.focusFirstItem();\n }\n\n private handleKeydown(event: KeyboardEvent) {\n if (this.navigator.handleKeydown(event)) {\n event.preventDefault();\n this.navigator.activeItem?.scrollIntoView({block: 'nearest'});\n return;\n }\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n // Focus is on the menu itself, not on an item: the arrows enter the list.\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.focusFirstItem();\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusLastItem();\n break;\n case 'Home':\n event.preventDefault();\n this.focusFirstItem();\n break;\n case 'End':\n event.preventDefault();\n this.focusLastItem();\n break;\n case 'Escape':\n // With softDismiss on, the browser closes the menu on Escape by\n // itself. Blocking the default here would stop that and leave the\n // menu open.\n if (this.softDismiss) break;\n event.preventDefault();\n this.dispatchEvent(new CustomEvent('close'));\n break;\n default:\n break;\n }\n }\n\n private get isMultiSelect(): boolean {\n if (this.multiSelect !== undefined) return this.multiSelect;\n return [\n ContextMenuType.Checkboxes,\n ContextMenuType.NestedCheckboxes,\n ContextMenuType.Multi,\n ContextMenuType.MultiWithSubtitles,\n ].includes(this.type);\n }\n\n private get isPerGroupSingleSelect(): boolean {\n if (this.isMultiSelect) return false;\n if (this.selectPerGroup !== undefined) return this.selectPerGroup;\n return this.type === ContextMenuType.Flyout;\n }\n\n /**\n * Returns a unique group-key for each option:\n * - In multi-with-subtitles: group title + subcolumn index (each subcolumn is a group)\n * - In multi: column index (each column is a group)\n */\n private getGroupForValue(value: string): string | undefined {\n if (\n this.type === ContextMenuType.MultiWithSubtitles &&\n this.columnGroups.length\n ) {\n for (const group of this.columnGroups) {\n const totalCols = Math.max(\n group.columns,\n Math.ceil(group.options.length / this.itemsPerColumn)\n );\n const distributed = this.chunkArray(\n group.options,\n this.itemsPerColumn,\n totalCols\n );\n for (let subColIdx = 0; subColIdx < distributed.length; ++subColIdx) {\n if (distributed[subColIdx].some((opt) => opt.value === value)) {\n return `${group.title}___${subColIdx}`;\n }\n }\n }\n return undefined;\n }\n if (this.type === ContextMenuType.Multi && this.itemsPerColumn > 0) {\n const columns = this.chunkArray(this.options, this.itemsPerColumn);\n for (let colIdx = 0; colIdx < columns.length; ++colIdx) {\n if (columns[colIdx].some((opt) => opt.value === value)) {\n return `column-${colIdx}`;\n }\n }\n return undefined;\n }\n if (this.type === ContextMenuType.Flyout && this.options.length) {\n for (const group of this.options) {\n if (group.children?.some((child) => child.value === value)) {\n return group.value;\n }\n if (group.value === value) return group.value;\n }\n return undefined;\n }\n return undefined;\n }\n\n private handleCheckboxChange(option: ContextMenuOption, e: Event) {\n const {status} = (e as CustomEvent<{status: 'checked' | 'unchecked'}>)\n .detail;\n let next: string[];\n\n // Enable \"one per group/column\" for multi-column layouts as well\n if (\n this.selectPerGroup &&\n (this.type === ContextMenuType.Multi ||\n this.type === ContextMenuType.MultiWithSubtitles)\n ) {\n const groupKey = this.getGroupForValue(option.value);\n next = [\n ...this.selectedValues.filter(\n (val) => this.getGroupForValue(val) !== groupKey\n ),\n ...(status === 'checked' ? [option.value] : []),\n ];\n } else {\n next =\n status === 'checked'\n ? [...this.selectedValues, option.value]\n : this.selectedValues.filter((v) => v !== option.value);\n }\n\n if (!arraysEqual(this.selectedValues, next)) this.updateSelection(next);\n }\n\n private handleMenuItemClick(option: ContextMenuOption, event: Event) {\n event.preventDefault();\n\n // Always fire item-click event, even for groups\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputItemClickEvent['detail']>(\n 'item-click',\n {\n detail: {value: option.value, option},\n }\n )\n );\n\n // Don't process selection for navigation groups in flyout menus or multi\n if (option.children?.length) return;\n\n let newSelectedValues: string[];\n\n if (this.isPerGroupSingleSelect) {\n // Get the group key for this value (column or group)\n const groupKey = this.getGroupForValue\n ? this.getGroupForValue(option.value)\n : undefined;\n\n // Find currently selected in this group\n const selectedInGroup = this.selectedValues.find(\n (val) => this.getGroupForValue(val) === groupKey\n );\n\n // If the clicked option is already selected in this group, unselect it\n if (selectedInGroup === option.value) {\n newSelectedValues = this.selectedValues.filter(\n (val) => val !== option.value\n );\n } else {\n // Otherwise, replace any existing selection in the group with this one\n newSelectedValues = [\n ...this.selectedValues.filter(\n (val) => this.getGroupForValue(val) !== groupKey\n ),\n option.value,\n ];\n }\n } else {\n // REGULAR (single select, non-grouped): toggle if already selected\n if (this.selectedValues.includes(option.value)) {\n newSelectedValues = [];\n } else {\n newSelectedValues = [option.value];\n }\n }\n\n if (!arraysEqual(this.selectedValues, newSelectedValues))\n this.updateSelection(newSelectedValues);\n }\n\n private updateSelection(vals: string[]) {\n this.selectedValues = vals;\n const selectedOptions: ContextMenuOption[] = [];\n const collect = (arr: ContextMenuOption[]) =>\n arr.forEach((o) => {\n if (vals.includes(o.value)) selectedOptions.push(o);\n if (o.children) collect(o.children);\n });\n collect(this.options);\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputChangeEvent['detail']>('change', {\n detail: {selectedValues: vals, selectedOptions},\n })\n );\n }\n\n private handleCloseClick(e: Event) {\n e.preventDefault();\n this.dispatchEvent(new CustomEvent('close'));\n }\n\n private isOptionSelected(v: string) {\n return this.selectedValues.includes(v);\n }\n\n private renderTitleBar() {\n if (!this.hasTitleBar) return nothing;\n return html`\n <div class=\"title-container\">\n <div class=\"title-content\">\n <div class=\"title-text\">${this.title}</div>\n </div>\n <obc-icon-button\n variant=\"flat\"\n @click=${this.handleCloseClick}\n aria-label=\"Close menu\"\n .focusable=${false}\n >\n <obi-close-google></obi-close-google>\n </obc-icon-button>\n </div>\n `;\n }\n\n private renderRegularItems() {\n return this.options.map((o) => this.renderNavItem(o));\n }\n\n private renderCheckboxItems() {\n return this.options.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n const isNested =\n this.type === ContextMenuType.NestedCheckboxes &&\n o.level &&\n o.level > 1;\n const indent = isNested ? (o.level! - 1) * 16 : 0;\n return html`<div\n class=\"menu-item checkbox-item-wrapper\"\n style=${indent ? `padding-left:${indent}px` : ''}\n >\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(o, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n\n private renderNavItem(o: ContextMenuOption) {\n const isSelected = this.isOptionSelected(o.value);\n const indent = o.level ? (o.level - 1) * 16 : 0;\n return html`<div\n class=\"menu-item navigation-item-wrapper\"\n style=${indent ? `padding-left:${indent}px` : ''}\n >\n <obc-navigation-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n @click=${(e: Event) => this.handleMenuItemClick(o, e)}\n .itemRole=${NavigationItemRole.MenuItemRadio}\n ?hasIcon=${!!o.icon}\n >\n ${o.icon ? html`<div slot=\"icon\">${o.icon}</div>` : nothing}\n </obc-navigation-item>\n </div>`;\n }\n\n // Renders checkboxes for children if multi, otherwise navigation items\n private renderFlyoutChildren(children: ContextMenuOption[]) {\n if (this.isMultiSelect) {\n return children.map((c) => {\n const isSelected = this.isOptionSelected(c.value);\n return html`<div class=\"menu-item checkbox-item-wrapper\">\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${c.value}\n .label=${c.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(c, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n return children.map((c) => {\n const isSelected = this.isOptionSelected(c.value);\n return html`<obc-navigation-item\n data-menu-item=\"true\"\n data-menu-value=${c.value}\n .label=${c.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n @click=${(e: Event) => this.handleMenuItemClick(c, e)}\n .itemRole=${NavigationItemRole.MenuItemRadio}\n ?hasIcon=${!!c.icon}\n >\n ${c.icon ? html`<div slot=\"icon\">${c.icon}</div>` : nothing}\n </obc-navigation-item>`;\n });\n }\n\n /**\n * Rows a group shows or hides join or leave the roving set only once the\n * group has rendered; until then a newly shown row is its own tab stop.\n */\n private async refreshAfterDisclosure(group: ObcNavigationItemGroup) {\n await group.updateComplete;\n await this.updateComplete;\n this.navigator.refresh();\n }\n\n private handleFlyoutGroupClick(option: ContextMenuOption, event: Event) {\n event.preventDefault();\n this.refreshAfterDisclosure(event.currentTarget as ObcNavigationItemGroup);\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputItemClickEvent['detail']>(\n 'item-click',\n {\n detail: {value: option.value, option},\n }\n )\n );\n // Don't fire a change event for navigation groups\n }\n\n private renderFlyoutItems() {\n return this.options.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n if (o.children?.length) {\n return html`<obc-navigation-item-group\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n .hug=${true}\n .hasIcon=${!!o.icon}\n @click=${(e: Event) => this.handleFlyoutGroupClick(o, e)}\n @open=${(e: Event) => {\n this.shadowRoot\n ?.querySelectorAll('obc-navigation-item-group')\n .forEach((g) => {\n const group = g as ObcNavigationItemGroup;\n if (group.label !== o.label) group.close();\n });\n this.refreshAfterDisclosure(\n e.currentTarget as ObcNavigationItemGroup\n );\n }}\n >\n ${o.icon ? html`<div slot=\"icon\">${o.icon}</div>` : nothing}\n ${this.renderFlyoutChildren(o.children)}\n </obc-navigation-item-group>`;\n }\n return this.renderNavItem(o);\n });\n }\n\n // --------- MULTI COLUMN ---------\n\n private renderMultiColumnItems() {\n const renderColumn = (columnOptions: ContextMenuOption[]) => {\n if (!columnOptions.length) return nothing;\n\n // True multi-select: checkboxes\n if (this.isMultiSelect && !this.selectPerGroup) {\n return columnOptions.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n return html`<div class=\"menu-item checkbox-item-wrapper\">\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(o, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n // fallback: nav item\n return columnOptions.map((opt) => this.renderNavItem(opt));\n };\n\n if (this.type === ContextMenuType.MultiWithSubtitles) {\n if (!this.columnGroups.length) {\n // Fallback – evenly spread across columns\n const cols = this.chunkArray(this.options, this.itemsPerColumn);\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n <div class=\"columns-container\">\n ${cols.map(\n (col, idx) =>\n html`<div\n class=\"column-with-header ${idx ? 'column-divider' : ''}\"\n >\n <div class=\"column-header\">\n <div class=\"subtitle-container\">\n <div class=\"subtitle-text\">Group ${idx + 1}</div>\n </div>\n </div>\n <div class=\"column-content\">${renderColumn(col)}</div>\n </div>`\n )}\n </div>\n </div>\n </div>`;\n }\n\n interface ColumnInfo {\n options: ContextMenuOption[];\n groupTitle: string;\n isFirstInGroup: boolean;\n isFirstGroup: boolean;\n colIdx: number;\n }\n\n const allCols: ColumnInfo[] = [];\n this.columnGroups.forEach((g, gIdx) => {\n const calculatedCols = Math.ceil(\n g.options.length / this.itemsPerColumn\n );\n const actualCols = Math.max(g.columns, calculatedCols);\n const distributed = this.chunkArray(\n g.options,\n this.itemsPerColumn,\n actualCols\n );\n distributed.forEach((opts, idx) => {\n allCols.push({\n options: opts,\n groupTitle: g.title,\n isFirstInGroup: idx === 0,\n isFirstGroup: gIdx === 0,\n colIdx: idx,\n });\n });\n });\n\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n <div class=\"columns-container\">\n ${allCols.map(\n (c) =>\n html`<div\n class=\"column-with-header ${\n !c.isFirstGroup && c.isFirstInGroup ? 'column-divider' : ''\n }\"\n >\n ${\n c.isFirstInGroup\n ? html`<div class=\"column-header\">\n <div class=\"subtitle-container\">\n <div class=\"subtitle-text\">${c.groupTitle}</div>\n </div>\n </div>`\n : html`<div class=\"column-header-spacer\"></div>`\n }\n <div class=\"column-content\">${renderColumn(c.options)}</div>\n </div>`\n )}\n </div>\n </div>\n </div>`;\n }\n\n // Simple multi (no subtitles)\n const columns = this.chunkArray(this.options, this.itemsPerColumn);\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n ${columns.map(\n (col, idx) =>\n html`<div class=\"column ${idx ? 'column-divider' : ''}\">\n ${renderColumn(col)}\n </div>`\n )}\n </div>\n </div>`;\n }\n\n private chunkArray<T>(arr: T[], size: number, forcedColumns?: number): T[][] {\n if (forcedColumns) {\n const out: T[][] = Array.from({length: forcedColumns}, () => []);\n arr.forEach((item, idx) => out[Math.floor(idx / size)].push(item));\n return out;\n }\n const result: T[][] = [];\n for (let i = 0; i < arr.length; i += size)\n result.push(arr.slice(i + 0, i + size));\n return result;\n }\n\n private renderMenuContent() {\n switch (this.type) {\n case ContextMenuType.Checkboxes:\n case ContextMenuType.NestedCheckboxes:\n return this.renderCheckboxItems();\n case ContextMenuType.Flyout:\n return this.renderFlyoutItems();\n case ContextMenuType.Multi:\n case ContextMenuType.MultiWithSubtitles:\n return this.renderMultiColumnItems();\n default:\n return this.renderRegularItems();\n }\n }\n\n override render() {\n return html`<div\n class=${classMap({\n 'context-menu': true,\n [`type-${this.type}`]: true,\n 'has-title': this.hasTitleBar,\n })}\n tabindex=\"-1\"\n role=\"menu\"\n aria-label=${this.hasTitleBar ? this.title : 'Context menu'}\n @keydown=${this.handleKeydown}\n @focusin=${(event: Event) => this.navigator.handleFocusin(event)}\n >\n ${this.renderTitleBar()}\n <div class=\"menu-content\">${this.renderMenuContent()}</div>\n </div>`;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\nfunction arraysEqual(a: string[], b: string[]) {\n if (a.length !== b.length) return false;\n const setA = new Set(a);\n return b.every((v) => setA.has(v));\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-context-menu-input': ObcContextMenuInput;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA+EA,IAAY,kBAAL,yBAAA,iBAAA;CACL,gBAAA,aAAA;CACA,gBAAA,gBAAA;CACA,gBAAA,sBAAA;CACA,gBAAA,YAAA;CACA,gBAAA,WAAA;CACA,gBAAA,wBAAA;;AACF,EAAA,CAAA,CAAA;AA+KO,IAAM,sBAAN,MAAM,4BAA4B,WAAW;;;EACT,KAAA,cAAA;EAEP,KAAA,OAAA;EAES,KAAA,wBAAA,IAAI,kBAAkB,IAAI;;EAKb,KAAA,UAAA,CAAC;EAEL,KAAA,iBAAA,CAAC;EAEZ,KAAA,cAAA;EAEE,KAAA,QAAA;EAEY,KAAA,eAAA,CAAC;EAEb,KAAA,iBAAA;EAMd,KAAA,YAAA,IAAI,gBAC/B;GACE,aAAa,KAAK,aAAa;GAC/B,iBAAiB,KAAK,iBAAiB;GACvC,eAAe,MAAM,cAAc;IACjC,KAAK,YAAY;GACnB;EACF,GACA;GAAC,aAAa;GAAY,MAAM;EAAK,CACvC;;CAEA,UAAmB;EACjB,KAAK,UAAU,QAAQ;CACzB;CAEA,eAA0C;EACxC,OAAO,MAAM,KACX,KAAK,WAAW,iBACd,2BACF,CACF,CAAC,CAAC,QAAQ,SAAS,KAAK,eAAe,CAAC,CAAC,SAAS,CAAC;CACrD;CAEA,mBAAwD;EACtD,MAAM,QAAQ,KAAK,aAAa;EAChC,OAAO,KAAK,eACT,KAAK,UACJ,MAAM,MAAM,SAAS,KAAK,aAAa,iBAAiB,MAAM,KAAK,CACrE,CAAC,CACA,MAAM,SAAkC,SAAS,KAAA,CAAS;CAC/D;CAEA,cAAsB,OAAe;EACnC,MAAM,QAAQ,KAAK,aAAa;EAChC,IAAI,MAAM,WAAW,GAAG;EAExB,MAAM,OAAO,MAAM,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC;EACnD,KAAK,UAAU,UAAU,MAAM,IAAI;EACnC,KAAK,eAAe,EAAC,OAAO,UAAS,CAAC;CACxC;CAEA,iBAAwB;EACtB,KAAK,cAAc,CAAC;CACtB;CAEA,gBAAuB;EACrB,MAAM,QAAQ,KAAK,aAAa;EAChC,IAAI,MAAM,WAAW,GAAG;EAExB,KAAK,cAAc,MAAM,SAAS,CAAC;CACrC;CAEA,oBAA2B;EAEzB,IADc,KAAK,aACf,CAAA,CAAM,WAAW,GAAG;EAExB,MAAM,eAAe,KAAK,iBAAiB;EAC3C,IAAI,iBAAiB,KAAA,GAAW;GAC9B,KAAK,UAAU,UAAU,cAAc,IAAI;GAC3C,aAAa,eAAe,EAAC,OAAO,UAAS,CAAC;GAC9C;EACF;EAEA,KAAK,eAAe;CACtB;CAEA,cAAsB,OAAsB;EAC1C,IAAI,KAAK,UAAU,cAAc,KAAK,GAAG;GACvC,MAAM,eAAe;GACrB,KAAK,UAAU,YAAY,eAAe,EAAC,OAAO,UAAS,CAAC;GAC5D;EACF;EAEA,IADc,KAAK,aACf,CAAA,CAAM,WAAW,GAAG;EAGxB,QAAQ,MAAM,KAAd;GACE,KAAK;IACH,MAAM,eAAe;IACrB,KAAK,eAAe;IACpB;GACF,KAAK;IACH,MAAM,eAAe;IACrB,KAAK,cAAc;IACnB;GACF,KAAK;IACH,MAAM,eAAe;IACrB,KAAK,eAAe;IACpB;GACF,KAAK;IACH,MAAM,eAAe;IACrB,KAAK,cAAc;IACnB;GACF,KAAK;IAIH,IAAI,KAAK,aAAa;IACtB,MAAM,eAAe;IACrB,KAAK,cAAc,IAAI,YAAY,OAAO,CAAC;EAI/C;CACF;CAEA,IAAY,gBAAyB;EACnC,IAAI,KAAK,gBAAgB,KAAA,GAAW,OAAO,KAAK;EAChD,OAAO;;;;;EAKP,CAAC,CAAC,SAAS,KAAK,IAAI;CACtB;CAEA,IAAY,yBAAkC;EAC5C,IAAI,KAAK,eAAe,OAAO;EAC/B,IAAI,KAAK,mBAAmB,KAAA,GAAW,OAAO,KAAK;EACnD,OAAO,KAAK,SAAA;CACd;;;;;;CAOA,iBAAyB,OAAmC;EAC1D,IACE,KAAK,SAAA,0BACL,KAAK,aAAa,QAClB;GACA,KAAK,MAAM,SAAS,KAAK,cAAc;IACrC,MAAM,YAAY,KAAK,IACrB,MAAM,SACN,KAAK,KAAK,MAAM,QAAQ,SAAS,KAAK,cAAc,CACtD;IACA,MAAM,cAAc,KAAK,WACvB,MAAM,SACN,KAAK,gBACL,SACF;IACA,KAAK,IAAI,YAAY,GAAG,YAAY,YAAY,QAAQ,EAAE,WACxD,IAAI,YAAY,UAAU,CAAC,MAAM,QAAQ,IAAI,UAAU,KAAK,GAC1D,OAAO,GAAG,MAAM,MAAM,KAAK;GAGjC;GACA;EACF;EACA,IAAI,KAAK,SAAA,WAAkC,KAAK,iBAAiB,GAAG;GAClE,MAAM,UAAU,KAAK,WAAW,KAAK,SAAS,KAAK,cAAc;GACjE,KAAK,IAAI,SAAS,GAAG,SAAS,QAAQ,QAAQ,EAAE,QAC9C,IAAI,QAAQ,OAAO,CAAC,MAAM,QAAQ,IAAI,UAAU,KAAK,GACnD,OAAO,UAAU;GAGrB;EACF;EACA,IAAI,KAAK,SAAA,YAAmC,KAAK,QAAQ,QAAQ;GAC/D,KAAK,MAAM,SAAS,KAAK,SAAS;IAChC,IAAI,MAAM,UAAU,MAAM,UAAU,MAAM,UAAU,KAAK,GACvD,OAAO,MAAM;IAEf,IAAI,MAAM,UAAU,OAAO,OAAO,MAAM;GAC1C;GACA;EACF;CAEF;CAEA,qBAA6B,QAA2B,GAAU;EAChE,MAAM,EAAC,WAAW,EACf;EACH,IAAI;EAGJ,IACE,KAAK,mBACJ,KAAK,SAAA,WACJ,KAAK,SAAA,yBACP;GACA,MAAM,WAAW,KAAK,iBAAiB,OAAO,KAAK;GACnD,OAAO,CACL,GAAG,KAAK,eAAe,QACpB,QAAQ,KAAK,iBAAiB,GAAG,MAAM,QAC1C,GACA,GAAI,WAAW,YAAY,CAAC,OAAO,KAAK,IAAI,CAAC,CAC/C;EACF,OACE,OACE,WAAW,YACP,CAAC,GAAG,KAAK,gBAAgB,OAAO,KAAK,IACrC,KAAK,eAAe,QAAQ,MAAM,MAAM,OAAO,KAAK;EAG5D,IAAI,CAAC,YAAY,KAAK,gBAAgB,IAAI,GAAG,KAAK,gBAAgB,IAAI;CACxE;CAEA,oBAA4B,QAA2B,OAAc;EACnE,MAAM,eAAe;EAGrB,KAAK,cACH,IAAI,YACF,cACA,EACE,QAAQ;GAAC,OAAO,OAAO;GAAO;EAAM,EACtC,CACF,CACF;EAGA,IAAI,OAAO,UAAU,QAAQ;EAE7B,IAAI;EAEJ,IAAI,KAAK,wBAAwB;GAE/B,MAAM,WAAW,KAAK,mBAClB,KAAK,iBAAiB,OAAO,KAAK,IAClC,KAAA;GAQJ,IALwB,KAAK,eAAe,MACzC,QAAQ,KAAK,iBAAiB,GAAG,MAAM,QAItC,MAAoB,OAAO,OAC7B,oBAAoB,KAAK,eAAe,QACrC,QAAQ,QAAQ,OAAO,KAC1B;QAGA,oBAAoB,CAClB,GAAG,KAAK,eAAe,QACpB,QAAQ,KAAK,iBAAiB,GAAG,MAAM,QAC1C,GACA,OAAO,KACT;EAEJ,OAEE,IAAI,KAAK,eAAe,SAAS,OAAO,KAAK,GAC3C,oBAAoB,CAAC;OAErB,oBAAoB,CAAC,OAAO,KAAK;EAIrC,IAAI,CAAC,YAAY,KAAK,gBAAgB,iBAAiB,GACrD,KAAK,gBAAgB,iBAAiB;CAC1C;CAEA,gBAAwB,MAAgB;EACtC,KAAK,iBAAiB;EACtB,MAAM,kBAAuC,CAAC;EAC9C,MAAM,WAAW,QACf,IAAI,SAAS,MAAM;GACjB,IAAI,KAAK,SAAS,EAAE,KAAK,GAAG,gBAAgB,KAAK,CAAC;GAClD,IAAI,EAAE,UAAU,QAAQ,EAAE,QAAQ;EACpC,CAAC;EACH,QAAQ,KAAK,OAAO;EACpB,KAAK,cACH,IAAI,YAAsD,UAAU,EAClE,QAAQ;GAAC,gBAAgB;GAAM;EAAe,EAChD,CAAC,CACH;CACF;CAEA,iBAAyB,GAAU;EACjC,EAAE,eAAe;EACjB,KAAK,cAAc,IAAI,YAAY,OAAO,CAAC;CAC7C;CAEA,iBAAyB,GAAW;EAClC,OAAO,KAAK,eAAe,SAAS,CAAC;CACvC;CAEA,iBAAyB;EACvB,IAAI,CAAC,KAAK,aAAa,OAAO;EAC9B,OAAO,IAAI;;;oCAGqB,KAAK,MAAM;;;;mBAI5B,KAAK,iBAAiB;;uBAElB,MAAM;;;;;;CAM3B;CAEA,qBAA6B;EAC3B,OAAO,KAAK,QAAQ,KAAK,MAAM,KAAK,cAAc,CAAC,CAAC;CACtD;CAEA,sBAA8B;EAC5B,OAAO,KAAK,QAAQ,KAAK,MAAM;GAC7B,MAAM,aAAa,KAAK,iBAAiB,EAAE,KAAK;GAKhD,MAAM,SAHJ,KAAK,SAAA,uBACL,EAAE,SACF,EAAE,QAAQ,KACe,EAAE,QAAS,KAAK,KAAK;GAChD,OAAO,IAAI;;gBAED,SAAS,gBAAgB,OAAO,MAAM,GAAG;;;;4BAI7B,EAAE,MAAM;mBACjB,EAAE,MAAM;oBACP,aAAa,YAAY,YAAY;2BAC9B,gBAAgB;qBACtB,MAAa,KAAK,qBAAqB,GAAG,CAAC,EAAE;;;EAG9D,CAAC;CACH;CAEA,cAAsB,GAAsB;EAC1C,MAAM,aAAa,KAAK,iBAAiB,EAAE,KAAK;EAChD,MAAM,SAAS,EAAE,SAAS,EAAE,QAAQ,KAAK,KAAK;EAC9C,OAAO,IAAI;;cAED,SAAS,gBAAgB,OAAO,MAAM,GAAG;;;;0BAI7B,EAAE,MAAM;iBACjB,EAAE,MAAM;mBACN,WAAW;mBACX,yBAAyB,KAAK;kBAC/B,MAAa,KAAK,oBAAoB,GAAG,CAAC,EAAE;oBAC1C,mBAAmB,cAAc;mBAClC,CAAC,CAAC,EAAE,KAAK;;UAElB,EAAE,OAAO,IAAI,oBAAoB,EAAE,KAAK,UAAU,QAAQ;;;CAGlE;CAGA,qBAA6B,UAA+B;EAC1D,IAAI,KAAK,eACP,OAAO,SAAS,KAAK,MAAM;GACzB,MAAM,aAAa,KAAK,iBAAiB,EAAE,KAAK;GAChD,OAAO,IAAI;;;8BAGW,EAAE,MAAM;qBACjB,EAAE,MAAM;sBACP,aAAa,YAAY,YAAY;6BAC9B,gBAAgB;uBACtB,MAAa,KAAK,qBAAqB,GAAG,CAAC,EAAE;;;EAG9D,CAAC;EAEH,OAAO,SAAS,KAAK,MAAM;GACzB,MAAM,aAAa,KAAK,iBAAiB,EAAE,KAAK;GAChD,OAAO,IAAI;;0BAES,EAAE,MAAM;iBACjB,EAAE,MAAM;mBACN,WAAW;mBACX,yBAAyB,KAAK;kBAC/B,MAAa,KAAK,oBAAoB,GAAG,CAAC,EAAE;oBAC1C,mBAAmB,cAAc;mBAClC,CAAC,CAAC,EAAE,KAAK;;UAElB,EAAE,OAAO,IAAI,oBAAoB,EAAE,KAAK,UAAU,QAAQ;;EAEhE,CAAC;CACH;;;;;CAMA,MAAc,uBAAuB,OAA+B;EAClE,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,KAAK,UAAU,QAAQ;CACzB;CAEA,uBAA+B,QAA2B,OAAc;EACtE,MAAM,eAAe;EACrB,KAAK,uBAAuB,MAAM,aAAuC;EACzE,KAAK,cACH,IAAI,YACF,cACA,EACE,QAAQ;GAAC,OAAO,OAAO;GAAO;EAAM,EACtC,CACF,CACF;CAEF;CAEA,oBAA4B;EAC1B,OAAO,KAAK,QAAQ,KAAK,MAAM;GAC7B,MAAM,aAAa,KAAK,iBAAiB,EAAE,KAAK;GAChD,IAAI,EAAE,UAAU,QACd,OAAO,IAAI;;4BAES,EAAE,MAAM;mBACjB,EAAE,MAAM;qBACN,WAAW;qBACX,yBAAyB,KAAK;iBAClC,KAAK;qBACD,CAAC,CAAC,EAAE,KAAK;oBACV,MAAa,KAAK,uBAAuB,GAAG,CAAC,EAAE;mBAChD,MAAa;IACpB,KAAK,YACD,iBAAiB,2BAA2B,CAAC,CAC9C,SAAS,MAAM;KACd,MAAM,QAAQ;KACd,IAAI,MAAM,UAAU,EAAE,OAAO,MAAM,MAAM;IAC3C,CAAC;IACH,KAAK,uBACH,EAAE,aACJ;GACF,EAAE;;YAEA,EAAE,OAAO,IAAI,oBAAoB,EAAE,KAAK,UAAU,QAAQ;YAC1D,KAAK,qBAAqB,EAAE,QAAQ,EAAE;;GAG5C,OAAO,KAAK,cAAc,CAAC;EAC7B,CAAC;CACH;CAIA,yBAAiC;EAC/B,MAAM,gBAAgB,kBAAuC;GAC3D,IAAI,CAAC,cAAc,QAAQ,OAAO;GAGlC,IAAI,KAAK,iBAAiB,CAAC,KAAK,gBAC9B,OAAO,cAAc,KAAK,MAAM;IAC9B,MAAM,aAAa,KAAK,iBAAiB,EAAE,KAAK;IAChD,OAAO,IAAI;;;gCAGW,EAAE,MAAM;uBACjB,EAAE,MAAM;wBACP,aAAa,YAAY,YAAY;+BAC9B,gBAAgB;yBACtB,MAAa,KAAK,qBAAqB,GAAG,CAAC,EAAE;;;GAG9D,CAAC;GAGH,OAAO,cAAc,KAAK,QAAQ,KAAK,cAAc,GAAG,CAAC;EAC3D;EAEA,IAAI,KAAK,SAAA,wBAA6C;GACpD,IAAI,CAAC,KAAK,aAAa,QAAQ;IAE7B,MAAM,OAAO,KAAK,WAAW,KAAK,SAAS,KAAK,cAAc;IAC9D,OAAO,IAAI;;;gBAGH,KAAK,KACJ,KAAK,QACJ,IAAI;gDAC0B,MAAM,mBAAmB,GAAG;;;;2DAIjB,MAAM,EAAE;;;kDAGjB,aAAa,GAAG,EAAE;yBAEtD,EAAE;;;;GAIV;GAUA,MAAM,UAAwB,CAAC;GAC/B,KAAK,aAAa,SAAS,GAAG,SAAS;IACrC,MAAM,iBAAiB,KAAK,KAC1B,EAAE,QAAQ,SAAS,KAAK,cAC1B;IACA,MAAM,aAAa,KAAK,IAAI,EAAE,SAAS,cAAc;IAMrD,KALyB,WACvB,EAAE,SACF,KAAK,gBACL,UAEF,CAAA,CAAY,SAAS,MAAM,QAAQ;KACjC,QAAQ,KAAK;MACX,SAAS;MACT,YAAY,EAAE;MACd,gBAAgB,QAAQ;MACxB,cAAc,SAAS;MACvB,QAAQ;KACV,CAAC;IACH,CAAC;GACH,CAAC;GAED,OAAO,IAAI;;;cAGH,QAAQ,KACP,MACC,IAAI;8CAEA,CAAC,EAAE,gBAAgB,EAAE,iBAAiB,mBAAmB,GAC1D;;oBAGC,EAAE,iBACE,IAAI;;yDAE6B,EAAE,WAAW;;kCAG9C,IAAI,2CACT;gDAC6B,aAAa,EAAE,OAAO,EAAE;uBAE5D,EAAE;;;;EAIV;EAGA,MAAM,UAAU,KAAK,WAAW,KAAK,SAAS,KAAK,cAAc;EACjE,OAAO,IAAI;;UAEL,QAAQ,KACP,KAAK,QACJ,IAAI,sBAAsB,MAAM,mBAAmB,GAAG;gBAClD,aAAa,GAAG,EAAE;mBAE1B,EAAE;;;CAGR;CAEA,WAAsB,KAAU,MAAc,eAA+B;EAC3E,IAAI,eAAe;GACjB,MAAM,MAAa,MAAM,KAAK,EAAC,QAAQ,cAAa,SAAS,CAAC,CAAC;GAC/D,IAAI,SAAS,MAAM,QAAQ,IAAI,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;GACjE,OAAO;EACT;EACA,MAAM,SAAgB,CAAC;EACvB,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,MACnC,OAAO,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;EACxC,OAAO;CACT;CAEA,oBAA4B;EAC1B,QAAQ,KAAK,MAAb;GACE,KAAA;GACA,KAAA,qBACE,OAAO,KAAK,oBAAoB;GAClC,KAAA,UACE,OAAO,KAAK,kBAAkB;GAChC,KAAA;GACA,KAAA,wBACE,OAAO,KAAK,uBAAuB;GACrC,SACE,OAAO,KAAK,mBAAmB;EACnC;CACF;CAEA,SAAkB;EAChB,OAAO,IAAI;cACD,SAAS;GACf,gBAAgB;IACf,QAAQ,KAAK,SAAS;GACvB,aAAa,KAAK;EACpB,CAAC,EAAE;;;mBAGU,KAAK,cAAc,KAAK,QAAQ,eAAe;iBACjD,KAAK,cAAc;kBAClB,UAAiB,KAAK,UAAU,cAAc,KAAK,EAAE;;QAE/D,KAAK,eAAe,EAAE;kCACI,KAAK,kBAAkB,EAAE;;CAEzD;;EAEyB,KAAA,SAAA,UAAU,0BAAY;;AACjD;AAznBG,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,oBAAA,WAAA,eAAA,KAAA,CAAA;AAExB,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,oBAAA,WAAA,QAAA,KAAA,CAAA;AAIxB,WAAA,CAAA,SAAS,EAAC,MAAM,OAAM,CAAC,CAAA,GAAA,oBAAA,WAAA,QAAA,KAAA,CAAA;AAGvB,WAAA,CAAA,SAAS,EAAC,MAAM,MAAK,CAAC,CAAA,GAAA,oBAAA,WAAA,WAAA,KAAA,CAAA;AAEtB,WAAA,CAAA,SAAS,EAAC,MAAM,MAAK,CAAC,CAAA,GAAA,oBAAA,WAAA,kBAAA,KAAA,CAAA;AAEtB,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,oBAAA,WAAA,eAAA,KAAA,CAAA;AAExB,WAAA,CAAA,SAAS,EAAC,MAAM,OAAM,CAAC,CAAA,GAAA,oBAAA,WAAA,SAAA,KAAA,CAAA;AAEvB,WAAA,CAAA,SAAS,EAAC,MAAM,MAAK,CAAC,CAAA,GAAA,oBAAA,WAAA,gBAAA,KAAA,CAAA;AAEtB,WAAA,CAAA,SAAS,EAAC,MAAM,OAAM,CAAC,CAAA,GAAA,oBAAA,WAAA,kBAAA,KAAA,CAAA;AAEvB,WAAA,CAAA,SAAS,EAAC,MAAM,QAAO,CAAC,CAAA,GAAA,oBAAA,WAAA,eAAA,KAAA,CAAA;AAExB,WAAA,CAAA,SAAS;CAAC,MAAM;CAAS,SAAS;AAAI,CAAC,CAAA,GAAA,oBAAA,WAAA,kBAAA,KAAA,CAAA;AAzBzC,sBAAA,WAAA,CAAA,cAAc,wBAAwB,CAAA,GAAA,mBAAA;AA6nBvC,SAAS,YAAY,GAAa,GAAa;CAC7C,IAAI,EAAE,WAAW,EAAE,QAAQ,OAAO;CAClC,MAAM,OAAO,IAAI,IAAI,CAAC;CACtB,OAAO,EAAE,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC;AACnC"}
|