@oicl/openbridge-webcomponents 2.0.0-next.117 → 2.0.0-next.118
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 +37 -33
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +28 -23
- package/dist/ar/poi/poi-base.d.ts +6 -0
- package/dist/ar/poi/poi-base.d.ts.map +1 -1
- package/dist/ar/poi/poi-base.js.map +1 -1
- package/dist/ar/poi-button/poi-button.d.ts +2 -2
- package/dist/ar/poi-button/poi-button.js.map +1 -1
- package/dist/components/accordion-card/accordion-card.d.ts.map +1 -1
- package/dist/components/accordion-card/accordion-card.js.map +1 -1
- package/dist/components/advice-message-item/advice-message-item.d.ts +4 -2
- package/dist/components/advice-message-item/advice-message-item.d.ts.map +1 -1
- package/dist/components/advice-message-item/advice-message-item.js +4 -2
- package/dist/components/advice-message-item/advice-message-item.js.map +1 -1
- package/dist/components/app-menu/app-menu.d.ts +1 -1
- package/dist/components/app-menu/app-menu.js +1 -1
- package/dist/components/app-menu/app-menu.js.map +1 -1
- package/dist/components/brilliance-menu/brilliance-menu.d.ts +8 -4
- package/dist/components/brilliance-menu/brilliance-menu.d.ts.map +1 -1
- package/dist/components/brilliance-menu/brilliance-menu.js +8 -4
- package/dist/components/brilliance-menu/brilliance-menu.js.map +1 -1
- package/dist/components/check-button/check-button.js.map +1 -1
- package/dist/components/checkbox/checkbox.d.ts +2 -2
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/command-menu/command-menu.d.ts +1 -1
- package/dist/components/command-menu/command-menu.js +1 -1
- package/dist/components/command-menu/command-menu.js.map +1 -1
- package/dist/components/dropdown-button/dropdown-button.d.ts +2 -2
- package/dist/components/dropdown-button/dropdown-button.js +2 -2
- package/dist/components/dropdown-button/dropdown-button.js.map +1 -1
- package/dist/components/menu-button/menu-button.d.ts.map +1 -1
- package/dist/components/menu-button/menu-button.js.map +1 -1
- package/dist/components/navigation-item/navigation-item.d.ts +1 -5
- package/dist/components/navigation-item/navigation-item.d.ts.map +1 -1
- package/dist/components/navigation-item/navigation-item.js +0 -8
- package/dist/components/navigation-item/navigation-item.js.map +1 -1
- package/dist/components/navigation-item-group/navigation-item-group.d.ts +2 -1
- package/dist/components/navigation-item-group/navigation-item-group.d.ts.map +1 -1
- package/dist/components/navigation-item-group/navigation-item-group.js +2 -1
- package/dist/components/navigation-item-group/navigation-item-group.js.map +1 -1
- package/dist/components/notification-button/notification-button.d.ts +1 -1
- package/dist/components/notification-button/notification-button.js +1 -1
- package/dist/components/notification-button/notification-button.js.map +1 -1
- package/dist/components/notification-message-item/notification-message-item.d.ts +4 -2
- package/dist/components/notification-message-item/notification-message-item.d.ts.map +1 -1
- package/dist/components/notification-message-item/notification-message-item.js +4 -2
- package/dist/components/notification-message-item/notification-message-item.js.map +1 -1
- package/dist/components/pivot-item/pivot-item.d.ts +1 -1
- package/dist/components/pivot-item/pivot-item.js +1 -1
- package/dist/components/pivot-item/pivot-item.js.map +1 -1
- package/dist/components/slide-button/slide-button.d.ts.map +1 -1
- package/dist/components/slide-button/slide-button.js.map +1 -1
- package/dist/components/slider/slider.d.ts +2 -2
- package/dist/components/slider/slider.js +2 -2
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/slider-double/slider-double.d.ts +2 -2
- package/dist/components/slider-double/slider-double.js +2 -2
- package/dist/components/slider-double/slider-double.js.map +1 -1
- package/dist/components/stepper-box/stepper-box.d.ts +4 -2
- package/dist/components/stepper-box/stepper-box.d.ts.map +1 -1
- package/dist/components/stepper-box/stepper-box.js +4 -2
- package/dist/components/stepper-box/stepper-box.js.map +1 -1
- package/dist/components/system-button/system-button.d.ts +1 -1
- package/dist/components/system-button/system-button.js +1 -1
- package/dist/components/system-button/system-button.js.map +1 -1
- package/dist/components/tabbed-card/tabbed-card.d.ts.map +1 -1
- package/dist/components/tabbed-card/tabbed-card.js.map +1 -1
- package/dist/components/toggle-button-option/toggle-button-option.d.ts +2 -1
- package/dist/components/toggle-button-option/toggle-button-option.d.ts.map +1 -1
- package/dist/components/toggle-button-option/toggle-button-option.js +2 -1
- package/dist/components/toggle-button-option/toggle-button-option.js.map +1 -1
- package/dist/components/toggle-button-vertical-group/toggle-button-vertical-group.js.map +1 -1
- package/dist/components/toggle-switch/toggle-switch.d.ts +1 -1
- package/dist/components/toggle-switch/toggle-switch.js +1 -1
- package/dist/components/toggle-switch/toggle-switch.js.map +1 -1
- package/dist/components/top-bar/top-bar.d.ts.map +1 -1
- package/dist/components/top-bar/top-bar.js.map +1 -1
- package/dist/components/topbar-message-item/topbar-message-item.js.map +1 -1
- package/dist/integration-systems/integration-dropdown-button/integration-dropdown-button.d.ts +1 -1
- package/dist/integration-systems/integration-dropdown-button/integration-dropdown-button.js +1 -1
- package/dist/integration-systems/integration-dropdown-button/integration-dropdown-button.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-menu.js","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';\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 * - Ensure that only one command menu is active for a given system at a time to avoid conflicting states.\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 * @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 * @beta\n */\n@customElement('obc-command-menu')\nexport class ObcCommandMenu extends LitElement {\n /**\n * Whether the menu is in the \"in command\" state.\n * Controls the toggle and visual state.\n *\n * @default false\n */\n @property({type: Boolean}) inCommand = false;\n\n /**\n * Whether to display the location slot.\n * If false, the location is omitted from the menu.\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 ${this.showLocation\n ? html` <div class=\"divider\"></div>\n <div class=\"command-location\">\n <slot name=\"command-location\"></slot>\n </div>`\n : nothing}\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 showCheckedStateIcon\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 {CustomEvent<{inCommand: boolean}>} change - Fired when the command state is toggled.\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"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAiGO,IAAM,iBAAN,cAA6B,WAAW;AAAA,EAAxC,cAAA;AAAA,UAAA,GAAA,SAAA;AAOsB,SAAA,YAAY;AAMM,SAAA,eAAwB;AAAA,EAAA;AAAA,EAE5D,SAAS;AAChB,WAAO;AAAA;AAAA,gBAEK,SAAS;AAAA,MACf,MAAM;AAAA,MACN,cAAc,KAAK;AAAA,MACnB,cAAc,CAAC,KAAK;AAAA,MACpB,gBAAgB,KAAK;AAAA,IAAA,CACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAgBQ,KAAK,eACH;AAAA;AAAA;AAAA,gCAIA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMH,KAAK,QAAQ;AAAA,yBACZ,KAAK,SAAS;AAAA;AAAA,sBAEjB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwB3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,SAAS,OAAsC;AAGrD,UAAM,gBAAA;AACN,UAAM,WAAW,MAAM,OAAO;AAC9B,SAAK,YAAY;AACjB,SAAK;AAAA,MACH,IAAI,YAAkC,UAAU;AAAA,QAC9C,QAAQ,EAAC,WAAW,SAAA;AAAA,QACpB,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAEL;AAGF;AApGa,eAmGK,SAAS,UAAU,YAAY;AA5FpB,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAPd,eAOgB,WAAA,aAAA,CAAA;AAMkB,gBAAA;AAAA,EAA5C,SAAS,EAAC,MAAM,SAAS,WAAW,OAAM;AAAA,GAbhC,eAakC,WAAA,gBAAA,CAAA;AAblC,iBAAN,gBAAA;AAAA,EADN,cAAc,kBAAkB;AAAA,GACpB,cAAA;"}
|
|
1
|
+
{"version":3,"file":"command-menu.js","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';\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 * - Ensure that only one command menu is active for a given system at a time to avoid conflicting states.\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 * @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 * @beta\n */\n@customElement('obc-command-menu')\nexport class ObcCommandMenu extends LitElement {\n /**\n * Whether the menu is in the \"in command\" state.\n * Controls the toggle and visual state.\n *\n * @default false\n */\n @property({type: Boolean}) inCommand = false;\n\n /**\n * Whether to display the location slot.\n * If false, the location is omitted from the menu.\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 ${this.showLocation\n ? html` <div class=\"divider\"></div>\n <div class=\"command-location\">\n <slot name=\"command-location\"></slot>\n </div>`\n : nothing}\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 showCheckedStateIcon\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"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAiGO,IAAM,iBAAN,cAA6B,WAAW;AAAA,EAAxC,cAAA;AAAA,UAAA,GAAA,SAAA;AAOsB,SAAA,YAAY;AAMM,SAAA,eAAwB;AAAA,EAAA;AAAA,EAE5D,SAAS;AAChB,WAAO;AAAA;AAAA,gBAEK,SAAS;AAAA,MACf,MAAM;AAAA,MACN,cAAc,KAAK;AAAA,MACnB,cAAc,CAAC,KAAK;AAAA,MACpB,gBAAgB,KAAK;AAAA,IAAA,CACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAgBQ,KAAK,eACH;AAAA;AAAA;AAAA,gCAIA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMH,KAAK,QAAQ;AAAA,yBACZ,KAAK,SAAS;AAAA;AAAA,sBAEjB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwB3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,SAAS,OAAsC;AAGrD,UAAM,gBAAA;AACN,UAAM,WAAW,MAAM,OAAO;AAC9B,SAAK,YAAY;AACjB,SAAK;AAAA,MACH,IAAI,YAAkC,UAAU;AAAA,QAC9C,QAAQ,EAAC,WAAW,SAAA;AAAA,QACpB,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAEL;AAGF;AApGa,eAmGK,SAAS,UAAU,YAAY;AA5FpB,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAPd,eAOgB,WAAA,aAAA,CAAA;AAMkB,gBAAA;AAAA,EAA5C,SAAS,EAAC,MAAM,SAAS,WAAW,OAAM;AAAA,GAbhC,eAakC,WAAA,gBAAA,CAAA;AAblC,iBAAN,gBAAA;AAAA,EADN,cAAc,kBAAkB;AAAA,GACpB,cAAA;"}
|
|
@@ -127,8 +127,8 @@ export declare class ObcDropdownButton extends LitElement {
|
|
|
127
127
|
/**
|
|
128
128
|
* Handles the dropdown-change and change event when a new option is selected. Updates the selected value and label, and dispatches a `dropdown-change` and 'change' event with the new selection.
|
|
129
129
|
*
|
|
130
|
-
* @fires
|
|
131
|
-
* @fires
|
|
130
|
+
* @fires dropdown-change
|
|
131
|
+
* @fires change
|
|
132
132
|
*/
|
|
133
133
|
private changeHandler;
|
|
134
134
|
static styles: import('lit').CSSResult;
|
|
@@ -108,8 +108,8 @@ let ObcDropdownButton = class extends LitElement {
|
|
|
108
108
|
/**
|
|
109
109
|
* Handles the dropdown-change and change event when a new option is selected. Updates the selected value and label, and dispatches a `dropdown-change` and 'change' event with the new selection.
|
|
110
110
|
*
|
|
111
|
-
* @fires
|
|
112
|
-
* @fires
|
|
111
|
+
* @fires dropdown-change
|
|
112
|
+
* @fires change
|
|
113
113
|
*/
|
|
114
114
|
changeHandler(event) {
|
|
115
115
|
const target = event.target;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown-button.js","sources":["../../../src/components/dropdown-button/dropdown-button.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing, PropertyValues} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport compentStyle from './dropdown-button.css?inline';\nimport '../../icons/icon-drop-down-google.js';\nimport '../button/button.js';\nimport {customElement} from '../../decorator.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nexport enum DropdownButtonType {\n label = 'label',\n icon = 'icon',\n labelIcon = 'label-icon',\n}\n\nexport type ObcDropdownButtonChangeEvent = CustomEvent<{\n value: string;\n label: string;\n}>;\n\nexport type DropdownButtonOption = {\n value: string;\n label: string;\n level?: number;\n};\n\n/**\n * `<obc-dropdown-button>` – A dropdown select component for choosing a single option from a list.\n *\n * Presents a styled dropdown menu with a visible label and icon, allowing users to select one value from a set of options. The component displays the currently selected label and provides a native select element for accessibility and keyboard navigation.\n *\n * ### Features\n * - **Single selection:** Allows users to pick one option from a provided list.\n * - **Customizable options:** Accepts an array of `{value, label, level?}` objects for flexible option content and optional indentation (via `level`).\n * - **Visual label and icon:** Shows the selected label and a dropdown arrow icon (`<obi-drop-down-google>`).\n * - **Full width mode:** Can expand to fill the width of its container using the `fullWidth` property.\n * - **Accessible:** Uses a native `<select>` element under the hood for keyboard and screen reader support.\n * - **Focus styling:** Highlights the visible wrapper when the select is focused.\n *\n * ### Variants\n * - **Default:** Renders at intrinsic width, sized to content.\n * - **Full Width:** When `fullWidth` is true, stretches to fill the parent container.\n *\n * ### Usage Guidelines\n * Use `<obc-dropdown-button>` when you need a compact, accessible dropdown for single-choice selection. Ideal for forms, filters, and settings where users must pick one value from a list. Options can be grouped visually by providing a `level` property for indentation.\n *\n * **TODO(designer):** Confirm if there are recommended use cases or constraints for the `level` property (e.g., maximum nesting, visual grouping intent).\n *\n * ### Properties\n * - `options` (Array): List of selectable options, each with a `value` (string), `label` (string), and optional `level` (number) for indentation.\n * - `value` (string): The currently selected option's value. If not set, defaults to the first option.\n * - `fullWidth` (boolean): Expands the component to fill its container when true. Default is false.\n * - `allowEmptySelection` (boolean): When true, a `value` that does not match any option leaves the button with no option selected, showing `placeholder` instead of defaulting to the first option. Default is false.\n * - `placeholder` (string): Text shown when nothing is selected and `allowEmptySelection` is true. Default is an empty string.\n *\n * ### Events\n * - `dropdown-change` – Fired when the user selects a different option. The event detail includes `{ value, label }` of the selected option.\n * - `change` – Fired when the user selects a different option. The event detail includes `{ value, label }` of the selected option.\n *\n * ### Best Practices\n * - Always provide a non-empty `options` array; if empty, the select will show no label or options.\n * - Use unique `value` strings for each option to ensure correct selection and event detail.\n * - For grouped or indented options, set the `level` property (e.g., `level: 2` for sub-options).\n * - Avoid using for multi-select scenarios; use a dedicated multi-select component if multiple selections are needed.\n *\n * ### Example:\n * ```html\n * <obc-dropdown-button\n * .options=${[\n * { value: 'volvo', label: 'Volvo' },\n * { value: 'xc90', label: 'XC 90', level: 2 },\n * { value: 'mercedes', label: 'Mercedes' },\n * { value: 'audi', label: 'Audi' }\n * ]}\n * value=\"volvo\"\n * ></obc-dropdown-button>\n * ```\n *\n * @slot - (No named slots; all content is provided via properties)\n * @slot icon - Icon displayed at the start of the button when `type` is `icon` or `label-icon`.\n * @fires {ObcDropdownButtonChangeEvent} dropdown-change - Fires when the value of the select changes\n * @fires {ObcDropdownButtonChangeEvent} change - Fires when the value of the select changes\n * @stable\n */\n@customElement('obc-dropdown-button')\nexport class ObcDropdownButton extends LitElement {\n /**\n * List of selectable options. Each option is an object with a `value` (string), `label` (string), and optional `level` (number) for indentation/grouping.\n *\n * Example:\n * [\n * { value: 'volvo', label: 'Volvo' },\n * { value: 'xc90', label: 'XC 90', level: 2 }\n * ]\n */\n @property({type: Array}) options: DropdownButtonOption[] = [];\n\n /**\n * The value of the currently selected option. If not set, defaults to the first option in the list.\n */\n @property({type: String}) value: string | undefined;\n @property({type: Boolean}) disabled: boolean = false;\n\n /**\n * If true, the select expands to fill the width of its container. Default is false.\n */\n @property({type: Boolean}) fullWidth = false;\n\n /**\n * If true, a `value` that does not match any option leaves the button with no option selected,\n * showing `placeholder` instead of defaulting to the first option. Default is false.\n */\n @property({type: Boolean}) allowEmptySelection = false;\n\n /**\n * Text shown when nothing is selected and `allowEmptySelection` is true. Default is an empty string.\n */\n @property({type: String}) placeholder = '';\n\n /**\n * Controls the button's display type.\n * - `label`: Text label only (default)\n * - `icon`: Icon only, no label\n * - `label-icon`: Icon before the label\n */\n @property({type: String}) type: DropdownButtonType = DropdownButtonType.label;\n\n /**\n * If true, the dropdown menu opens above the button.\n */\n @property({type: Boolean}) openTop = false;\n\n /**\n * If true, the select is integration style. Default is false, only for integration bar.\n */\n @property({type: Boolean}) integration = false;\n\n @property({type: Boolean}) flat = false;\n\n @state() private selectedValue = '';\n @state() private selectedLabel = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateSelectedValues();\n }\n\n override willUpdate(changedProperties: PropertyValues): void {\n if (changedProperties.has('value') || changedProperties.has('options')) {\n this.updateSelectedValues();\n }\n }\n\n private updateSelectedValues(): void {\n if (this.options.length === 0) {\n this.selectedValue = '';\n this.selectedLabel = '';\n return;\n }\n const match = this.value\n ? this.options.find((item) => item.value === this.value)\n : undefined;\n if (match) {\n this.selectedValue = match.value;\n this.selectedLabel = match.label;\n return;\n }\n if (this.allowEmptySelection) {\n this.selectedValue = '';\n this.selectedLabel = this.placeholder;\n return;\n }\n this.selectedValue = this.options[0].value;\n this.selectedLabel = this.options[0].label;\n }\n\n override render() {\n return html`\n <div\n class=${classMap({\n wrapper: true,\n 'full-width': this.fullWidth,\n 'open-top': this.openTop,\n integration: this.integration,\n flat: this.flat && !this.integration,\n disabled: this.disabled,\n })}\n >\n <div class=\"visible-wrapper\">\n ${this.type !== DropdownButtonType.label\n ? html`<div class=\"icon-container\"><slot name=\"icon\"></slot></div>`\n : nothing}\n ${this.type !== DropdownButtonType.icon\n ? html`<div class=\"label\">${this.selectedLabel}</div>`\n : nothing}\n <div class=\"icon\">\n <obi-drop-down-google></obi-drop-down-google>\n </div>\n </div>\n <select @change=${this.changeHandler} ?disabled=${this.disabled}>\n ${this.allowEmptySelection && this.selectedValue === ''\n ? html`<option value=\"\" disabled selected hidden>\n ${this.placeholder}\n </option>`\n : nothing}\n ${this.options.map((item) => {\n const indent = item.level ? (item.level - 1) * 2 : 0;\n const indentText = [];\n for (let i = 0; i < indent; i++) {\n indentText.push(html` `);\n }\n\n return html`<option\n value=${item.value}\n ?selected=${item.value === this.selectedValue}\n >\n ${indentText}${item.label}\n </option>`;\n })}\n </select>\n </div>\n `;\n }\n\n /**\n * Handles the dropdown-change and change event when a new option is selected. Updates the selected value and label, and dispatches a `dropdown-change` and 'change' event with the new selection.\n *\n * @fires {ObcDropdownButtonChangeEvent} dropdown-change - Fired when the user selects a different option.\n * @fires {ObcDropdownButtonChangeEvent} change - Fired when the user selects a different option.\n */\n private changeHandler(event: Event) {\n const target = event.target as HTMLSelectElement;\n this.selectedValue = target.value;\n this.selectedLabel = this.options\n .find((item) => item.value === this.selectedValue)!\n .label.trim();\n this.dispatchEvent(\n new CustomEvent('dropdown-change', {\n detail: {value: this.selectedValue, label: this.selectedLabel},\n })\n );\n this.dispatchEvent(\n new CustomEvent('change', {\n detail: {value: this.selectedValue, label: this.selectedLabel},\n })\n );\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-dropdown-button': ObcDropdownButton;\n }\n}\n"],"names":["DropdownButtonType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dropdown-button.js","sources":["../../../src/components/dropdown-button/dropdown-button.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing, PropertyValues} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport compentStyle from './dropdown-button.css?inline';\nimport '../../icons/icon-drop-down-google.js';\nimport '../button/button.js';\nimport {customElement} from '../../decorator.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nexport enum DropdownButtonType {\n label = 'label',\n icon = 'icon',\n labelIcon = 'label-icon',\n}\n\nexport type ObcDropdownButtonChangeEvent = CustomEvent<{\n value: string;\n label: string;\n}>;\n\nexport type DropdownButtonOption = {\n value: string;\n label: string;\n level?: number;\n};\n\n/**\n * `<obc-dropdown-button>` – A dropdown select component for choosing a single option from a list.\n *\n * Presents a styled dropdown menu with a visible label and icon, allowing users to select one value from a set of options. The component displays the currently selected label and provides a native select element for accessibility and keyboard navigation.\n *\n * ### Features\n * - **Single selection:** Allows users to pick one option from a provided list.\n * - **Customizable options:** Accepts an array of `{value, label, level?}` objects for flexible option content and optional indentation (via `level`).\n * - **Visual label and icon:** Shows the selected label and a dropdown arrow icon (`<obi-drop-down-google>`).\n * - **Full width mode:** Can expand to fill the width of its container using the `fullWidth` property.\n * - **Accessible:** Uses a native `<select>` element under the hood for keyboard and screen reader support.\n * - **Focus styling:** Highlights the visible wrapper when the select is focused.\n *\n * ### Variants\n * - **Default:** Renders at intrinsic width, sized to content.\n * - **Full Width:** When `fullWidth` is true, stretches to fill the parent container.\n *\n * ### Usage Guidelines\n * Use `<obc-dropdown-button>` when you need a compact, accessible dropdown for single-choice selection. Ideal for forms, filters, and settings where users must pick one value from a list. Options can be grouped visually by providing a `level` property for indentation.\n *\n * **TODO(designer):** Confirm if there are recommended use cases or constraints for the `level` property (e.g., maximum nesting, visual grouping intent).\n *\n * ### Properties\n * - `options` (Array): List of selectable options, each with a `value` (string), `label` (string), and optional `level` (number) for indentation.\n * - `value` (string): The currently selected option's value. If not set, defaults to the first option.\n * - `fullWidth` (boolean): Expands the component to fill its container when true. Default is false.\n * - `allowEmptySelection` (boolean): When true, a `value` that does not match any option leaves the button with no option selected, showing `placeholder` instead of defaulting to the first option. Default is false.\n * - `placeholder` (string): Text shown when nothing is selected and `allowEmptySelection` is true. Default is an empty string.\n *\n * ### Events\n * - `dropdown-change` – Fired when the user selects a different option. The event detail includes `{ value, label }` of the selected option.\n * - `change` – Fired when the user selects a different option. The event detail includes `{ value, label }` of the selected option.\n *\n * ### Best Practices\n * - Always provide a non-empty `options` array; if empty, the select will show no label or options.\n * - Use unique `value` strings for each option to ensure correct selection and event detail.\n * - For grouped or indented options, set the `level` property (e.g., `level: 2` for sub-options).\n * - Avoid using for multi-select scenarios; use a dedicated multi-select component if multiple selections are needed.\n *\n * ### Example:\n * ```html\n * <obc-dropdown-button\n * .options=${[\n * { value: 'volvo', label: 'Volvo' },\n * { value: 'xc90', label: 'XC 90', level: 2 },\n * { value: 'mercedes', label: 'Mercedes' },\n * { value: 'audi', label: 'Audi' }\n * ]}\n * value=\"volvo\"\n * ></obc-dropdown-button>\n * ```\n *\n * @slot - (No named slots; all content is provided via properties)\n * @slot icon - Icon displayed at the start of the button when `type` is `icon` or `label-icon`.\n * @fires {ObcDropdownButtonChangeEvent} dropdown-change - Fires when the value of the select changes\n * @fires {ObcDropdownButtonChangeEvent} change - Fires when the value of the select changes\n * @stable\n */\n@customElement('obc-dropdown-button')\nexport class ObcDropdownButton extends LitElement {\n /**\n * List of selectable options. Each option is an object with a `value` (string), `label` (string), and optional `level` (number) for indentation/grouping.\n *\n * Example:\n * [\n * { value: 'volvo', label: 'Volvo' },\n * { value: 'xc90', label: 'XC 90', level: 2 }\n * ]\n */\n @property({type: Array}) options: DropdownButtonOption[] = [];\n\n /**\n * The value of the currently selected option. If not set, defaults to the first option in the list.\n */\n @property({type: String}) value: string | undefined;\n @property({type: Boolean}) disabled: boolean = false;\n\n /**\n * If true, the select expands to fill the width of its container. Default is false.\n */\n @property({type: Boolean}) fullWidth = false;\n\n /**\n * If true, a `value` that does not match any option leaves the button with no option selected,\n * showing `placeholder` instead of defaulting to the first option. Default is false.\n */\n @property({type: Boolean}) allowEmptySelection = false;\n\n /**\n * Text shown when nothing is selected and `allowEmptySelection` is true. Default is an empty string.\n */\n @property({type: String}) placeholder = '';\n\n /**\n * Controls the button's display type.\n * - `label`: Text label only (default)\n * - `icon`: Icon only, no label\n * - `label-icon`: Icon before the label\n */\n @property({type: String}) type: DropdownButtonType = DropdownButtonType.label;\n\n /**\n * If true, the dropdown menu opens above the button.\n */\n @property({type: Boolean}) openTop = false;\n\n /**\n * If true, the select is integration style. Default is false, only for integration bar.\n */\n @property({type: Boolean}) integration = false;\n\n @property({type: Boolean}) flat = false;\n\n @state() private selectedValue = '';\n @state() private selectedLabel = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateSelectedValues();\n }\n\n override willUpdate(changedProperties: PropertyValues): void {\n if (changedProperties.has('value') || changedProperties.has('options')) {\n this.updateSelectedValues();\n }\n }\n\n private updateSelectedValues(): void {\n if (this.options.length === 0) {\n this.selectedValue = '';\n this.selectedLabel = '';\n return;\n }\n const match = this.value\n ? this.options.find((item) => item.value === this.value)\n : undefined;\n if (match) {\n this.selectedValue = match.value;\n this.selectedLabel = match.label;\n return;\n }\n if (this.allowEmptySelection) {\n this.selectedValue = '';\n this.selectedLabel = this.placeholder;\n return;\n }\n this.selectedValue = this.options[0].value;\n this.selectedLabel = this.options[0].label;\n }\n\n override render() {\n return html`\n <div\n class=${classMap({\n wrapper: true,\n 'full-width': this.fullWidth,\n 'open-top': this.openTop,\n integration: this.integration,\n flat: this.flat && !this.integration,\n disabled: this.disabled,\n })}\n >\n <div class=\"visible-wrapper\">\n ${this.type !== DropdownButtonType.label\n ? html`<div class=\"icon-container\"><slot name=\"icon\"></slot></div>`\n : nothing}\n ${this.type !== DropdownButtonType.icon\n ? html`<div class=\"label\">${this.selectedLabel}</div>`\n : nothing}\n <div class=\"icon\">\n <obi-drop-down-google></obi-drop-down-google>\n </div>\n </div>\n <select @change=${this.changeHandler} ?disabled=${this.disabled}>\n ${this.allowEmptySelection && this.selectedValue === ''\n ? html`<option value=\"\" disabled selected hidden>\n ${this.placeholder}\n </option>`\n : nothing}\n ${this.options.map((item) => {\n const indent = item.level ? (item.level - 1) * 2 : 0;\n const indentText = [];\n for (let i = 0; i < indent; i++) {\n indentText.push(html` `);\n }\n\n return html`<option\n value=${item.value}\n ?selected=${item.value === this.selectedValue}\n >\n ${indentText}${item.label}\n </option>`;\n })}\n </select>\n </div>\n `;\n }\n\n /**\n * Handles the dropdown-change and change event when a new option is selected. Updates the selected value and label, and dispatches a `dropdown-change` and 'change' event with the new selection.\n *\n * @fires dropdown-change\n * @fires change\n */\n private changeHandler(event: Event) {\n const target = event.target as HTMLSelectElement;\n this.selectedValue = target.value;\n this.selectedLabel = this.options\n .find((item) => item.value === this.selectedValue)!\n .label.trim();\n this.dispatchEvent(\n new CustomEvent('dropdown-change', {\n detail: {value: this.selectedValue, label: this.selectedLabel},\n })\n );\n this.dispatchEvent(\n new CustomEvent('change', {\n detail: {value: this.selectedValue, label: this.selectedLabel},\n })\n );\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-dropdown-button': ObcDropdownButton;\n }\n}\n"],"names":["DropdownButtonType"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-button.d.ts","sourceRoot":"","sources":["../../../src/components/menu-button/menu-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,yCAAyC,CAAC;AACjD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,6CAA6C,CAAC;AACrD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,WAAW,EACZ,MAAM,6CAA6C,CAAC;AAGrD,MAAM,MAAM,yBAAyB,GAAG,WAAW,CAAC;IAClD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,MAAM,2BAA2B,GAAG,WAAW,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,CAAC;CAC3B,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwGG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C;;;OAGG;IACuB,KAAK,SAAM;IAErC;;;;;;;;OAQG;IACsB,OAAO,EAAE,iBAAiB,EAAE,CAAM;IAE3D;;;OAGG;IACsB,cAAc,EAAE,MAAM,EAAE,CAAM;IAEvD;;;OAGG;IACwB,SAAS,UAAS;IAE7C;;;OAGG;IACwB,OAAO,UAAS;IAE3C;;;;;;;;;;OAUG;IAEH,QAAQ,EAAE,eAAe,CAA2B;IAEpD;;;;OAIG;IACwB,WAAW,CAAC,EAAE,OAAO,CAAC;IAEjD;;;OAGG;IACwB,cAAc,CAAC,EAAE,OAAO,CAAC;IAEpD;;;OAGG;IACwB,WAAW,UAAS;IAE/C;;OAEG;IACuB,SAAS,SAAM;IAEzC;;;OAGG;IACsB,YAAY,EAAE,WAAW,EAAE,CAAM;IAE1D;;;OAGG;IACuB,cAAc,SAAK;IAE7C;;;OAGG;IACwB,OAAO,UAAS;IAE3C;;;OAGG;IACwB,QAAQ,UAAS;IAEnC,OAAO,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,mBAAmB,CAAS;IAEpC,OAAO,CAAC,iBAAiB,CAA6C;IAE3C,OAAO,CAAC,IAAI,CAAC,CAAoC;IAEnD,OAAO,CAAC,aAAa,CAAC,CAAoB;IAEnE,OAAO,KAAK,oBAAoB,GAU/B;IAED,OAAO,KAAK,iBAAiB,GAU5B;IAED,OAAO,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"menu-button.d.ts","sourceRoot":"","sources":["../../../src/components/menu-button/menu-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,yCAAyC,CAAC;AACjD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,6CAA6C,CAAC;AACrD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,WAAW,EACZ,MAAM,6CAA6C,CAAC;AAGrD,MAAM,MAAM,yBAAyB,GAAG,WAAW,CAAC;IAClD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,MAAM,2BAA2B,GAAG,WAAW,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,CAAC;CAC3B,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwGG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C;;;OAGG;IACuB,KAAK,SAAM;IAErC;;;;;;;;OAQG;IACsB,OAAO,EAAE,iBAAiB,EAAE,CAAM;IAE3D;;;OAGG;IACsB,cAAc,EAAE,MAAM,EAAE,CAAM;IAEvD;;;OAGG;IACwB,SAAS,UAAS;IAE7C;;;OAGG;IACwB,OAAO,UAAS;IAE3C;;;;;;;;;;OAUG;IAEH,QAAQ,EAAE,eAAe,CAA2B;IAEpD;;;;OAIG;IACwB,WAAW,CAAC,EAAE,OAAO,CAAC;IAEjD;;;OAGG;IACwB,cAAc,CAAC,EAAE,OAAO,CAAC;IAEpD;;;OAGG;IACwB,WAAW,UAAS;IAE/C;;OAEG;IACuB,SAAS,SAAM;IAEzC;;;OAGG;IACsB,YAAY,EAAE,WAAW,EAAE,CAAM;IAE1D;;;OAGG;IACuB,cAAc,SAAK;IAE7C;;;OAGG;IACwB,OAAO,UAAS;IAE3C;;;OAGG;IACwB,QAAQ,UAAS;IAEnC,OAAO,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,mBAAmB,CAAS;IAEpC,OAAO,CAAC,iBAAiB,CAA6C;IAE3C,OAAO,CAAC,IAAI,CAAC,CAAoC;IAEnD,OAAO,CAAC,aAAa,CAAC,CAAoB;IAEnE,OAAO,KAAK,oBAAoB,GAU/B;IAED,OAAO,KAAK,iBAAiB,GAU5B;IAED,OAAO,CAAC,mBAAmB,CAuBzB;YAEY,kBAAkB;IAYhC,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,oBAAoB;IAyB5B,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,eAAe;IAMvB,OAAO,KAAK,aAAa,GAQxB;IAGD,OAAO,KAAK,uBAAuB,GAElC;IAEQ,MAAM;IA2Df,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-button.js","sources":["../../../src/components/menu-button/menu-button.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing} from 'lit';\nimport {property, state, query} from 'lit/decorators.js';\nimport compentStyle from './menu-button.css?inline';\nimport {customElement} from '../../decorator.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../../icons/icon-arrow-flyout-google.js';\nimport '../button/button.js';\nimport '../context-menu-input/context-menu-input.js';\nimport {\n ContextMenuType,\n ContextMenuOption,\n ColumnGroup,\n} from '../context-menu-input/context-menu-input.js';\nimport type {ObcContextMenuInput} from '../context-menu-input/context-menu-input.js';\n\nexport type ObcSplitButtonChangeEvent = CustomEvent<{\n selectedValues: string[];\n selectedOptions: Array<ContextMenuOption>;\n}>;\n\nexport type ObcMenuButtonItemClickEvent = CustomEvent<{\n value: string;\n option: ContextMenuOption;\n}>;\n\n/**\n * `<obc-menu-button>` – A dropdown menu button for selecting one or more options from a contextual menu.\n *\n * Provides a button that opens a configurable context menu, supporting single or multi-select, nested/flyout submenus, and multi-column layouts. The button can display a label, an optional icon, and adapts to various menu types (regular, checkboxes, flyout, multi-column, etc.).\n *\n * Appears as a compact button that, when clicked, reveals a menu for actions, filtering, or grouped selections. Useful for toolbars, filter bars, or anywhere contextual actions or selections are needed without taking up persistent space.\n *\n * ## Features\n * - **Menu Types:** Supports multiple menu variants via `menuType`:\n * - `Regular`: Standard single-select menu (action menu).\n * - `Checkboxes`: Multi-select with checkboxes.\n * - `NestedCheckboxes`: Hierarchical multi-select with nested checkboxes.\n * - `Flyout`: Multi-level flyout menu (supports nested groups).\n * - `Multi`: Multi-column menu (for large option sets).\n * - `MultiWithSubtitles`: Multi-column menu with group subtitles.\n * - **Selection Modes:**\n * - Single-select or multi-select (controlled by `multiSelect` and `menuType`).\n * - Per-group selection (only one item per group/column, via `selectPerGroup`).\n * - Optionally persist selection state (`persistSelection`).\n * - **Layout Options:**\n * - Full width (`fullWidth`) or fit-content.\n * - Menu can open above or below the button (`openTop`).\n * - Multi-column and grouped layouts (`columnGroups`, `itemsPerColumn`).\n * - Optional title bar with close button (`hasTitleBar`, `menuTitle`).\n * - **Content Customization:**\n * - Optional icon slot in button (`hasIcon`).\n * - Option icons and hierarchical/nested option structures.\n * - **Accessibility & Keyboard:**\n * - Keyboard navigation and ARIA roles.\n * - Disabled state disables both button and menu.\n * - **Events:**\n * - Emits `change` when selection changes.\n * - Emits `item-click` when an item is clicked.\n * - Emits `close` when the menu closes.\n *\n * ## Usage Guidelines\n * Use `obc-menu-button` to present a compact button that reveals a contextual menu for actions, filtering, or grouped selections. Ideal for toolbars, filter bars, or overflow menus where space is limited but multiple or hierarchical options are needed. Choose the menu type and selection mode based on your use case:\n * - Use `menuType=\"Regular\"` for simple single-action menus.\n * - Use `multiSelect` or `menuType=\"Checkboxes\"` for multi-select scenarios (e.g., filtering).\n * - Use `menuType=\"Flyout\"` for hierarchical or grouped actions.\n * - Use `menuType=\"Multi\"` or `menuType=\"MultiWithSubtitles\"` for large sets of options, grouped or split across columns.\n * - Use the icon slot for visual context (e.g., filter, settings, actions).\n * - Avoid using for persistent navigation—this is for contextual, transient actions or selections.\n *\n * **TODO(designer):** Confirm recommended use cases for each menu type and when to use per-group selection.\n *\n * ## Slots\n * | Slot Name | Renders When... | Purpose |\n * |-----------|---------------------|-----------------------------------------|\n * | `icon` | `hasIcon` is true | Icon displayed at the start of the button. |\n *\n * ## Properties & Attributes\n * - `label`: Text label shown on the button.\n * - `options`: Array of menu options (each with value, label, optional icon, children, etc.).\n * - `selectedValues`: Array of currently selected option values.\n * - `fullWidth`: If true, button stretches to fill its container.\n * - `hasIcon`: If true, shows the `icon` slot.\n * - `menuType`: Controls menu variant (see Features above). Defaults to `Regular`.\n * - `multiSelect`: If true, enables multi-select (overrides default for menuType).\n * - `selectPerGroup`: If true, only one selection per group/column (flyout/multi-column).\n * - `hasTitleBar`: If true, shows a title bar with close button in the menu.\n * - `menuTitle`: Title text for the menu (if `hasTitleBar` is true).\n * - `columnGroups`: Used for `multi-with-subtitles` layout; defines grouped columns.\n * - `itemsPerColumn`: Number of items per column in multi-column layouts.\n * - `openTop`: If true, menu opens above the button.\n * - `disabled`: Disables both the button and the menu.\n *\n * ## Events\n * - `change` – Fired when the menu selection changes (returns selected values and options).\n * - `item-click` – Fired when a menu item is clicked (returns value and option).\n * - `open` – Fired when the menu is opened.\n * - `close` – Fired when the menu is closed.\n *\n * ## Best Practices & Constraints\n * - Only use multi-select for scenarios where users may need to select multiple items (e.g., filters, bulk actions).\n * - For action menus (single-select, no persistence), set `persistSelection` to false.\n * - Use per-group selection (`selectPerGroup`) for grouped flyout or multi-column menus where only one selection per group is allowed.\n * - Avoid nesting too deeply in flyout menus for usability.\n * - If using icons in options, supply them via the `icon` property of each option (e.g., `<obi-placeholder></obi-placeholder>`).\n * - The button is fully keyboard accessible and supports ARIA roles for menu and menuitem.\n * - Menu closes automatically on selection (unless in multi-select mode).\n *\n * ## Example\n * ```html\n * <obc-menu-button\n * label=\"Actions\"\n * .options=${[\n * { value: 'edit', label: 'Edit', icon: html`<obi-placeholder></obi-placeholder>` },\n * { value: 'delete', label: 'Delete' }\n * ]}\n * .selectedValues=${['edit']}\n * hasIcon\n * >\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-menu-button>\n * ```\n * In this example, the button displays an icon and label, and opens a menu with two options (one with an icon).\n *\n * @slot icon - Icon displayed at the start of the button when `hasIcon` is true.\n * @fires {ObcSplitButtonChangeEvent} change - Fired when the menu selection changes.\n * @fires {ObcMenuButtonItemClickEvent} item-click - Fired when a menu item is clicked.\n * @fires {CustomEvent<void>} open - Fired when the menu is opened.\n * @fires {CustomEvent<void>} close - Fired when the menu is closed.\n * @beta\n */\n@customElement('obc-menu-button')\nexport class ObcMenuButton extends LitElement {\n /**\n * The label displayed on the button.\n * If empty, the button can be rendered as icon-only.\n */\n @property({type: String}) label = '';\n\n /**\n * Array of menu options with value, label, and optional level, icon, and children.\n * Each option can include:\n * - `value`: Unique string identifier.\n * - `label`: Display text.\n * - `icon`: Optional icon (e.g., `<obi-placeholder></obi-placeholder>`).\n * - `children`: Optional array of child options (for nested/flyout menus).\n * - `level`: Optional nesting level (for hierarchical menus).\n */\n @property({type: Array}) options: ContextMenuOption[] = [];\n\n /**\n * Array of currently selected option values.\n * Used to control which options are checked/selected in the menu.\n */\n @property({type: Array}) selectedValues: string[] = [];\n\n /**\n * Whether the button should fill the full width of its container.\n * If true, the button stretches to 100% width.\n */\n @property({type: Boolean}) fullWidth = false;\n\n /**\n * Whether the button should show an icon slot.\n * If true, the `icon` slot is rendered at the start of the button.\n */\n @property({type: Boolean}) hasIcon = false;\n\n /**\n * The variant type of context menu to display.\n * Determines menu layout and selection behavior.\n * - `Regular`: Standard single-select.\n * - `Checkboxes`: Multi-select with checkboxes.\n * - `NestedCheckboxes`: Hierarchical multi-select.\n * - `Flyout`: Multi-level flyout menu.\n * - `Multi`: Multi-column menu.\n * - `MultiWithSubtitles`: Multi-column with group subtitles.\n * @default ContextMenuType.Regular\n */\n @property({type: String})\n menuType: ContextMenuType = ContextMenuType.Regular;\n\n /**\n * Whether multiple selections are allowed.\n * Overrides the default selection mode for the chosen variant.\n * If not explicitly set, defaults based on `menuType`.\n */\n @property({type: Boolean}) multiSelect?: boolean;\n\n /**\n * Allows single selection per group (flyout/multi-column only).\n * When true, only one item per group/column can be selected.\n */\n @property({type: Boolean}) selectPerGroup?: boolean;\n\n /**\n * Whether to show a title bar with close button at the top of the menu.\n * If true, the menu displays a title bar (use `menuTitle` for text).\n */\n @property({type: Boolean}) hasTitleBar = false;\n\n /**\n * Title text displayed in the title bar (if `hasTitleBar` is true).\n */\n @property({type: String}) menuTitle = '';\n\n /**\n * Array of column groups for the `multi-with-subtitles` layout.\n * Used to define grouped columns with subtitles in multi-column menus.\n */\n @property({type: Array}) columnGroups: ColumnGroup[] = [];\n\n /**\n * Number of items per column in multi-column layouts.\n * Used for `Multi` and `MultiWithSubtitles` menu types.\n */\n @property({type: Number}) itemsPerColumn = 5;\n\n /**\n * Render the dropdown context menu above or below the button.\n * If true, the menu opens above the button; otherwise, it opens below.\n */\n @property({type: Boolean}) openTop = false;\n\n /**\n * Whether both parts of the button are disabled.\n * Disables both the button and the menu.\n */\n @property({type: Boolean}) disabled = false;\n\n @state() private isOpen = false;\n\n private restoreFocusOnClose = false;\n\n private menuFocusStrategy: 'first' | 'selected' | 'last' = 'selected';\n\n @query('.positioned-menu') private menu?: HTMLElement & ObcContextMenuInput;\n\n @query('button.wrapper') private triggerButton?: HTMLButtonElement;\n\n private get effectiveMultiSelect(): boolean {\n if (this.multiSelect !== undefined) return this.multiSelect;\n\n // Auto-determine based on menuType only for types that are inherently multi-select\n return [\n ContextMenuType.Checkboxes,\n ContextMenuType.NestedCheckboxes,\n ContextMenuType.Multi,\n ContextMenuType.MultiWithSubtitles,\n ].includes(this.menuType);\n }\n\n private get effectiveMenuType(): ContextMenuType {\n // Only rewrite regular->checkboxes for multi, never flyout\n if (\n this.effectiveMultiSelect &&\n this.menuType === ContextMenuType.Regular\n ) {\n return ContextMenuType.Checkboxes;\n }\n // DO NOT map Flyout to NestedCheckboxes!\n return this.menuType;\n }\n\n private handlePopoverToggle = (e: ToggleEvent) => {\n this.isOpen = e.newState === 'open';\n if (e.newState === 'open') {\n void this.focusMenuAfterOpen();\n /**\n * @event open - Fired when the menu is opened.\n * @type {CustomEvent<void>}\n */\n this.dispatchEvent(new CustomEvent('open'));\n }\n if (e.newState === 'closed') {\n if (this.restoreFocusOnClose) {\n this.restoreFocusOnClose = false;\n this.triggerButton?.focus();\n }\n /**\n * @event close - Fired when the menu is closed.\n * @type {CustomEvent<void>}\n */\n this.dispatchEvent(new CustomEvent('close'));\n }\n };\n\n private async focusMenuAfterOpen() {\n await this.updateComplete;\n if (this.menuFocusStrategy === 'last') {\n this.menu?.focusLastItem();\n } else if (this.menuFocusStrategy === 'first') {\n this.menu?.focusFirstItem();\n } else {\n this.menu?.focusSelectedItem();\n }\n this.menuFocusStrategy = 'selected';\n }\n\n private openMenu(focusStrategy: 'first' | 'selected' | 'last' = 'selected') {\n if (this.disabled) return;\n\n this.menuFocusStrategy = focusStrategy;\n this.menu?.showPopover();\n }\n\n private handleTriggerKeydown(event: KeyboardEvent) {\n if (this.disabled) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.openMenu('first');\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.openMenu('last');\n break;\n case 'Home':\n event.preventDefault();\n this.openMenu('first');\n break;\n case 'End':\n event.preventDefault();\n this.openMenu('last');\n break;\n default:\n break;\n }\n }\n\n private handleMenuChange(\n e: CustomEvent<{\n selectedValues: string[];\n selectedOptions: ContextMenuOption[];\n }>\n ) {\n this.selectedValues = e.detail.selectedValues;\n\n /**\n * @event change - Fired when the menu selection changes.\n * @type {CustomEvent<{selectedValues: string[], selectedOptions: Array<ContextMenuOption>}>}\n */\n this.dispatchEvent(new CustomEvent('change', {detail: e.detail}));\n if (!this.effectiveMultiSelect) {\n this.handleMenuClose();\n }\n }\n\n private handleItemClick(\n e: CustomEvent<{value: string; option: ContextMenuOption}>\n ) {\n /**\n * @event item-click - Fired when a menu item is clicked.\n * @type {CustomEvent<{value: string, option: ContextMenuOption}>}\n */\n this.dispatchEvent(new CustomEvent('item-click', {detail: e.detail}));\n const option = e.detail.option;\n if (option.children?.length) {\n return;\n }\n\n const isFlyoutMenu =\n this.menuType === ContextMenuType.Flyout ||\n this.menuType === ContextMenuType.NestedCheckboxes;\n\n if (isFlyoutMenu && !this.effectiveMultiSelect) {\n this.handleMenuClose();\n return;\n }\n }\n\n private handleMenuClose() {\n if (this.menu === undefined) return;\n this.restoreFocusOnClose = true;\n this.menu.hidePopover();\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.menuType);\n }\n\n // Only meaningful if not multi-select AND persistSelection is true\n private get effectiveSelectPerGroup(): boolean {\n return !this.isMultiSelect && !!this.selectPerGroup;\n }\n\n override render() {\n return html`\n <button\n class=${classMap({\n wrapper: true,\n 'full-width': this.fullWidth,\n 'is-open': this.isOpen,\n 'open-top': this.openTop,\n disabled: this.disabled,\n })}\n ?disabled=${this.disabled}\n popovertarget=\"menu-popover\"\n aria-expanded=${this.isOpen}\n aria-haspopup=\"menu\"\n @keydown=${this.handleTriggerKeydown}\n >\n <div class=\"visible-wrapper\">\n <div class=\"content-container\">\n ${\n this.hasIcon\n ? html`\n <div class=\"icon-container\"><slot name=\"icon\"></slot></div>\n `\n : nothing\n }\n ${\n this.label\n ? html` <div class=\"label-container\">${this.label}</div> `\n : nothing\n }\n </div>\n <div class=\"arrow-flyout-container\">\n <obi-arrow-flyout-google></obi-arrow-flyout-google>\n </div>\n </div>\n\n \n </button>\n <obc-context-menu-input\n popover=\"auto\"\n id=\"menu-popover\"\n class=\"positioned-menu\"\n .type=${this.effectiveMenuType}\n .options=${this.options}\n .selectedValues=${this.selectedValues}\n .multiSelect=${this.isMultiSelect}\n .selectPerGroup=${this.effectiveSelectPerGroup}\n .hasTitleBar=${this.hasTitleBar}\n .title=${this.menuTitle}\n .columnGroups=${this.columnGroups}\n .itemsPerColumn=${this.itemsPerColumn}\n @change=${this.handleMenuChange}\n @item-click=${this.handleItemClick}\n @close=${this.handleMenuClose}\n @toggle=${this.handlePopoverToggle}\n /></obc-context-menu-input>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-menu-button': ObcMenuButton;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAmIO,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA;AAKqB,SAAA,QAAQ;AAWT,SAAA,UAA+B,CAAA;AAM/B,SAAA,iBAA2B,CAAA;AAMzB,SAAA,YAAY;AAMZ,SAAA,UAAU;AAcrC,SAAA,WAA4B,gBAAgB;AAmBjB,SAAA,cAAc;AAKf,SAAA,YAAY;AAMb,SAAA,eAA8B,CAAA;AAM7B,SAAA,iBAAiB;AAMhB,SAAA,UAAU;AAMV,SAAA,WAAW;AAE7B,SAAQ,SAAS;AAE1B,SAAQ,sBAAsB;AAE9B,SAAQ,oBAAmD;AA8B3D,SAAQ,sBAAsB,CAAC,MAAmB;AAChD,WAAK,SAAS,EAAE,aAAa;AAC7B,UAAI,EAAE,aAAa,QAAQ;AACzB,aAAK,KAAK,mBAAA;AAKV,aAAK,cAAc,IAAI,YAAY,MAAM,CAAC;AAAA,MAC5C;AACA,UAAI,EAAE,aAAa,UAAU;AAC3B,YAAI,KAAK,qBAAqB;AAC5B,eAAK,sBAAsB;AAC3B,eAAK,eAAe,MAAA;AAAA,QACtB;AAKA,aAAK,cAAc,IAAI,YAAY,OAAO,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EAAA;AAAA,EA7CA,IAAY,uBAAgC;AAC1C,QAAI,KAAK,gBAAgB,OAAW,QAAO,KAAK;AAGhD,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,IAAA,EAChB,SAAS,KAAK,QAAQ;AAAA,EAC1B;AAAA,EAEA,IAAY,oBAAqC;AAE/C,QACE,KAAK,wBACL,KAAK,aAAa,gBAAgB,SAClC;AACA,aAAO,gBAAgB;AAAA,IACzB;AAEA,WAAO,KAAK;AAAA,EACd;AAAA,EAyBA,MAAc,qBAAqB;AACjC,UAAM,KAAK;AACX,QAAI,KAAK,sBAAsB,QAAQ;AACrC,WAAK,MAAM,cAAA;AAAA,IACb,WAAW,KAAK,sBAAsB,SAAS;AAC7C,WAAK,MAAM,eAAA;AAAA,IACb,OAAO;AACL,WAAK,MAAM,kBAAA;AAAA,IACb;AACA,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEQ,SAAS,gBAA+C,YAAY;AAC1E,QAAI,KAAK,SAAU;AAEnB,SAAK,oBAAoB;AACzB,SAAK,MAAM,YAAA;AAAA,EACb;AAAA,EAEQ,qBAAqB,OAAsB;AACjD,QAAI,KAAK,SAAU;AAEnB,YAAQ,MAAM,KAAA;AAAA,MACZ,KAAK;AACH,cAAM,eAAA;AACN,aAAK,SAAS,OAAO;AACrB;AAAA,MACF,KAAK;AACH,cAAM,eAAA;AACN,aAAK,SAAS,MAAM;AACpB;AAAA,MACF,KAAK;AACH,cAAM,eAAA;AACN,aAAK,SAAS,OAAO;AACrB;AAAA,MACF,KAAK;AACH,cAAM,eAAA;AACN,aAAK,SAAS,MAAM;AACpB;AAAA,IAEA;AAAA,EAEN;AAAA,EAEQ,iBACN,GAIA;AACA,SAAK,iBAAiB,EAAE,OAAO;AAM/B,SAAK,cAAc,IAAI,YAAY,UAAU,EAAC,QAAQ,EAAE,OAAA,CAAO,CAAC;AAChE,QAAI,CAAC,KAAK,sBAAsB;AAC9B,WAAK,gBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,gBACN,GACA;AAKA,SAAK,cAAc,IAAI,YAAY,cAAc,EAAC,QAAQ,EAAE,OAAA,CAAO,CAAC;AACpE,UAAM,SAAS,EAAE,OAAO;AACxB,QAAI,OAAO,UAAU,QAAQ;AAC3B;AAAA,IACF;AAEA,UAAM,eACJ,KAAK,aAAa,gBAAgB,UAClC,KAAK,aAAa,gBAAgB;AAEpC,QAAI,gBAAgB,CAAC,KAAK,sBAAsB;AAC9C,WAAK,gBAAA;AACL;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAkB;AACxB,QAAI,KAAK,SAAS,OAAW;AAC7B,SAAK,sBAAsB;AAC3B,SAAK,KAAK,YAAA;AAAA,EACZ;AAAA,EAEA,IAAY,gBAAyB;AACnC,QAAI,KAAK,gBAAgB,OAAW,QAAO,KAAK;AAChD,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,IAAA,EAChB,SAAS,KAAK,QAAQ;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAY,0BAAmC;AAC7C,WAAO,CAAC,KAAK,iBAAiB,CAAC,CAAC,KAAK;AAAA,EACvC;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA,gBAEK,SAAS;AAAA,MACf,SAAS;AAAA,MACT,cAAc,KAAK;AAAA,MACnB,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,UAAU,KAAK;AAAA,IAAA,CAChB,CAAC;AAAA,oBACU,KAAK,QAAQ;AAAA;AAAA,wBAET,KAAK,MAAM;AAAA;AAAA,mBAEhB,KAAK,oBAAoB;AAAA;AAAA;AAAA;AAAA,cAK9B,KAAK,UACD;AAAA;AAAA,sBAGA,OACN;AAAA,cAEE,KAAK,QACD,qCAAqC,KAAK,KAAK,YAC/C,OACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAaM,KAAK,iBAAiB;AAAA,qBACnB,KAAK,OAAO;AAAA,4BACL,KAAK,cAAc;AAAA,yBACtB,KAAK,aAAa;AAAA,4BACf,KAAK,uBAAuB;AAAA,yBAC/B,KAAK,WAAW;AAAA,mBACtB,KAAK,SAAS;AAAA,0BACP,KAAK,YAAY;AAAA,4BACf,KAAK,cAAc;AAAA,oBAC3B,KAAK,gBAAgB;AAAA,wBACjB,KAAK,eAAe;AAAA,mBACzB,KAAK,eAAe;AAAA,oBACnB,KAAK,mBAAmB;AAAA;AAAA;AAAA,EAG1C;AAGF;AAjUa,cAgUK,SAAS,UAAU,YAAY;AA3TrB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,cAKe,WAAA,SAAA,CAAA;AAWD,gBAAA;AAAA,EAAxB,SAAS,EAAC,MAAM,MAAA,CAAM;AAAA,GAhBZ,cAgBc,WAAA,WAAA,CAAA;AAMA,gBAAA;AAAA,EAAxB,SAAS,EAAC,MAAM,MAAA,CAAM;AAAA,GAtBZ,cAsBc,WAAA,kBAAA,CAAA;AAME,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA5Bd,cA4BgB,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAlCd,cAkCgB,WAAA,WAAA,CAAA;AAc3B,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA/Cb,cAgDX,WAAA,YAAA,CAAA;AAO2B,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAvDd,cAuDgB,WAAA,eAAA,CAAA;AAMA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA7Dd,cA6DgB,WAAA,kBAAA,CAAA;AAMA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAnEd,cAmEgB,WAAA,eAAA,CAAA;AAKD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAxEb,cAwEe,WAAA,aAAA,CAAA;AAMD,gBAAA;AAAA,EAAxB,SAAS,EAAC,MAAM,MAAA,CAAM;AAAA,GA9EZ,cA8Ec,WAAA,gBAAA,CAAA;AAMC,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GApFb,cAoFe,WAAA,kBAAA,CAAA;AAMC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA1Fd,cA0FgB,WAAA,WAAA,CAAA;AAMA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAhGd,cAgGgB,WAAA,YAAA,CAAA;AAEV,gBAAA;AAAA,EAAhB,MAAA;AAAM,GAlGI,cAkGM,WAAA,UAAA,CAAA;AAMkB,gBAAA;AAAA,EAAlC,MAAM,kBAAkB;AAAA,GAxGd,cAwGwB,WAAA,QAAA,CAAA;AAEF,gBAAA;AAAA,EAAhC,MAAM,gBAAgB;AAAA,GA1GZ,cA0GsB,WAAA,iBAAA,CAAA;AA1GtB,gBAAN,gBAAA;AAAA,EADN,cAAc,iBAAiB;AAAA,GACnB,aAAA;"}
|
|
1
|
+
{"version":3,"file":"menu-button.js","sources":["../../../src/components/menu-button/menu-button.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing} from 'lit';\nimport {property, state, query} from 'lit/decorators.js';\nimport compentStyle from './menu-button.css?inline';\nimport {customElement} from '../../decorator.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../../icons/icon-arrow-flyout-google.js';\nimport '../button/button.js';\nimport '../context-menu-input/context-menu-input.js';\nimport {\n ContextMenuType,\n ContextMenuOption,\n ColumnGroup,\n} from '../context-menu-input/context-menu-input.js';\nimport type {ObcContextMenuInput} from '../context-menu-input/context-menu-input.js';\n\nexport type ObcSplitButtonChangeEvent = CustomEvent<{\n selectedValues: string[];\n selectedOptions: Array<ContextMenuOption>;\n}>;\n\nexport type ObcMenuButtonItemClickEvent = CustomEvent<{\n value: string;\n option: ContextMenuOption;\n}>;\n\n/**\n * `<obc-menu-button>` – A dropdown menu button for selecting one or more options from a contextual menu.\n *\n * Provides a button that opens a configurable context menu, supporting single or multi-select, nested/flyout submenus, and multi-column layouts. The button can display a label, an optional icon, and adapts to various menu types (regular, checkboxes, flyout, multi-column, etc.).\n *\n * Appears as a compact button that, when clicked, reveals a menu for actions, filtering, or grouped selections. Useful for toolbars, filter bars, or anywhere contextual actions or selections are needed without taking up persistent space.\n *\n * ## Features\n * - **Menu Types:** Supports multiple menu variants via `menuType`:\n * - `Regular`: Standard single-select menu (action menu).\n * - `Checkboxes`: Multi-select with checkboxes.\n * - `NestedCheckboxes`: Hierarchical multi-select with nested checkboxes.\n * - `Flyout`: Multi-level flyout menu (supports nested groups).\n * - `Multi`: Multi-column menu (for large option sets).\n * - `MultiWithSubtitles`: Multi-column menu with group subtitles.\n * - **Selection Modes:**\n * - Single-select or multi-select (controlled by `multiSelect` and `menuType`).\n * - Per-group selection (only one item per group/column, via `selectPerGroup`).\n * - Optionally persist selection state (`persistSelection`).\n * - **Layout Options:**\n * - Full width (`fullWidth`) or fit-content.\n * - Menu can open above or below the button (`openTop`).\n * - Multi-column and grouped layouts (`columnGroups`, `itemsPerColumn`).\n * - Optional title bar with close button (`hasTitleBar`, `menuTitle`).\n * - **Content Customization:**\n * - Optional icon slot in button (`hasIcon`).\n * - Option icons and hierarchical/nested option structures.\n * - **Accessibility & Keyboard:**\n * - Keyboard navigation and ARIA roles.\n * - Disabled state disables both button and menu.\n * - **Events:**\n * - Emits `change` when selection changes.\n * - Emits `item-click` when an item is clicked.\n * - Emits `close` when the menu closes.\n *\n * ## Usage Guidelines\n * Use `obc-menu-button` to present a compact button that reveals a contextual menu for actions, filtering, or grouped selections. Ideal for toolbars, filter bars, or overflow menus where space is limited but multiple or hierarchical options are needed. Choose the menu type and selection mode based on your use case:\n * - Use `menuType=\"Regular\"` for simple single-action menus.\n * - Use `multiSelect` or `menuType=\"Checkboxes\"` for multi-select scenarios (e.g., filtering).\n * - Use `menuType=\"Flyout\"` for hierarchical or grouped actions.\n * - Use `menuType=\"Multi\"` or `menuType=\"MultiWithSubtitles\"` for large sets of options, grouped or split across columns.\n * - Use the icon slot for visual context (e.g., filter, settings, actions).\n * - Avoid using for persistent navigation—this is for contextual, transient actions or selections.\n *\n * **TODO(designer):** Confirm recommended use cases for each menu type and when to use per-group selection.\n *\n * ## Slots\n * | Slot Name | Renders When... | Purpose |\n * |-----------|---------------------|-----------------------------------------|\n * | `icon` | `hasIcon` is true | Icon displayed at the start of the button. |\n *\n * ## Properties & Attributes\n * - `label`: Text label shown on the button.\n * - `options`: Array of menu options (each with value, label, optional icon, children, etc.).\n * - `selectedValues`: Array of currently selected option values.\n * - `fullWidth`: If true, button stretches to fill its container.\n * - `hasIcon`: If true, shows the `icon` slot.\n * - `menuType`: Controls menu variant (see Features above). Defaults to `Regular`.\n * - `multiSelect`: If true, enables multi-select (overrides default for menuType).\n * - `selectPerGroup`: If true, only one selection per group/column (flyout/multi-column).\n * - `hasTitleBar`: If true, shows a title bar with close button in the menu.\n * - `menuTitle`: Title text for the menu (if `hasTitleBar` is true).\n * - `columnGroups`: Used for `multi-with-subtitles` layout; defines grouped columns.\n * - `itemsPerColumn`: Number of items per column in multi-column layouts.\n * - `openTop`: If true, menu opens above the button.\n * - `disabled`: Disables both the button and the menu.\n *\n * ## Events\n * - `change` – Fired when the menu selection changes (returns selected values and options).\n * - `item-click` – Fired when a menu item is clicked (returns value and option).\n * - `open` – Fired when the menu is opened.\n * - `close` – Fired when the menu is closed.\n *\n * ## Best Practices & Constraints\n * - Only use multi-select for scenarios where users may need to select multiple items (e.g., filters, bulk actions).\n * - For action menus (single-select, no persistence), set `persistSelection` to false.\n * - Use per-group selection (`selectPerGroup`) for grouped flyout or multi-column menus where only one selection per group is allowed.\n * - Avoid nesting too deeply in flyout menus for usability.\n * - If using icons in options, supply them via the `icon` property of each option (e.g., `<obi-placeholder></obi-placeholder>`).\n * - The button is fully keyboard accessible and supports ARIA roles for menu and menuitem.\n * - Menu closes automatically on selection (unless in multi-select mode).\n *\n * ## Example\n * ```html\n * <obc-menu-button\n * label=\"Actions\"\n * .options=${[\n * { value: 'edit', label: 'Edit', icon: html`<obi-placeholder></obi-placeholder>` },\n * { value: 'delete', label: 'Delete' }\n * ]}\n * .selectedValues=${['edit']}\n * hasIcon\n * >\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-menu-button>\n * ```\n * In this example, the button displays an icon and label, and opens a menu with two options (one with an icon).\n *\n * @slot icon - Icon displayed at the start of the button when `hasIcon` is true.\n * @fires {ObcSplitButtonChangeEvent} change - Fired when the menu selection changes.\n * @fires {ObcMenuButtonItemClickEvent} item-click - Fired when a menu item is clicked.\n * @fires {CustomEvent<void>} open - Fired when the menu is opened.\n * @fires {CustomEvent<void>} close - Fired when the menu is closed.\n * @beta\n */\n@customElement('obc-menu-button')\nexport class ObcMenuButton extends LitElement {\n /**\n * The label displayed on the button.\n * If empty, the button can be rendered as icon-only.\n */\n @property({type: String}) label = '';\n\n /**\n * Array of menu options with value, label, and optional level, icon, and children.\n * Each option can include:\n * - `value`: Unique string identifier.\n * - `label`: Display text.\n * - `icon`: Optional icon (e.g., `<obi-placeholder></obi-placeholder>`).\n * - `children`: Optional array of child options (for nested/flyout menus).\n * - `level`: Optional nesting level (for hierarchical menus).\n */\n @property({type: Array}) options: ContextMenuOption[] = [];\n\n /**\n * Array of currently selected option values.\n * Used to control which options are checked/selected in the menu.\n */\n @property({type: Array}) selectedValues: string[] = [];\n\n /**\n * Whether the button should fill the full width of its container.\n * If true, the button stretches to 100% width.\n */\n @property({type: Boolean}) fullWidth = false;\n\n /**\n * Whether the button should show an icon slot.\n * If true, the `icon` slot is rendered at the start of the button.\n */\n @property({type: Boolean}) hasIcon = false;\n\n /**\n * The variant type of context menu to display.\n * Determines menu layout and selection behavior.\n * - `Regular`: Standard single-select.\n * - `Checkboxes`: Multi-select with checkboxes.\n * - `NestedCheckboxes`: Hierarchical multi-select.\n * - `Flyout`: Multi-level flyout menu.\n * - `Multi`: Multi-column menu.\n * - `MultiWithSubtitles`: Multi-column with group subtitles.\n * @default ContextMenuType.Regular\n */\n @property({type: String})\n menuType: ContextMenuType = ContextMenuType.Regular;\n\n /**\n * Whether multiple selections are allowed.\n * Overrides the default selection mode for the chosen variant.\n * If not explicitly set, defaults based on `menuType`.\n */\n @property({type: Boolean}) multiSelect?: boolean;\n\n /**\n * Allows single selection per group (flyout/multi-column only).\n * When true, only one item per group/column can be selected.\n */\n @property({type: Boolean}) selectPerGroup?: boolean;\n\n /**\n * Whether to show a title bar with close button at the top of the menu.\n * If true, the menu displays a title bar (use `menuTitle` for text).\n */\n @property({type: Boolean}) hasTitleBar = false;\n\n /**\n * Title text displayed in the title bar (if `hasTitleBar` is true).\n */\n @property({type: String}) menuTitle = '';\n\n /**\n * Array of column groups for the `multi-with-subtitles` layout.\n * Used to define grouped columns with subtitles in multi-column menus.\n */\n @property({type: Array}) columnGroups: ColumnGroup[] = [];\n\n /**\n * Number of items per column in multi-column layouts.\n * Used for `Multi` and `MultiWithSubtitles` menu types.\n */\n @property({type: Number}) itemsPerColumn = 5;\n\n /**\n * Render the dropdown context menu above or below the button.\n * If true, the menu opens above the button; otherwise, it opens below.\n */\n @property({type: Boolean}) openTop = false;\n\n /**\n * Whether both parts of the button are disabled.\n * Disables both the button and the menu.\n */\n @property({type: Boolean}) disabled = false;\n\n @state() private isOpen = false;\n\n private restoreFocusOnClose = false;\n\n private menuFocusStrategy: 'first' | 'selected' | 'last' = 'selected';\n\n @query('.positioned-menu') private menu?: HTMLElement & ObcContextMenuInput;\n\n @query('button.wrapper') private triggerButton?: HTMLButtonElement;\n\n private get effectiveMultiSelect(): boolean {\n if (this.multiSelect !== undefined) return this.multiSelect;\n\n // Auto-determine based on menuType only for types that are inherently multi-select\n return [\n ContextMenuType.Checkboxes,\n ContextMenuType.NestedCheckboxes,\n ContextMenuType.Multi,\n ContextMenuType.MultiWithSubtitles,\n ].includes(this.menuType);\n }\n\n private get effectiveMenuType(): ContextMenuType {\n // Only rewrite regular->checkboxes for multi, never flyout\n if (\n this.effectiveMultiSelect &&\n this.menuType === ContextMenuType.Regular\n ) {\n return ContextMenuType.Checkboxes;\n }\n // DO NOT map Flyout to NestedCheckboxes!\n return this.menuType;\n }\n\n private handlePopoverToggle = (e: ToggleEvent) => {\n this.isOpen = e.newState === 'open';\n if (e.newState === 'open') {\n void this.focusMenuAfterOpen();\n /**\n * Fired when the menu is opened.\n * @event open\n * @type {CustomEvent<void>}\n */\n this.dispatchEvent(new CustomEvent('open'));\n }\n if (e.newState === 'closed') {\n if (this.restoreFocusOnClose) {\n this.restoreFocusOnClose = false;\n this.triggerButton?.focus();\n }\n /**\n * Fired when the menu is closed.\n * @event close\n * @type {CustomEvent<void>}\n */\n this.dispatchEvent(new CustomEvent('close'));\n }\n };\n\n private async focusMenuAfterOpen() {\n await this.updateComplete;\n if (this.menuFocusStrategy === 'last') {\n this.menu?.focusLastItem();\n } else if (this.menuFocusStrategy === 'first') {\n this.menu?.focusFirstItem();\n } else {\n this.menu?.focusSelectedItem();\n }\n this.menuFocusStrategy = 'selected';\n }\n\n private openMenu(focusStrategy: 'first' | 'selected' | 'last' = 'selected') {\n if (this.disabled) return;\n\n this.menuFocusStrategy = focusStrategy;\n this.menu?.showPopover();\n }\n\n private handleTriggerKeydown(event: KeyboardEvent) {\n if (this.disabled) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.openMenu('first');\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.openMenu('last');\n break;\n case 'Home':\n event.preventDefault();\n this.openMenu('first');\n break;\n case 'End':\n event.preventDefault();\n this.openMenu('last');\n break;\n default:\n break;\n }\n }\n\n private handleMenuChange(\n e: CustomEvent<{\n selectedValues: string[];\n selectedOptions: ContextMenuOption[];\n }>\n ) {\n this.selectedValues = e.detail.selectedValues;\n\n /**\n * Fired when the menu selection changes.\n * @event change\n * @type {CustomEvent<{selectedValues: string[], selectedOptions: Array<ContextMenuOption>}>}\n */\n this.dispatchEvent(new CustomEvent('change', {detail: e.detail}));\n if (!this.effectiveMultiSelect) {\n this.handleMenuClose();\n }\n }\n\n private handleItemClick(\n e: CustomEvent<{value: string; option: ContextMenuOption}>\n ) {\n /**\n * Fired when a menu item is clicked.\n * @event item-click\n * @type {CustomEvent<{value: string, option: ContextMenuOption}>}\n */\n this.dispatchEvent(new CustomEvent('item-click', {detail: e.detail}));\n const option = e.detail.option;\n if (option.children?.length) {\n return;\n }\n\n const isFlyoutMenu =\n this.menuType === ContextMenuType.Flyout ||\n this.menuType === ContextMenuType.NestedCheckboxes;\n\n if (isFlyoutMenu && !this.effectiveMultiSelect) {\n this.handleMenuClose();\n return;\n }\n }\n\n private handleMenuClose() {\n if (this.menu === undefined) return;\n this.restoreFocusOnClose = true;\n this.menu.hidePopover();\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.menuType);\n }\n\n // Only meaningful if not multi-select AND persistSelection is true\n private get effectiveSelectPerGroup(): boolean {\n return !this.isMultiSelect && !!this.selectPerGroup;\n }\n\n override render() {\n return html`\n <button\n class=${classMap({\n wrapper: true,\n 'full-width': this.fullWidth,\n 'is-open': this.isOpen,\n 'open-top': this.openTop,\n disabled: this.disabled,\n })}\n ?disabled=${this.disabled}\n popovertarget=\"menu-popover\"\n aria-expanded=${this.isOpen}\n aria-haspopup=\"menu\"\n @keydown=${this.handleTriggerKeydown}\n >\n <div class=\"visible-wrapper\">\n <div class=\"content-container\">\n ${\n this.hasIcon\n ? html`\n <div class=\"icon-container\"><slot name=\"icon\"></slot></div>\n `\n : nothing\n }\n ${\n this.label\n ? html` <div class=\"label-container\">${this.label}</div> `\n : nothing\n }\n </div>\n <div class=\"arrow-flyout-container\">\n <obi-arrow-flyout-google></obi-arrow-flyout-google>\n </div>\n </div>\n\n \n </button>\n <obc-context-menu-input\n popover=\"auto\"\n id=\"menu-popover\"\n class=\"positioned-menu\"\n .type=${this.effectiveMenuType}\n .options=${this.options}\n .selectedValues=${this.selectedValues}\n .multiSelect=${this.isMultiSelect}\n .selectPerGroup=${this.effectiveSelectPerGroup}\n .hasTitleBar=${this.hasTitleBar}\n .title=${this.menuTitle}\n .columnGroups=${this.columnGroups}\n .itemsPerColumn=${this.itemsPerColumn}\n @change=${this.handleMenuChange}\n @item-click=${this.handleItemClick}\n @close=${this.handleMenuClose}\n @toggle=${this.handlePopoverToggle}\n /></obc-context-menu-input>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-menu-button': ObcMenuButton;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -83,7 +83,7 @@ import '../tree-navigation-item/tree-navigation-item.js';
|
|
|
83
83
|
*
|
|
84
84
|
* @slot icon - Leading icon slot (optional, shown if provided). Set `hasIcon` to `true` to show the icon.
|
|
85
85
|
* @slot trailing-icon - Trailing icon slot (optional, shown if provided). Set `hasTrailingIcon` to `true` to show.
|
|
86
|
-
* @fires
|
|
86
|
+
* @fires click - Fired when the navigation item is clicked, either as a link or as a button.
|
|
87
87
|
* @stable
|
|
88
88
|
*/
|
|
89
89
|
export declare class ObcNavigationItem extends LitElement {
|
|
@@ -144,10 +144,6 @@ export declare class ObcNavigationItem extends LitElement {
|
|
|
144
144
|
alerts?: TreeNavigationItemAlerts;
|
|
145
145
|
private anchorElement?;
|
|
146
146
|
private treeItemElement?;
|
|
147
|
-
/**
|
|
148
|
-
* @fires {CustomEvent<void>} click - Fired when the navigation item is clicked (either as a link or button).
|
|
149
|
-
*/
|
|
150
|
-
onClick(): void;
|
|
151
147
|
private handleKeydown;
|
|
152
148
|
focus(options?: FocusOptions): void;
|
|
153
149
|
private getItemRole;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-item.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-item/navigation-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,yCAAyC,CAAC;AACjD,OAAO,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAE/E,OAAO,iDAAiD,CAAC;AACzD,OAAO,EACL,cAAc,EAEd,KAAK,wBAAwB,EAC9B,MAAM,iDAAiD,CAAC;AAOzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AAEH,qBACa,iBAAkB,SAAQ,UAAU;IAC/C;;;;OAIG;IACuB,KAAK,SAAW;IAE1C;;;;OAIG;IACuB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnD;;;OAGG;IACwB,OAAO,UAAS;IAE3C;;;;OAIG;IACuB,OAAO,2BAAiC;IAElE;;;OAGG;IACwB,KAAK,UAAS;IAEzC;;;;OAIG;IACwB,aAAa,UAAS;IAEjD;;OAEG;IACuC,OAAO,UAAS;IAE1D,uDAAuD;IAC5B,eAAe,UAAS;IAEnD,yFAAyF;IAC9D,QAAQ,UAAS;IAE5C,4EAA4E;IACnD,YAAY,EAAE,cAAc,EAAE,CAAM;IAE7D;;;OAGG;IACuB,YAAY,EAAE,MAAM,CAA4B;IAE1E;;;;OAIG;IACuB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAEhD,OAAO,CAAC,aAAa,CAAC,CAAoB;IAGnB,OAAO,CAAC,eAAe,CAAC,CAAc;IAEzE
|
|
1
|
+
{"version":3,"file":"navigation-item.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-item/navigation-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,yCAAyC,CAAC;AACjD,OAAO,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAE/E,OAAO,iDAAiD,CAAC;AACzD,OAAO,EACL,cAAc,EAEd,KAAK,wBAAwB,EAC9B,MAAM,iDAAiD,CAAC;AAOzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AAEH,qBACa,iBAAkB,SAAQ,UAAU;IAC/C;;;;OAIG;IACuB,KAAK,SAAW;IAE1C;;;;OAIG;IACuB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnD;;;OAGG;IACwB,OAAO,UAAS;IAE3C;;;;OAIG;IACuB,OAAO,2BAAiC;IAElE;;;OAGG;IACwB,KAAK,UAAS;IAEzC;;;;OAIG;IACwB,aAAa,UAAS;IAEjD;;OAEG;IACuC,OAAO,UAAS;IAE1D,uDAAuD;IAC5B,eAAe,UAAS;IAEnD,yFAAyF;IAC9D,QAAQ,UAAS;IAE5C,4EAA4E;IACnD,YAAY,EAAE,cAAc,EAAE,CAAM;IAE7D;;;OAGG;IACuB,YAAY,EAAE,MAAM,CAA4B;IAE1E;;;;OAIG;IACuB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAEhD,OAAO,CAAC,aAAa,CAAC,CAAoB;IAGnB,OAAO,CAAC,eAAe,CAAC,CAAc;IAEzE,OAAO,CAAC,aAAa;IAYL,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAInD,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,eAAe;IAUd,MAAM;IA8Ef,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,qBAAqB,EAAE,iBAAiB,CAAC;KAC1C;CACF"}
|
|
@@ -31,12 +31,6 @@ let ObcNavigationItem = class extends LitElement {
|
|
|
31
31
|
this.treeBranches = [];
|
|
32
32
|
this.terminalType = TreeTerminalType.regular;
|
|
33
33
|
}
|
|
34
|
-
/**
|
|
35
|
-
* @fires {CustomEvent<void>} click - Fired when the navigation item is clicked (either as a link or button).
|
|
36
|
-
*/
|
|
37
|
-
onClick() {
|
|
38
|
-
dispatchEvent(new CustomEvent("click"));
|
|
39
|
-
}
|
|
40
34
|
handleKeydown(event) {
|
|
41
35
|
const isMenuItem = this.getAttribute("role") === "menuitem";
|
|
42
36
|
if (this.href !== void 0 && !isMenuItem) return;
|
|
@@ -76,7 +70,6 @@ let ObcNavigationItem = class extends LitElement {
|
|
|
76
70
|
.href=${this.href}
|
|
77
71
|
.terminalType=${this.terminalType}
|
|
78
72
|
.alerts=${this.alerts}
|
|
79
|
-
@click=${this.onClick}
|
|
80
73
|
>
|
|
81
74
|
${this.hasIcon ? html`<slot name="icon" slot="icon"></slot>` : nothing}
|
|
82
75
|
</obc-tree-navigation-item>
|
|
@@ -94,7 +87,6 @@ let ObcNavigationItem = class extends LitElement {
|
|
|
94
87
|
[this.variant]: true
|
|
95
88
|
})}"
|
|
96
89
|
href=${ifDefined(this.href)}
|
|
97
|
-
@click=${this.onClick}
|
|
98
90
|
@keydown=${this.handleKeydown}
|
|
99
91
|
tabindex=${ifDefined(this.getItemTabIndex())}
|
|
100
92
|
role=${ifDefined(this.getItemRole())}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-item.js","sources":["../../../src/components/navigation-item/navigation-item.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query} from 'lit/decorators.js';\nimport compentStyle from './navigation-item.css?inline';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport '../../icons/icon-arrow-flyout-google.js';\nimport {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';\nimport {customElement} from '../../decorator.js';\nimport '../tree-navigation-item/tree-navigation-item.js';\nimport {\n TreeBranchType,\n TreeTerminalType,\n type TreeNavigationItemAlerts,\n} from '../tree-navigation-item/tree-navigation-item.js';\n\nenum NavigationItemRole {\n Button = 'button',\n MenuItem = 'menuitem',\n}\n\n/**\n * `<obc-navigation-item>` – A navigation menu item component for use in navigation bars, side menus, or toolbars.\n *\n * Displays a selectable navigation option, optionally with an icon and support for different visual variants. Can be used as a link or as a button within navigation menus, supporting both single items and grouped menu structures.\n *\n * Appears as a horizontal or vertical item, with optional icon, label, and flyout indicator for nested or grouped navigation. Designed for use in navigation menus, toolbars, or any UI requiring a consistent, interactive navigation element.\n *\n * ## Features\n * - **Variants:**\n * - `Full` (default): Standard navigation item with icon (optional), label, and optional flyout indicator for groups.\n * - `IconOnly`: Displays only the icon, suitable for compact or icon-based navigation menus.\n * - `IconOnlyLarge`: Larger icon-only variant for prominent navigation actions.\n * - `Compact`: Smaller, vertically-stacked layout with icon and label, optimized for space-constrained menus.\n * - **Icon Support:**\n * - Leading icon can be provided via the `icon` slot.\n * - Icon presence is automatically detected and styled.\n * - **Label:**\n * - Text label shown unless in icon-only variants.\n * - **Checked State:**\n * - Indicates the currently selected or active navigation item.\n * - **Group Mode:**\n * - When `group` is true, displays a flyout indicator (arrow) and supports group selection highlighting.\n * - **Link Support:**\n * - Can be rendered as a link via the `href` property, or as a button if `href` is not set.\n * - **Accessibility:**\n * - Uses semantic anchor element for navigation.\n *\n * ## Usage Guidelines\n * Use `obc-navigation-item` for interactive navigation options within menus, toolbars, or navigation drawers.\n * - Ideal for main or secondary navigation, especially where visual consistency and flexible layout are needed.\n * - Use the `Full` variant for standard navigation lists with both icon and label.\n * - Use `IconOnly` or `IconOnlyLarge` for toolbars or sidebars where space is limited or icon-only navigation is preferred.\n * - Use `Compact` for dense menus or when vertical stacking of icon and label is desired.\n * - Set `checked` to highlight the currently active or selected item.\n * - Use `group` and `groupSelected` to indicate grouped navigation and selection within groups.\n * - Provide an icon via the `icon` slot for visual context (e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>).\n * - Use `href` to make the item a link; omit for button-like behavior.\n * - Use `::part(label)` CSS pseudo-element to style the label.\n *\n * **TODO(designer):** Clarify if there are recommended icon choices or label length constraints for each variant.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|---------|\n * | icon | Always (optional) | Leading icon for the navigation item. Place an icon such as `<obi-placeholder slot=\"icon\"></obi-placeholder>`. |\n *\n * ## Properties and Attributes\n * - `label` (string): The text label for the navigation item. Hidden in icon-only variants.\n * - `href` (string, optional): If set, the item is rendered as a link. If undefined, acts as a button.\n * - `checked` (boolean): Marks the item as selected/active.\n * - `variant` (string): Controls the visual style. One of `Full`, `IconOnly`, `IconOnlyLarge`, or `Compact`.\n * - `group` (boolean): Enables group mode, showing a flyout indicator and supporting group selection.\n * - `groupSelected` (boolean): Highlights the item as selected within a group.\n * - `hasIcon` (boolean): Whether the item has a leading icon.\n *\n * ## Events\n * - `click` – Fired when the navigation item is clicked (either as a link or button).\n *\n * ## Best Practices and Constraints\n * - Only use one navigation item as `checked` at a time within a menu to indicate the current location.\n * - For icon-only variants, ensure the icon clearly represents the navigation action.\n * - Use `group` for items that open submenus or represent grouped navigation.\n * - Avoid long labels in compact or icon-only variants to maintain layout integrity.\n * - For accessibility, provide meaningful labels and icons.\n *\n * ## Example:\n * ```\n * <obc-navigation-item\n * label=\"Dashboard\"\n * href=\"/dashboard\"\n * checked\n * variant=\"Full\"\n * >\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-navigation-item>\n * ```\n *\n * @slot icon - Leading icon slot (optional, shown if provided). Set `hasIcon` to `true` to show the icon.\n * @slot trailing-icon - Trailing icon slot (optional, shown if provided). Set `hasTrailingIcon` to `true` to show.\n * @fires {CustomEvent<void>} click - Fired when the navigation item is clicked.\n * @stable\n */\n\n@customElement('obc-navigation-item')\nexport class ObcNavigationItem extends LitElement {\n /**\n * The text label displayed for the navigation item.\n * Hidden in icon-only variants.\n * @availableWhen variant in [Full, Compact]\n */\n @property({type: String}) label = 'Label';\n\n /**\n * The URL to navigate to when the item is clicked.\n * If set, the item is rendered as a link (`<a href=\"...\" />`).\n * If undefined, acts as a button.\n */\n @property({type: String}) href: string | undefined;\n\n /**\n * Whether the navigation item is currently selected/active.\n * Use to indicate the current location or selection.\n */\n @property({type: Boolean}) checked = false;\n\n /**\n * Visual variant of the navigation item.\n * One of `Full` (default), `IconOnly`, `IconOnlyLarge`, or `Compact`.\n * Controls layout and visibility of icon/label.\n */\n @property({type: String}) variant = ObcNavigationMenuVariant.Full;\n\n /**\n * Enables group mode for the item, displaying a flyout indicator and supporting group selection.\n * Use for items that open submenus or represent grouped navigation.\n */\n @property({type: Boolean}) group = false;\n\n /**\n * Highlights the item as selected within a group.\n * Only relevant when `group` is true.\n * @availableWhen group==true\n */\n @property({type: Boolean}) groupSelected = false;\n\n /**\n * Whether the item has a leading icon.\n */\n @property({type: Boolean, reflect: true}) hasIcon = false;\n\n /** @availableWhen group==false || variant==IconOnly */\n @property({type: Boolean}) hasTrailingIcon = false;\n\n /** Set by `obc-navigation-menu` in its Tree variant — renders the row as a tree item. */\n @property({type: Boolean}) treeMode = false;\n\n /** Indentation columns for tree mode, assigned by `obc-navigation-menu`. */\n @property({type: Array}) treeBranches: TreeBranchType[] = [];\n\n /**\n * Terminal type for the row in the Tree variant — one of `regular` (default),\n * `aggregated-header`, or `group-header`. Has no effect in the flat variants.\n */\n @property({type: String}) terminalType: string = TreeTerminalType.regular;\n\n /**\n * Per-severity alert counts shown as trailing badge(s) (Tree variant only).\n * Forwarded to the underlying `obc-tree-navigation-item`. See\n * {@link TreeNavigationItemAlerts}.\n */\n @property({type: Object}) alerts?: TreeNavigationItemAlerts;\n\n @query('a') private anchorElement?: HTMLAnchorElement;\n\n // In tree mode the row renders an `obc-tree-navigation-item` instead of an `<a>`.\n @query('obc-tree-navigation-item') private treeItemElement?: HTMLElement;\n\n /**\n * @fires {CustomEvent<void>} click - Fired when the navigation item is clicked (either as a link or button).\n */\n onClick() {\n dispatchEvent(new CustomEvent('click'));\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const isMenuItem =\n this.getAttribute('role') === NavigationItemRole.MenuItem;\n if (this.href !== undefined && !isMenuItem) return;\n if (event.key !== 'Enter' && event.key !== ' ') {\n return;\n }\n\n event.preventDefault();\n this.anchorElement?.click();\n }\n\n public override focus(options?: FocusOptions): void {\n (this.treeItemElement ?? this.anchorElement)?.focus(options);\n }\n\n private getItemRole(): NavigationItemRole | undefined {\n const hostRole = this.getAttribute('role');\n if (hostRole === NavigationItemRole.MenuItem) {\n return NavigationItemRole.MenuItem;\n }\n\n return this.href === undefined ? NavigationItemRole.Button : undefined;\n }\n\n private getItemTabIndex(): number | undefined {\n const hostTabIndex = this.getAttribute('tabindex');\n if (hostTabIndex !== null) {\n const parsedTabIndex = Number(hostTabIndex);\n return Number.isNaN(parsedTabIndex) ? undefined : parsedTabIndex;\n }\n\n return this.href === undefined ? 0 : undefined;\n }\n\n override render() {\n if (this.treeMode) {\n // Delegate the whole row to the tree item: it owns focus, keyboard\n // activation, the checked-inert behavior, and href navigation. Forward its\n // activation as this item's own `click` so selection wiring is unchanged.\n return html`\n <obc-tree-navigation-item\n class=\"tree\"\n .label=${this.label}\n .branches=${this.treeBranches}\n ?checked=${this.checked}\n .hasLeadingIcon=${this.hasIcon}\n .href=${this.href}\n .terminalType=${this.terminalType}\n .alerts=${this.alerts}\n @click=${this.onClick}\n >\n ${this.hasIcon\n ? html`<slot name=\"icon\" slot=\"icon\"></slot>`\n : nothing}\n </obc-tree-navigation-item>\n `;\n }\n\n const showFlyout =\n this.group && this.variant !== ObcNavigationMenuVariant.IconOnly;\n const isCompact = this.variant === ObcNavigationMenuVariant.Compact;\n\n return html`\n <a\n class=\"${classMap({\n wrapper: true,\n checked: this.checked,\n 'group-selected': this.groupSelected && this.group,\n 'has-icon': this.hasIcon,\n [this.variant]: true,\n })}\"\n href=${ifDefined(this.href)}\n @click=${this.onClick}\n @keydown=${this.handleKeydown}\n tabindex=${ifDefined(this.getItemTabIndex())}\n role=${ifDefined(this.getItemRole())}\n >\n <div class=\"visible-wrapper\">\n ${this.hasIcon\n ? html`<slot name=\"icon\" class=\"icon leading\"></slot>`\n : nothing}\n ${![\n ObcNavigationMenuVariant.IconOnly,\n ObcNavigationMenuVariant.IconOnlyLarge,\n ].includes(this.variant)\n ? html`\n <span\n part=\"label\"\n class=${classMap({\n label: true,\n 'label-flyout': showFlyout && !isCompact,\n })}\n >\n ${this.label}\n </span>\n `\n : nothing}\n ${showFlyout\n ? html`\n <div class=\"flyout-wrapper\">\n <obi-arrow-flyout-google\n class=\"icon trailing\"\n ></obi-arrow-flyout-google>\n </div>\n `\n : nothing}\n ${this.hasTrailingIcon && !showFlyout\n ? html`<slot name=\"trailing-icon\" class=\"icon trailing\"></slot>`\n : nothing}\n </div>\n </a>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-navigation-item': ObcNavigationItem;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"navigation-item.js","sources":["../../../src/components/navigation-item/navigation-item.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query} from 'lit/decorators.js';\nimport compentStyle from './navigation-item.css?inline';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport '../../icons/icon-arrow-flyout-google.js';\nimport {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';\nimport {customElement} from '../../decorator.js';\nimport '../tree-navigation-item/tree-navigation-item.js';\nimport {\n TreeBranchType,\n TreeTerminalType,\n type TreeNavigationItemAlerts,\n} from '../tree-navigation-item/tree-navigation-item.js';\n\nenum NavigationItemRole {\n Button = 'button',\n MenuItem = 'menuitem',\n}\n\n/**\n * `<obc-navigation-item>` – A navigation menu item component for use in navigation bars, side menus, or toolbars.\n *\n * Displays a selectable navigation option, optionally with an icon and support for different visual variants. Can be used as a link or as a button within navigation menus, supporting both single items and grouped menu structures.\n *\n * Appears as a horizontal or vertical item, with optional icon, label, and flyout indicator for nested or grouped navigation. Designed for use in navigation menus, toolbars, or any UI requiring a consistent, interactive navigation element.\n *\n * ## Features\n * - **Variants:**\n * - `Full` (default): Standard navigation item with icon (optional), label, and optional flyout indicator for groups.\n * - `IconOnly`: Displays only the icon, suitable for compact or icon-based navigation menus.\n * - `IconOnlyLarge`: Larger icon-only variant for prominent navigation actions.\n * - `Compact`: Smaller, vertically-stacked layout with icon and label, optimized for space-constrained menus.\n * - **Icon Support:**\n * - Leading icon can be provided via the `icon` slot.\n * - Icon presence is automatically detected and styled.\n * - **Label:**\n * - Text label shown unless in icon-only variants.\n * - **Checked State:**\n * - Indicates the currently selected or active navigation item.\n * - **Group Mode:**\n * - When `group` is true, displays a flyout indicator (arrow) and supports group selection highlighting.\n * - **Link Support:**\n * - Can be rendered as a link via the `href` property, or as a button if `href` is not set.\n * - **Accessibility:**\n * - Uses semantic anchor element for navigation.\n *\n * ## Usage Guidelines\n * Use `obc-navigation-item` for interactive navigation options within menus, toolbars, or navigation drawers.\n * - Ideal for main or secondary navigation, especially where visual consistency and flexible layout are needed.\n * - Use the `Full` variant for standard navigation lists with both icon and label.\n * - Use `IconOnly` or `IconOnlyLarge` for toolbars or sidebars where space is limited or icon-only navigation is preferred.\n * - Use `Compact` for dense menus or when vertical stacking of icon and label is desired.\n * - Set `checked` to highlight the currently active or selected item.\n * - Use `group` and `groupSelected` to indicate grouped navigation and selection within groups.\n * - Provide an icon via the `icon` slot for visual context (e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>).\n * - Use `href` to make the item a link; omit for button-like behavior.\n * - Use `::part(label)` CSS pseudo-element to style the label.\n *\n * **TODO(designer):** Clarify if there are recommended icon choices or label length constraints for each variant.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|---------|\n * | icon | Always (optional) | Leading icon for the navigation item. Place an icon such as `<obi-placeholder slot=\"icon\"></obi-placeholder>`. |\n *\n * ## Properties and Attributes\n * - `label` (string): The text label for the navigation item. Hidden in icon-only variants.\n * - `href` (string, optional): If set, the item is rendered as a link. If undefined, acts as a button.\n * - `checked` (boolean): Marks the item as selected/active.\n * - `variant` (string): Controls the visual style. One of `Full`, `IconOnly`, `IconOnlyLarge`, or `Compact`.\n * - `group` (boolean): Enables group mode, showing a flyout indicator and supporting group selection.\n * - `groupSelected` (boolean): Highlights the item as selected within a group.\n * - `hasIcon` (boolean): Whether the item has a leading icon.\n *\n * ## Events\n * - `click` – Fired when the navigation item is clicked (either as a link or button).\n *\n * ## Best Practices and Constraints\n * - Only use one navigation item as `checked` at a time within a menu to indicate the current location.\n * - For icon-only variants, ensure the icon clearly represents the navigation action.\n * - Use `group` for items that open submenus or represent grouped navigation.\n * - Avoid long labels in compact or icon-only variants to maintain layout integrity.\n * - For accessibility, provide meaningful labels and icons.\n *\n * ## Example:\n * ```\n * <obc-navigation-item\n * label=\"Dashboard\"\n * href=\"/dashboard\"\n * checked\n * variant=\"Full\"\n * >\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-navigation-item>\n * ```\n *\n * @slot icon - Leading icon slot (optional, shown if provided). Set `hasIcon` to `true` to show the icon.\n * @slot trailing-icon - Trailing icon slot (optional, shown if provided). Set `hasTrailingIcon` to `true` to show.\n * @fires click - Fired when the navigation item is clicked, either as a link or as a button.\n * @stable\n */\n\n@customElement('obc-navigation-item')\nexport class ObcNavigationItem extends LitElement {\n /**\n * The text label displayed for the navigation item.\n * Hidden in icon-only variants.\n * @availableWhen variant in [Full, Compact]\n */\n @property({type: String}) label = 'Label';\n\n /**\n * The URL to navigate to when the item is clicked.\n * If set, the item is rendered as a link (`<a href=\"...\" />`).\n * If undefined, acts as a button.\n */\n @property({type: String}) href: string | undefined;\n\n /**\n * Whether the navigation item is currently selected/active.\n * Use to indicate the current location or selection.\n */\n @property({type: Boolean}) checked = false;\n\n /**\n * Visual variant of the navigation item.\n * One of `Full` (default), `IconOnly`, `IconOnlyLarge`, or `Compact`.\n * Controls layout and visibility of icon/label.\n */\n @property({type: String}) variant = ObcNavigationMenuVariant.Full;\n\n /**\n * Enables group mode for the item, displaying a flyout indicator and supporting group selection.\n * Use for items that open submenus or represent grouped navigation.\n */\n @property({type: Boolean}) group = false;\n\n /**\n * Highlights the item as selected within a group.\n * Only relevant when `group` is true.\n * @availableWhen group==true\n */\n @property({type: Boolean}) groupSelected = false;\n\n /**\n * Whether the item has a leading icon.\n */\n @property({type: Boolean, reflect: true}) hasIcon = false;\n\n /** @availableWhen group==false || variant==IconOnly */\n @property({type: Boolean}) hasTrailingIcon = false;\n\n /** Set by `obc-navigation-menu` in its Tree variant — renders the row as a tree item. */\n @property({type: Boolean}) treeMode = false;\n\n /** Indentation columns for tree mode, assigned by `obc-navigation-menu`. */\n @property({type: Array}) treeBranches: TreeBranchType[] = [];\n\n /**\n * Terminal type for the row in the Tree variant — one of `regular` (default),\n * `aggregated-header`, or `group-header`. Has no effect in the flat variants.\n */\n @property({type: String}) terminalType: string = TreeTerminalType.regular;\n\n /**\n * Per-severity alert counts shown as trailing badge(s) (Tree variant only).\n * Forwarded to the underlying `obc-tree-navigation-item`. See\n * {@link TreeNavigationItemAlerts}.\n */\n @property({type: Object}) alerts?: TreeNavigationItemAlerts;\n\n @query('a') private anchorElement?: HTMLAnchorElement;\n\n // In tree mode the row renders an `obc-tree-navigation-item` instead of an `<a>`.\n @query('obc-tree-navigation-item') private treeItemElement?: HTMLElement;\n\n private handleKeydown(event: KeyboardEvent) {\n const isMenuItem =\n this.getAttribute('role') === NavigationItemRole.MenuItem;\n if (this.href !== undefined && !isMenuItem) return;\n if (event.key !== 'Enter' && event.key !== ' ') {\n return;\n }\n\n event.preventDefault();\n this.anchorElement?.click();\n }\n\n public override focus(options?: FocusOptions): void {\n (this.treeItemElement ?? this.anchorElement)?.focus(options);\n }\n\n private getItemRole(): NavigationItemRole | undefined {\n const hostRole = this.getAttribute('role');\n if (hostRole === NavigationItemRole.MenuItem) {\n return NavigationItemRole.MenuItem;\n }\n\n return this.href === undefined ? NavigationItemRole.Button : undefined;\n }\n\n private getItemTabIndex(): number | undefined {\n const hostTabIndex = this.getAttribute('tabindex');\n if (hostTabIndex !== null) {\n const parsedTabIndex = Number(hostTabIndex);\n return Number.isNaN(parsedTabIndex) ? undefined : parsedTabIndex;\n }\n\n return this.href === undefined ? 0 : undefined;\n }\n\n override render() {\n if (this.treeMode) {\n // Delegate the whole row to the tree item: it owns focus, keyboard\n // activation, the checked-inert behavior, and href navigation. Forward its\n // activation as this item's own `click` so selection wiring is unchanged.\n return html`\n <obc-tree-navigation-item\n class=\"tree\"\n .label=${this.label}\n .branches=${this.treeBranches}\n ?checked=${this.checked}\n .hasLeadingIcon=${this.hasIcon}\n .href=${this.href}\n .terminalType=${this.terminalType}\n .alerts=${this.alerts}\n >\n ${this.hasIcon\n ? html`<slot name=\"icon\" slot=\"icon\"></slot>`\n : nothing}\n </obc-tree-navigation-item>\n `;\n }\n\n const showFlyout =\n this.group && this.variant !== ObcNavigationMenuVariant.IconOnly;\n const isCompact = this.variant === ObcNavigationMenuVariant.Compact;\n\n return html`\n <a\n class=\"${classMap({\n wrapper: true,\n checked: this.checked,\n 'group-selected': this.groupSelected && this.group,\n 'has-icon': this.hasIcon,\n [this.variant]: true,\n })}\"\n href=${ifDefined(this.href)}\n @keydown=${this.handleKeydown}\n tabindex=${ifDefined(this.getItemTabIndex())}\n role=${ifDefined(this.getItemRole())}\n >\n <div class=\"visible-wrapper\">\n ${this.hasIcon\n ? html`<slot name=\"icon\" class=\"icon leading\"></slot>`\n : nothing}\n ${![\n ObcNavigationMenuVariant.IconOnly,\n ObcNavigationMenuVariant.IconOnlyLarge,\n ].includes(this.variant)\n ? html`\n <span\n part=\"label\"\n class=${classMap({\n label: true,\n 'label-flyout': showFlyout && !isCompact,\n })}\n >\n ${this.label}\n </span>\n `\n : nothing}\n ${showFlyout\n ? html`\n <div class=\"flyout-wrapper\">\n <obi-arrow-flyout-google\n class=\"icon trailing\"\n ></obi-arrow-flyout-google>\n </div>\n `\n : nothing}\n ${this.hasTrailingIcon && !showFlyout\n ? html`<slot name=\"trailing-icon\" class=\"icon trailing\"></slot>`\n : nothing}\n </div>\n </a>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-navigation-item': ObcNavigationItem;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -104,7 +104,8 @@ export declare class ObcNavigationItemGroup extends LitElement {
|
|
|
104
104
|
get expanded(): boolean;
|
|
105
105
|
private onClickGroup;
|
|
106
106
|
/**
|
|
107
|
-
*
|
|
107
|
+
* Opens the flyout panel and emits the `open` event.
|
|
108
|
+
* @fires open
|
|
108
109
|
*/
|
|
109
110
|
open(): void;
|
|
110
111
|
close(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-item-group.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-item-group/navigation-item-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAG/E,OAAO,iDAAiD,CAAC;AACzD,OAAO,EACL,cAAc,EAEd,KAAK,wBAAwB,EAC9B,MAAM,iDAAiD,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBACa,sBAAuB,SAAQ,UAAU;IACpD;;OAEG;IACuB,KAAK,SAAW;IAE1C;;;OAGG;IACuB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnD;;;OAGG;IACwB,OAAO,UAAS;IAE3C;;;;OAIG;IACuB,OAAO,EAAE,wBAAwB,CAC3B;IAEhC;;OAEG;IACwB,GAAG,UAAS;IAEZ,OAAO,UAAS;IAE3C,0FAA0F;IAC/D,QAAQ,UAAS;IAE5C,4EAA4E;IACnD,YAAY,EAAE,cAAc,EAAE,CAAM;IAE7D;;;OAGG;IACuB,YAAY,EAAE,MAAM,CAA4B;IAE1E;;;;;OAKG;IACuB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAE5D,gFAAgF;IACrD,WAAW,UAAS;IAEtC,OAAO,CAAC,aAAa,CAAS;IAKvC,OAAO,CAAC,SAAS,CAAC,CAAc;IAEvB,YAAY;IAMrB,wEAAwE;IACxE,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,YAAY;IAQpB
|
|
1
|
+
{"version":3,"file":"navigation-item-group.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-item-group/navigation-item-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAG/E,OAAO,iDAAiD,CAAC;AACzD,OAAO,EACL,cAAc,EAEd,KAAK,wBAAwB,EAC9B,MAAM,iDAAiD,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBACa,sBAAuB,SAAQ,UAAU;IACpD;;OAEG;IACuB,KAAK,SAAW;IAE1C;;;OAGG;IACuB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnD;;;OAGG;IACwB,OAAO,UAAS;IAE3C;;;;OAIG;IACuB,OAAO,EAAE,wBAAwB,CAC3B;IAEhC;;OAEG;IACwB,GAAG,UAAS;IAEZ,OAAO,UAAS;IAE3C,0FAA0F;IAC/D,QAAQ,UAAS;IAE5C,4EAA4E;IACnD,YAAY,EAAE,cAAc,EAAE,CAAM;IAE7D;;;OAGG;IACuB,YAAY,EAAE,MAAM,CAA4B;IAE1E;;;;;OAKG;IACuB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAE5D,gFAAgF;IACrD,WAAW,UAAS;IAEtC,OAAO,CAAC,aAAa,CAAS;IAKvC,OAAO,CAAC,SAAS,CAAC,CAAc;IAEvB,YAAY;IAMrB,wEAAwE;IACxE,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,YAAY;IAQpB;;;OAGG;IACH,IAAI;IAKJ,KAAK;IAOW,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAI1C,MAAM;IA8Df,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,2BAA2B,EAAE,sBAAsB,CAAC;KACrD;CACF"}
|
|
@@ -46,7 +46,8 @@ let ObcNavigationItemGroup = class extends LitElement {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* Opens the flyout panel and emits the `open` event.
|
|
50
|
+
* @fires open
|
|
50
51
|
*/
|
|
51
52
|
open() {
|
|
52
53
|
this.openContainer = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-item-group.js","sources":["../../../src/components/navigation-item-group/navigation-item-group.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport compentStyle from './navigation-item-group.css?inline';\nimport {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {customElement} from '../../decorator.js';\nimport '../tree-navigation-item/tree-navigation-item.js';\nimport {\n TreeBranchType,\n TreeTerminalType,\n type TreeNavigationItemAlerts,\n} from '../tree-navigation-item/tree-navigation-item.js';\n\n/**\n * `<obc-navigation-item-group>` – A collapsible navigation group component for organizing related navigation items under a single expandable label.\n *\n * Appears as a navigation item that, when clicked, reveals a flyout panel containing additional navigation content. Used to group related links or actions in a navigation menu, improving organization and reducing clutter in complex navigation structures.\n *\n * ### Features\n * - **Expandable Group:** Clicking the group label toggles a flyout panel containing child navigation items or custom content.\n * - **Custom Icon Support:** Accepts a custom icon via the `icon` slot, displayed next to the group label.\n * - **Variants:** Supports multiple visual styles via the `variant` property (see `ObcNavigationMenuVariant`), such as full or compact menu modes.\n * - **Checked State:** The group can be marked as checked/selected for highlighting the current section.\n * - **Hug Mode:** When `hug` is true, the flyout panel appears anchored closely to the group label, with compact styling.\n * - **Flyout Panel:** The flyout is positioned adjacent to the group label and adapts its layout based on the `hug` and `variant` settings.\n * - **Keyboard and Mouse Interaction:** The group can be opened or closed by clicking the label; emits an `open` event when expanded.\n *\n * ### Usage Guidelines\n * Use `obc-navigation-item-group` to organize related navigation links or actions under a single expandable section within a navigation menu. Ideal for menus with many items or hierarchical structures, where grouping improves clarity and reduces visual noise. Place `obc-navigation-item` or other navigation-related components inside the group to form the flyout content.\n *\n * - Use the `icon` slot to visually distinguish the group.\n * - Use the `checked` property to indicate the currently active or selected group.\n * - Use the `hug` property for context menus or compact flyouts that should appear tightly anchored to the group label.\n * - Avoid nesting too many groups for better usability.\n *\n * **TODO(designer):** Clarify if there are recommended maximum numbers of items per group, and if keyboard navigation/focus management has specific requirements.\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|---------|\n * | icon | Always (optional) | Custom icon displayed next to the group label. |\n * | (default) | Always | Content of the flyout panel (typically navigation items or custom content). |\n *\n * ### Events\n * - `open` – Fired when the group is expanded and the flyout panel is shown.\n *\n * ### Best Practices and Constraints\n * - Only one navigation group should be open at a time in a given navigation menu for clarity.\n * - Place only navigation-related items in the flyout for consistency.\n * - For accessibility, ensure the group label clearly describes the grouped content.\n *\n * ### Example:\n * ```html\n * <obc-navigation-item-group label=\"Settings\">\n * <obi-settings slot=\"icon\"></obi-settings>\n * <obc-navigation-item label=\"Profile\"></obc-navigation-item>\n * <obc-navigation-item label=\"Security\"></obc-navigation-item>\n * </obc-navigation-item-group>\n * ```\n *\n * @slot icon - Custom icon displayed next to the group label.\n * @slot - Default slot for flyout content (typically navigation items).\n * @fires {CustomEvent<void>} open - When the group is expanded and the flyout is shown.\n */\n@customElement('obc-navigation-item-group')\nexport class ObcNavigationItemGroup extends LitElement {\n /**\n * The label text displayed for the navigation group.\n */\n @property({type: String}) label = 'Label';\n\n /**\n * Optional URL to navigate to when the group label is clicked.\n * If set, clicking the group label will navigate to this URL.\n */\n @property({type: String}) href: string | undefined;\n\n /**\n * Whether the group is currently checked/selected.\n * Use to highlight the group as active.\n */\n @property({type: Boolean}) checked = false;\n\n /**\n * Visual variant of the navigation group.\n * Accepts values from `ObcNavigationMenuVariant` (e.g., 'full', 'compact').\n * Controls the styling and layout of the group and its flyout.\n */\n @property({type: String}) variant: ObcNavigationMenuVariant =\n ObcNavigationMenuVariant.Full;\n\n /**\n * If true, the flyout panel appears tightly anchored to the group label with compact styling.\n */\n @property({type: Boolean}) hug = false;\n\n @property({type: Boolean}) hasIcon = false;\n\n /** Set by `obc-navigation-menu` in its Tree variant — renders the group as a tree row. */\n @property({type: Boolean}) treeMode = false;\n\n /** Indentation columns for tree mode, assigned by `obc-navigation-menu`. */\n @property({type: Array}) treeBranches: TreeBranchType[] = [];\n\n /**\n * Terminal type for the group header in the Tree variant — one of `regular`\n * (default), `aggregated-header`, or `group-header`. No effect in flat variants.\n */\n @property({type: String}) terminalType: string = TreeTerminalType.regular;\n\n /**\n * Per-severity alert counts shown as trailing badge(s) on the group header\n * (Tree variant only). Forwarded to the underlying `obc-tree-navigation-item`;\n * typically `{combine: true, ...}` so the header totals the rows beneath it.\n * See {@link TreeNavigationItemAlerts}.\n */\n @property({type: Object}) alerts?: TreeNavigationItemAlerts;\n\n /** Whether the group starts expanded. Useful for trees that open by default. */\n @property({type: Boolean}) defaultOpen = false;\n\n @state() private openContainer = false;\n\n // Flat mode renders an `obc-navigation-item` header; tree mode renders an\n // `obc-tree-navigation-item`. Match whichever is present so `focus()` works in both.\n @query('obc-navigation-item, obc-tree-navigation-item')\n private groupItem?: HTMLElement;\n\n override firstUpdated() {\n if (this.defaultOpen) {\n this.openContainer = true;\n }\n }\n\n /** Whether the group is currently open (its children are disclosed). */\n public get expanded(): boolean {\n return this.openContainer;\n }\n\n private onClickGroup() {\n if (this.openContainer) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * @fires open - Opens the flyout panel and emits the `open` event.\n */\n open() {\n this.openContainer = true;\n this.dispatchEvent(new CustomEvent('open'));\n }\n\n close() {\n this.openContainer = false;\n this.querySelectorAll('obc-navigation-item-group').forEach((item) => {\n item.close();\n });\n }\n\n public override focus(options?: FocusOptions): void {\n this.groupItem?.focus(options);\n }\n\n override render() {\n if (this.treeMode) {\n return html`\n <obc-tree-navigation-item\n part=\"header\"\n .label=${this.label}\n .branches=${this.treeBranches}\n expandable\n ?expanded=${this.openContainer}\n ?checked=${this.checked}\n .hasLeadingIcon=${this.hasIcon}\n .terminalType=${this.terminalType}\n .alerts=${this.expanded ? undefined : this.alerts}\n @expand-toggle=${this.onClickGroup}\n >\n ${this.hasIcon\n ? html`<slot name=\"icon\" slot=\"icon\"></slot>`\n : nothing}\n </obc-tree-navigation-item>\n <div part=\"children\" role=\"group\" ?hidden=${!this.openContainer}>\n <slot></slot>\n </div>\n `;\n }\n\n return html`\n <obc-navigation-item\n @click=${this.onClickGroup}\n .checked=${this.checked}\n .groupSelected=${this.openContainer}\n .href=${this.href}\n .label=${this.label}\n .variant=${this.variant}\n group\n id=\"group-item\"\n ?hasIcon=${this.hasIcon}\n >\n ${this.hasIcon ? html`<slot name=\"icon\" slot=\"icon\"></slot>` : nothing}\n </obc-navigation-item>\n <div\n part=\"flyout\"\n id=\"flyout-wrapper\"\n class=${classMap({\n hug: this.hug,\n [this.variant]: true,\n open: this.openContainer,\n })}\n >\n <div class=\"content\">\n <slot></slot>\n </div>\n </div>\n <div\n class=${classMap({\n shadow: true,\n open: this.openContainer,\n hug: this.hug,\n })}\n ></div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-navigation-item-group': ObcNavigationItemGroup;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"navigation-item-group.js","sources":["../../../src/components/navigation-item-group/navigation-item-group.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport compentStyle from './navigation-item-group.css?inline';\nimport {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {customElement} from '../../decorator.js';\nimport '../tree-navigation-item/tree-navigation-item.js';\nimport {\n TreeBranchType,\n TreeTerminalType,\n type TreeNavigationItemAlerts,\n} from '../tree-navigation-item/tree-navigation-item.js';\n\n/**\n * `<obc-navigation-item-group>` – A collapsible navigation group component for organizing related navigation items under a single expandable label.\n *\n * Appears as a navigation item that, when clicked, reveals a flyout panel containing additional navigation content. Used to group related links or actions in a navigation menu, improving organization and reducing clutter in complex navigation structures.\n *\n * ### Features\n * - **Expandable Group:** Clicking the group label toggles a flyout panel containing child navigation items or custom content.\n * - **Custom Icon Support:** Accepts a custom icon via the `icon` slot, displayed next to the group label.\n * - **Variants:** Supports multiple visual styles via the `variant` property (see `ObcNavigationMenuVariant`), such as full or compact menu modes.\n * - **Checked State:** The group can be marked as checked/selected for highlighting the current section.\n * - **Hug Mode:** When `hug` is true, the flyout panel appears anchored closely to the group label, with compact styling.\n * - **Flyout Panel:** The flyout is positioned adjacent to the group label and adapts its layout based on the `hug` and `variant` settings.\n * - **Keyboard and Mouse Interaction:** The group can be opened or closed by clicking the label; emits an `open` event when expanded.\n *\n * ### Usage Guidelines\n * Use `obc-navigation-item-group` to organize related navigation links or actions under a single expandable section within a navigation menu. Ideal for menus with many items or hierarchical structures, where grouping improves clarity and reduces visual noise. Place `obc-navigation-item` or other navigation-related components inside the group to form the flyout content.\n *\n * - Use the `icon` slot to visually distinguish the group.\n * - Use the `checked` property to indicate the currently active or selected group.\n * - Use the `hug` property for context menus or compact flyouts that should appear tightly anchored to the group label.\n * - Avoid nesting too many groups for better usability.\n *\n * **TODO(designer):** Clarify if there are recommended maximum numbers of items per group, and if keyboard navigation/focus management has specific requirements.\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|---------|\n * | icon | Always (optional) | Custom icon displayed next to the group label. |\n * | (default) | Always | Content of the flyout panel (typically navigation items or custom content). |\n *\n * ### Events\n * - `open` – Fired when the group is expanded and the flyout panel is shown.\n *\n * ### Best Practices and Constraints\n * - Only one navigation group should be open at a time in a given navigation menu for clarity.\n * - Place only navigation-related items in the flyout for consistency.\n * - For accessibility, ensure the group label clearly describes the grouped content.\n *\n * ### Example:\n * ```html\n * <obc-navigation-item-group label=\"Settings\">\n * <obi-settings slot=\"icon\"></obi-settings>\n * <obc-navigation-item label=\"Profile\"></obc-navigation-item>\n * <obc-navigation-item label=\"Security\"></obc-navigation-item>\n * </obc-navigation-item-group>\n * ```\n *\n * @slot icon - Custom icon displayed next to the group label.\n * @slot - Default slot for flyout content (typically navigation items).\n * @fires {CustomEvent<void>} open - When the group is expanded and the flyout is shown.\n */\n@customElement('obc-navigation-item-group')\nexport class ObcNavigationItemGroup extends LitElement {\n /**\n * The label text displayed for the navigation group.\n */\n @property({type: String}) label = 'Label';\n\n /**\n * Optional URL to navigate to when the group label is clicked.\n * If set, clicking the group label will navigate to this URL.\n */\n @property({type: String}) href: string | undefined;\n\n /**\n * Whether the group is currently checked/selected.\n * Use to highlight the group as active.\n */\n @property({type: Boolean}) checked = false;\n\n /**\n * Visual variant of the navigation group.\n * Accepts values from `ObcNavigationMenuVariant` (e.g., 'full', 'compact').\n * Controls the styling and layout of the group and its flyout.\n */\n @property({type: String}) variant: ObcNavigationMenuVariant =\n ObcNavigationMenuVariant.Full;\n\n /**\n * If true, the flyout panel appears tightly anchored to the group label with compact styling.\n */\n @property({type: Boolean}) hug = false;\n\n @property({type: Boolean}) hasIcon = false;\n\n /** Set by `obc-navigation-menu` in its Tree variant — renders the group as a tree row. */\n @property({type: Boolean}) treeMode = false;\n\n /** Indentation columns for tree mode, assigned by `obc-navigation-menu`. */\n @property({type: Array}) treeBranches: TreeBranchType[] = [];\n\n /**\n * Terminal type for the group header in the Tree variant — one of `regular`\n * (default), `aggregated-header`, or `group-header`. No effect in flat variants.\n */\n @property({type: String}) terminalType: string = TreeTerminalType.regular;\n\n /**\n * Per-severity alert counts shown as trailing badge(s) on the group header\n * (Tree variant only). Forwarded to the underlying `obc-tree-navigation-item`;\n * typically `{combine: true, ...}` so the header totals the rows beneath it.\n * See {@link TreeNavigationItemAlerts}.\n */\n @property({type: Object}) alerts?: TreeNavigationItemAlerts;\n\n /** Whether the group starts expanded. Useful for trees that open by default. */\n @property({type: Boolean}) defaultOpen = false;\n\n @state() private openContainer = false;\n\n // Flat mode renders an `obc-navigation-item` header; tree mode renders an\n // `obc-tree-navigation-item`. Match whichever is present so `focus()` works in both.\n @query('obc-navigation-item, obc-tree-navigation-item')\n private groupItem?: HTMLElement;\n\n override firstUpdated() {\n if (this.defaultOpen) {\n this.openContainer = true;\n }\n }\n\n /** Whether the group is currently open (its children are disclosed). */\n public get expanded(): boolean {\n return this.openContainer;\n }\n\n private onClickGroup() {\n if (this.openContainer) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * Opens the flyout panel and emits the `open` event.\n * @fires open\n */\n open() {\n this.openContainer = true;\n this.dispatchEvent(new CustomEvent('open'));\n }\n\n close() {\n this.openContainer = false;\n this.querySelectorAll('obc-navigation-item-group').forEach((item) => {\n item.close();\n });\n }\n\n public override focus(options?: FocusOptions): void {\n this.groupItem?.focus(options);\n }\n\n override render() {\n if (this.treeMode) {\n return html`\n <obc-tree-navigation-item\n part=\"header\"\n .label=${this.label}\n .branches=${this.treeBranches}\n expandable\n ?expanded=${this.openContainer}\n ?checked=${this.checked}\n .hasLeadingIcon=${this.hasIcon}\n .terminalType=${this.terminalType}\n .alerts=${this.expanded ? undefined : this.alerts}\n @expand-toggle=${this.onClickGroup}\n >\n ${this.hasIcon\n ? html`<slot name=\"icon\" slot=\"icon\"></slot>`\n : nothing}\n </obc-tree-navigation-item>\n <div part=\"children\" role=\"group\" ?hidden=${!this.openContainer}>\n <slot></slot>\n </div>\n `;\n }\n\n return html`\n <obc-navigation-item\n @click=${this.onClickGroup}\n .checked=${this.checked}\n .groupSelected=${this.openContainer}\n .href=${this.href}\n .label=${this.label}\n .variant=${this.variant}\n group\n id=\"group-item\"\n ?hasIcon=${this.hasIcon}\n >\n ${this.hasIcon ? html`<slot name=\"icon\" slot=\"icon\"></slot>` : nothing}\n </obc-navigation-item>\n <div\n part=\"flyout\"\n id=\"flyout-wrapper\"\n class=${classMap({\n hug: this.hug,\n [this.variant]: true,\n open: this.openContainer,\n })}\n >\n <div class=\"content\">\n <slot></slot>\n </div>\n </div>\n <div\n class=${classMap({\n shadow: true,\n open: this.openContainer,\n hug: this.hug,\n })}\n ></div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-navigation-item-group': ObcNavigationItemGroup;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -143,7 +143,7 @@ export declare class ObcNotificationButton extends LitElement {
|
|
|
143
143
|
/**
|
|
144
144
|
* Handles click events on the button and dispatches the `obc-click` custom event.
|
|
145
145
|
*
|
|
146
|
-
* @fires
|
|
146
|
+
* @fires obc-click
|
|
147
147
|
*/
|
|
148
148
|
private handleClick;
|
|
149
149
|
static styles: import('lit').CSSResult;
|
|
@@ -73,7 +73,7 @@ let ObcNotificationButton = class extends LitElement {
|
|
|
73
73
|
/**
|
|
74
74
|
* Handles click events on the button and dispatches the `obc-click` custom event.
|
|
75
75
|
*
|
|
76
|
-
* @fires
|
|
76
|
+
* @fires obc-click
|
|
77
77
|
*/
|
|
78
78
|
handleClick() {
|
|
79
79
|
const event = new CustomEvent("obc-click", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-button.js","sources":["../../../src/components/notification-button/notification-button.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport componentStyle from './notification-button.css?inline';\nimport {customElement} from '../../decorator.js';\nimport '../../icons/icon-notification.js';\nimport '../../icons/icon-notification-filled.js';\n\n/**\n * Defines the available visual styles for `<obc-notification-button>`.\n *\n * - `Flat`: Minimal, icon-only style. Counter is not shown, regardless of `count` or `showCount`.\n * - `Normal`: Standard notification button with optional counter badge. Requires `isActive` to be true to apply.\n * - `Enhanced`: Emphasized notification button with distinct background and counter styling. Requires `isActive` to be true to apply.\n *\n * The style affects both the button's appearance and whether the notification count is displayed.\n */\nexport enum NotificationButtonStyle {\n Flat = 'flat',\n Normal = 'normal',\n Enhanced = 'enhanced',\n}\n\n/**\n * Payload for the `obc-click` event dispatched by `<obc-notification-button>`.\n *\n * - `count`: The current notification count.\n * - `isActive`: The new active state after the button is clicked.\n */\nexport interface NotificationButtonClickEvent {\n count: number;\n isActive: boolean;\n}\n\n/**\n * `<obc-notification-button>` – Icon button for accessing notifications, optionally displaying a counter badge.\n *\n * This component provides a compact, interactive button for surfacing notification status and counts. It supports several visual styles to adapt to different UI contexts, and can display a badge with the number of unread notifications when appropriate.\n *\n * Appears as an icon-only button by default, with optional counter and active state styling. Designed for use in toolbars, headers, or anywhere a notification indicator is needed.\n *\n * ## Features\n * - **Visual Styles:**\n * - **Flat:** Minimal icon-only button. Counter is never shown, regardless of `count` or `showCount`.\n * - **Normal:** Standard notification button. Counter badge appears if `showCount` is true and `isActive` is true.\n * - **Enhanced:** Emphasized style with background and accent color. Counter badge appears if `showCount` is true and `isActive` is true.\n * - **Active State:**\n * - When `isActive` is true, the button uses the filled notification icon and applies the selected style (`Normal` or `Enhanced`).\n * - When inactive, the button uses the outlined notification icon and always appears in `Flat` style.\n * - **Notification Counter:**\n * - Shows a badge with the current `count` if `showCount` is true and style is `Normal` or `Enhanced` and `isActive` is true.\n * - Counter is hidden in `Flat` style, even if `showCount` is true.\n * - **Custom Icon Support:**\n * - Developers can supply a custom icon via the `icon` slot. Defaults to notification icons if slot is empty.\n * - **Accessibility:**\n * - Uses `aria-label` for screen readers, including the count if visible.\n * - `aria-pressed` reflects the active state.\n *\n * ## Usage Guidelines\n * Use `<obc-notification-button>` to provide a prominent, interactive entry point for notifications in an application. It is ideal for header bars, navigation panels, or any location where users need to be alerted to new activity or messages.\n *\n * - Use the `Flat` style for minimal, unobtrusive notification indicators.\n * - Use `Normal` or `Enhanced` styles when you want to emphasize the presence of new notifications, especially when the button is active.\n * - Show the counter badge only when it is important to indicate the number of unread notifications; otherwise, keep it hidden for a cleaner look.\n * - The button does not manage notification state internally; it is up to the parent application to update `count` and `isActive` as needed.\n *\n * **TODO(designer):** Clarify recommended scenarios for using `Normal` vs. `Enhanced` styles, and any design guidelines for when to show the counter.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|----------------|---------|\n * | `icon` | Always (optional) | Custom icon to display instead of the default notification icon. |\n *\n * ## Events\n * - `obc-click` – Fired when the button is clicked. Event detail includes the current `count` and the new `isActive` state.\n *\n * ## Example\n *\n * ```html\n * <obc-notification-button\n * buttonStyle=\"normal\"\n * count=\"5\"\n * showCount\n * isActive\n * ariaLabel=\"Notifications\"\n * ></obc-notification-button>\n * ```\n *\n * In this example, the button appears in the normal style, is active, and displays a counter badge with the value 5.\n *\n * @slot icon - Custom icon to display in place of the default notification icon.\n * @fires {CustomEvent<NotificationButtonClickEvent>} obc-click - Fired when the button is clicked, with the current count and new active state.\n * @stable\n */\n@customElement('obc-notification-button')\nexport class ObcNotificationButton extends LitElement {\n /**\n * Visual style of the notification button.\n *\n * - `flat`: Minimal icon-only style. Counter is never shown.\n * - `normal`: Standard notification button. Counter badge appears if `showCount` is true and `isActive` is true.\n * - `enhanced`: Emphasized style with background and accent color. Counter badge appears if `showCount` is true and `isActive` is true.\n *\n * Defaults to `flat`.\n *\n * @availableWhen isActive==true\n */\n @property({type: String}) buttonStyle: NotificationButtonStyle =\n NotificationButtonStyle.Flat;\n\n /**\n * Number of notifications to display in the counter badge.\n *\n * Only shown if `showCount` is true, `isActive` is true, and `buttonStyle` is `normal` or `enhanced`.\n * Ignored in `flat` style.\n *\n * Defaults to 0.\n *\n * @availableWhen isActive==true && showCount==true && buttonStyle in [Normal, Enhanced]\n */\n @property({type: Number}) count = 0;\n\n /**\n * Whether to display the notification count badge.\n *\n * If true, and the style is `normal` or `enhanced` and `isActive` is true, the counter badge is shown.\n * Has no effect in `flat` style.\n *\n * Defaults to false.\n *\n * @availableWhen isActive==true && buttonStyle in [Normal, Enhanced]\n */\n @property({type: Boolean}) showCount = false;\n\n /**\n * Whether the button is in the active (selected) state.\n *\n * When true, the button uses the filled notification icon and applies the selected style (`normal` or `enhanced`).\n * When false, the button always appears in `flat` style with the outlined icon.\n *\n * Defaults to false.\n */\n @property({type: Boolean}) isActive = false;\n\n /**\n * Accessibility label for the button.\n *\n * Used as the `aria-label` attribute for screen readers. If the counter is visible, the label will include the count (e.g., \"Notifications, 5 new\").\n *\n * Defaults to \"Notifications\".\n */\n @property({type: String}) override ariaLabel = 'Notifications';\n\n override render() {\n const useNormal =\n this.isActive && this.buttonStyle === NotificationButtonStyle.Normal;\n const useEnhanced =\n this.isActive && this.buttonStyle === NotificationButtonStyle.Enhanced;\n const useFlat =\n this.buttonStyle === NotificationButtonStyle.Flat ||\n (!useNormal && !useEnhanced);\n\n const hasCounter = (useNormal || useEnhanced) && this.showCount;\n\n const wrapperClasses = {\n wrapper: true,\n 'is-active': this.isActive,\n 'has-counter': hasCounter,\n flat: useFlat,\n normal: useNormal,\n enhanced: useEnhanced,\n };\n\n const visibleWrapperClasses = {\n 'visible-wrapper': true,\n };\n\n return html`\n <button\n class=\"${classMap(wrapperClasses)}\"\n @click=\"${this.handleClick}\"\n aria-label=\"${this.ariaLabel}${hasCounter ? `, ${this.count} new` : ''}\"\n aria-pressed=\"${this.isActive}\"\n role=\"button\"\n type=\"button\"\n >\n <div class=\"${classMap(visibleWrapperClasses)}\">\n <div class=\"icon-container\">\n <slot name=\"icon\"> ${this.renderDefaultIcon()} </slot>\n </div>\n ${hasCounter\n ? html` <span class=\"count-label\">${this.count}</span> `\n : nothing}\n </div>\n </button>\n `;\n }\n\n private renderDefaultIcon() {\n if (this.isActive) {\n return html`<obi-notification-filled></obi-notification-filled>`;\n }\n return html`<obi-notification></obi-notification>`;\n }\n\n /**\n * Handles click events on the button and dispatches the `obc-click` custom event.\n *\n * @fires {CustomEvent<NotificationButtonClickEvent>} obc-click - Fired with the current count and new active state.\n */\n private handleClick() {\n const event = new CustomEvent<NotificationButtonClickEvent>('obc-click', {\n detail: {\n count: this.count,\n isActive: !this.isActive,\n },\n composed: true,\n bubbles: true,\n });\n\n this.dispatchEvent(event);\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-notification-button': ObcNotificationButton;\n }\n}\n"],"names":["NotificationButtonStyle"],"mappings":";;;;;;;;;;;;;;;;;AAiBO,IAAK,4CAAAA,6BAAL;AACLA,2BAAA,MAAA,IAAO;AACPA,2BAAA,QAAA,IAAS;AACTA,2BAAA,UAAA,IAAW;AAHD,SAAAA;AAAA,GAAA,2BAAA,CAAA,CAAA;AA+EL,IAAM,wBAAN,cAAoC,WAAW;AAAA,EAA/C,cAAA;AAAA,UAAA,GAAA,SAAA;AAYqB,SAAA,cACxB;AAYwB,SAAA,QAAQ;AAYP,SAAA,YAAY;AAUZ,SAAA,WAAW;AASZ,SAAS,YAAY;AAAA,EAAA;AAAA,EAEtC,SAAS;AAChB,UAAM,YACJ,KAAK,YAAY,KAAK,gBAAgB;AACxC,UAAM,cACJ,KAAK,YAAY,KAAK,gBAAgB;AACxC,UAAM,UACJ,KAAK,gBAAgB,UACpB,CAAC,aAAa,CAAC;AAElB,UAAM,cAAc,aAAa,gBAAgB,KAAK;AAEtD,UAAM,iBAAiB;AAAA,MACrB,SAAS;AAAA,MACT,aAAa,KAAK;AAAA,MAClB,eAAe;AAAA,MACf,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,IAAA;AAGZ,UAAM,wBAAwB;AAAA,MAC5B,mBAAmB;AAAA,IAAA;AAGrB,WAAO;AAAA;AAAA,iBAEM,SAAS,cAAc,CAAC;AAAA,kBACvB,KAAK,WAAW;AAAA,sBACZ,KAAK,SAAS,GAAG,aAAa,KAAK,KAAK,KAAK,SAAS,EAAE;AAAA,wBACtD,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,sBAIf,SAAS,qBAAqB,CAAC;AAAA;AAAA,iCAEpB,KAAK,mBAAmB;AAAA;AAAA,YAE7C,aACE,kCAAkC,KAAK,KAAK,aAC5C,OAAO;AAAA;AAAA;AAAA;AAAA,EAInB;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,KAAK,UAAU;AACjB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,cAAc;AACpB,UAAM,QAAQ,IAAI,YAA0C,aAAa;AAAA,MACvE,QAAQ;AAAA,QACN,OAAO,KAAK;AAAA,QACZ,UAAU,CAAC,KAAK;AAAA,MAAA;AAAA,MAElB,UAAU;AAAA,MACV,SAAS;AAAA,IAAA,CACV;AAED,SAAK,cAAc,KAAK;AAAA,EAC1B;AAGF;AAjIa,sBAgIK,SAAS,UAAU,cAAc;AApHvB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAZb,sBAYe,WAAA,eAAA,CAAA;AAaA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAzBb,sBAyBe,WAAA,SAAA,CAAA;AAYC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GArCd,sBAqCgB,WAAA,aAAA,CAAA;AAUA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA/Cd,sBA+CgB,WAAA,YAAA,CAAA;AASQ,gBAAA;AAAA,EAAlC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAxDb,sBAwDwB,WAAA,aAAA,CAAA;AAxDxB,wBAAN,gBAAA;AAAA,EADN,cAAc,yBAAyB;AAAA,GAC3B,qBAAA;"}
|
|
1
|
+
{"version":3,"file":"notification-button.js","sources":["../../../src/components/notification-button/notification-button.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport componentStyle from './notification-button.css?inline';\nimport {customElement} from '../../decorator.js';\nimport '../../icons/icon-notification.js';\nimport '../../icons/icon-notification-filled.js';\n\n/**\n * Defines the available visual styles for `<obc-notification-button>`.\n *\n * - `Flat`: Minimal, icon-only style. Counter is not shown, regardless of `count` or `showCount`.\n * - `Normal`: Standard notification button with optional counter badge. Requires `isActive` to be true to apply.\n * - `Enhanced`: Emphasized notification button with distinct background and counter styling. Requires `isActive` to be true to apply.\n *\n * The style affects both the button's appearance and whether the notification count is displayed.\n */\nexport enum NotificationButtonStyle {\n Flat = 'flat',\n Normal = 'normal',\n Enhanced = 'enhanced',\n}\n\n/**\n * Payload for the `obc-click` event dispatched by `<obc-notification-button>`.\n *\n * - `count`: The current notification count.\n * - `isActive`: The new active state after the button is clicked.\n */\nexport interface NotificationButtonClickEvent {\n count: number;\n isActive: boolean;\n}\n\n/**\n * `<obc-notification-button>` – Icon button for accessing notifications, optionally displaying a counter badge.\n *\n * This component provides a compact, interactive button for surfacing notification status and counts. It supports several visual styles to adapt to different UI contexts, and can display a badge with the number of unread notifications when appropriate.\n *\n * Appears as an icon-only button by default, with optional counter and active state styling. Designed for use in toolbars, headers, or anywhere a notification indicator is needed.\n *\n * ## Features\n * - **Visual Styles:**\n * - **Flat:** Minimal icon-only button. Counter is never shown, regardless of `count` or `showCount`.\n * - **Normal:** Standard notification button. Counter badge appears if `showCount` is true and `isActive` is true.\n * - **Enhanced:** Emphasized style with background and accent color. Counter badge appears if `showCount` is true and `isActive` is true.\n * - **Active State:**\n * - When `isActive` is true, the button uses the filled notification icon and applies the selected style (`Normal` or `Enhanced`).\n * - When inactive, the button uses the outlined notification icon and always appears in `Flat` style.\n * - **Notification Counter:**\n * - Shows a badge with the current `count` if `showCount` is true and style is `Normal` or `Enhanced` and `isActive` is true.\n * - Counter is hidden in `Flat` style, even if `showCount` is true.\n * - **Custom Icon Support:**\n * - Developers can supply a custom icon via the `icon` slot. Defaults to notification icons if slot is empty.\n * - **Accessibility:**\n * - Uses `aria-label` for screen readers, including the count if visible.\n * - `aria-pressed` reflects the active state.\n *\n * ## Usage Guidelines\n * Use `<obc-notification-button>` to provide a prominent, interactive entry point for notifications in an application. It is ideal for header bars, navigation panels, or any location where users need to be alerted to new activity or messages.\n *\n * - Use the `Flat` style for minimal, unobtrusive notification indicators.\n * - Use `Normal` or `Enhanced` styles when you want to emphasize the presence of new notifications, especially when the button is active.\n * - Show the counter badge only when it is important to indicate the number of unread notifications; otherwise, keep it hidden for a cleaner look.\n * - The button does not manage notification state internally; it is up to the parent application to update `count` and `isActive` as needed.\n *\n * **TODO(designer):** Clarify recommended scenarios for using `Normal` vs. `Enhanced` styles, and any design guidelines for when to show the counter.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|----------------|---------|\n * | `icon` | Always (optional) | Custom icon to display instead of the default notification icon. |\n *\n * ## Events\n * - `obc-click` – Fired when the button is clicked. Event detail includes the current `count` and the new `isActive` state.\n *\n * ## Example\n *\n * ```html\n * <obc-notification-button\n * buttonStyle=\"normal\"\n * count=\"5\"\n * showCount\n * isActive\n * ariaLabel=\"Notifications\"\n * ></obc-notification-button>\n * ```\n *\n * In this example, the button appears in the normal style, is active, and displays a counter badge with the value 5.\n *\n * @slot icon - Custom icon to display in place of the default notification icon.\n * @fires {CustomEvent<NotificationButtonClickEvent>} obc-click - Fired when the button is clicked, with the current count and new active state.\n * @stable\n */\n@customElement('obc-notification-button')\nexport class ObcNotificationButton extends LitElement {\n /**\n * Visual style of the notification button.\n *\n * - `flat`: Minimal icon-only style. Counter is never shown.\n * - `normal`: Standard notification button. Counter badge appears if `showCount` is true and `isActive` is true.\n * - `enhanced`: Emphasized style with background and accent color. Counter badge appears if `showCount` is true and `isActive` is true.\n *\n * Defaults to `flat`.\n *\n * @availableWhen isActive==true\n */\n @property({type: String}) buttonStyle: NotificationButtonStyle =\n NotificationButtonStyle.Flat;\n\n /**\n * Number of notifications to display in the counter badge.\n *\n * Only shown if `showCount` is true, `isActive` is true, and `buttonStyle` is `normal` or `enhanced`.\n * Ignored in `flat` style.\n *\n * Defaults to 0.\n *\n * @availableWhen isActive==true && showCount==true && buttonStyle in [Normal, Enhanced]\n */\n @property({type: Number}) count = 0;\n\n /**\n * Whether to display the notification count badge.\n *\n * If true, and the style is `normal` or `enhanced` and `isActive` is true, the counter badge is shown.\n * Has no effect in `flat` style.\n *\n * Defaults to false.\n *\n * @availableWhen isActive==true && buttonStyle in [Normal, Enhanced]\n */\n @property({type: Boolean}) showCount = false;\n\n /**\n * Whether the button is in the active (selected) state.\n *\n * When true, the button uses the filled notification icon and applies the selected style (`normal` or `enhanced`).\n * When false, the button always appears in `flat` style with the outlined icon.\n *\n * Defaults to false.\n */\n @property({type: Boolean}) isActive = false;\n\n /**\n * Accessibility label for the button.\n *\n * Used as the `aria-label` attribute for screen readers. If the counter is visible, the label will include the count (e.g., \"Notifications, 5 new\").\n *\n * Defaults to \"Notifications\".\n */\n @property({type: String}) override ariaLabel = 'Notifications';\n\n override render() {\n const useNormal =\n this.isActive && this.buttonStyle === NotificationButtonStyle.Normal;\n const useEnhanced =\n this.isActive && this.buttonStyle === NotificationButtonStyle.Enhanced;\n const useFlat =\n this.buttonStyle === NotificationButtonStyle.Flat ||\n (!useNormal && !useEnhanced);\n\n const hasCounter = (useNormal || useEnhanced) && this.showCount;\n\n const wrapperClasses = {\n wrapper: true,\n 'is-active': this.isActive,\n 'has-counter': hasCounter,\n flat: useFlat,\n normal: useNormal,\n enhanced: useEnhanced,\n };\n\n const visibleWrapperClasses = {\n 'visible-wrapper': true,\n };\n\n return html`\n <button\n class=\"${classMap(wrapperClasses)}\"\n @click=\"${this.handleClick}\"\n aria-label=\"${this.ariaLabel}${hasCounter ? `, ${this.count} new` : ''}\"\n aria-pressed=\"${this.isActive}\"\n role=\"button\"\n type=\"button\"\n >\n <div class=\"${classMap(visibleWrapperClasses)}\">\n <div class=\"icon-container\">\n <slot name=\"icon\"> ${this.renderDefaultIcon()} </slot>\n </div>\n ${hasCounter\n ? html` <span class=\"count-label\">${this.count}</span> `\n : nothing}\n </div>\n </button>\n `;\n }\n\n private renderDefaultIcon() {\n if (this.isActive) {\n return html`<obi-notification-filled></obi-notification-filled>`;\n }\n return html`<obi-notification></obi-notification>`;\n }\n\n /**\n * Handles click events on the button and dispatches the `obc-click` custom event.\n *\n * @fires obc-click\n */\n private handleClick() {\n const event = new CustomEvent<NotificationButtonClickEvent>('obc-click', {\n detail: {\n count: this.count,\n isActive: !this.isActive,\n },\n composed: true,\n bubbles: true,\n });\n\n this.dispatchEvent(event);\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-notification-button': ObcNotificationButton;\n }\n}\n"],"names":["NotificationButtonStyle"],"mappings":";;;;;;;;;;;;;;;;;AAiBO,IAAK,4CAAAA,6BAAL;AACLA,2BAAA,MAAA,IAAO;AACPA,2BAAA,QAAA,IAAS;AACTA,2BAAA,UAAA,IAAW;AAHD,SAAAA;AAAA,GAAA,2BAAA,CAAA,CAAA;AA+EL,IAAM,wBAAN,cAAoC,WAAW;AAAA,EAA/C,cAAA;AAAA,UAAA,GAAA,SAAA;AAYqB,SAAA,cACxB;AAYwB,SAAA,QAAQ;AAYP,SAAA,YAAY;AAUZ,SAAA,WAAW;AASZ,SAAS,YAAY;AAAA,EAAA;AAAA,EAEtC,SAAS;AAChB,UAAM,YACJ,KAAK,YAAY,KAAK,gBAAgB;AACxC,UAAM,cACJ,KAAK,YAAY,KAAK,gBAAgB;AACxC,UAAM,UACJ,KAAK,gBAAgB,UACpB,CAAC,aAAa,CAAC;AAElB,UAAM,cAAc,aAAa,gBAAgB,KAAK;AAEtD,UAAM,iBAAiB;AAAA,MACrB,SAAS;AAAA,MACT,aAAa,KAAK;AAAA,MAClB,eAAe;AAAA,MACf,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,IAAA;AAGZ,UAAM,wBAAwB;AAAA,MAC5B,mBAAmB;AAAA,IAAA;AAGrB,WAAO;AAAA;AAAA,iBAEM,SAAS,cAAc,CAAC;AAAA,kBACvB,KAAK,WAAW;AAAA,sBACZ,KAAK,SAAS,GAAG,aAAa,KAAK,KAAK,KAAK,SAAS,EAAE;AAAA,wBACtD,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,sBAIf,SAAS,qBAAqB,CAAC;AAAA;AAAA,iCAEpB,KAAK,mBAAmB;AAAA;AAAA,YAE7C,aACE,kCAAkC,KAAK,KAAK,aAC5C,OAAO;AAAA;AAAA;AAAA;AAAA,EAInB;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,KAAK,UAAU;AACjB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,cAAc;AACpB,UAAM,QAAQ,IAAI,YAA0C,aAAa;AAAA,MACvE,QAAQ;AAAA,QACN,OAAO,KAAK;AAAA,QACZ,UAAU,CAAC,KAAK;AAAA,MAAA;AAAA,MAElB,UAAU;AAAA,MACV,SAAS;AAAA,IAAA,CACV;AAED,SAAK,cAAc,KAAK;AAAA,EAC1B;AAGF;AAjIa,sBAgIK,SAAS,UAAU,cAAc;AApHvB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAZb,sBAYe,WAAA,eAAA,CAAA;AAaA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAzBb,sBAyBe,WAAA,SAAA,CAAA;AAYC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GArCd,sBAqCgB,WAAA,aAAA,CAAA;AAUA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA/Cd,sBA+CgB,WAAA,YAAA,CAAA;AASQ,gBAAA;AAAA,EAAlC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAxDb,sBAwDwB,WAAA,aAAA,CAAA;AAxDxB,wBAAN,gBAAA;AAAA,EADN,cAAc,yBAAyB;AAAA,GAC3B,qBAAA;"}
|