@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.70 → 2.0.0-next.72
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 +5109 -4904
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +195 -2
- package/dist/components/alert-menu-item/alert-menu-item.d.ts +39 -1
- package/dist/components/alert-menu-item/alert-menu-item.d.ts.map +1 -1
- package/dist/components/alert-menu-item/alert-menu-item.js +41 -0
- package/dist/components/alert-menu-item/alert-menu-item.js.map +1 -1
- package/dist/components/message-menu-item/message-menu-item.d.ts +4 -0
- package/dist/components/message-menu-item/message-menu-item.d.ts.map +1 -1
- package/dist/components/message-menu-item/message-menu-item.js +10 -0
- package/dist/components/message-menu-item/message-menu-item.js.map +1 -1
- package/dist/components/textbox/textbox.css.js +114 -0
- package/dist/components/textbox/textbox.css.js.map +1 -0
- package/dist/components/textbox/textbox.d.ts +70 -0
- package/dist/components/textbox/textbox.d.ts.map +1 -0
- package/dist/components/textbox/textbox.js +84 -0
- package/dist/components/textbox/textbox.js.map +1 -0
- package/eslint.config.mjs +2 -7
- package/package.json +1 -1
- package/src/components/alert-menu-item/alert-menu-item.stories.ts +40 -1
- package/src/components/alert-menu-item/alert-menu-item.ts +67 -1
- package/src/components/message-menu-item/message-menu-item.stories.ts +18 -0
- package/src/components/message-menu-item/message-menu-item.ts +6 -0
- package/src/components/textbox/textbox.css +100 -0
- package/src/components/textbox/textbox.stories.ts +165 -0
- package/src/components/textbox/textbox.ts +103 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-menu-item.js","sources":["../../../src/components/message-menu-item/message-menu-item.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './message-menu-item.css?inline';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../button/button.js';\nimport '../../icons/icon-chevron-down-google.js';\nimport '../../icons/icon-chevron-up-google.js';\nimport {customElement} from '../../decorator.js';\nimport '../../icons/icon-alerts-shelf.js';\n\nexport enum ObcMessageMenuItemSize {\n SingleLine = 'single-line',\n DoubleLine = 'double-line',\n}\n\n/**\n * `<obc-message-menu-item>` – An expandable message or notification item for use in message lists, notification panels, or alert menus.\n *\n * Displays a concise message row with optional icons, title, description, timestamp, and action buttons. Clicking the item expands it to reveal the full content. Designed for scannable lists where users may need to quickly review and act on individual messages.\n *\n * ## Features\n *\n * - **Size Variants:**\n * - `single-line`: Compact layout with title and description on one line (default).\n * - `double-line`: Two-line layout with title on top and description below.\n * - When clicked, both variants expand to show full multi-line content.\n *\n * - **Stack Direction:**\n * - `stackVertical=false` (default): Action buttons appear inline to the right of the content.\n * - `stackVertical=true`: Action buttons appear below the content, spanning full width.\n *\n * - **Icon Options:**\n * - Primary and secondary icon slots for visual context or status indicators.\n * - Enhanced icon mode (`enhancedIcon`) increases icon size for emphasis.\n * - Trailing icon slot (horizontal layout only) for additional actions.\n * - Shelved state (`isShelved`) displays a shelf icon automatically.\n *\n * - **Actions:**\n * - Supports up to two action buttons via `primaryActionLabel` and `secondaryActionLabel`.\n * - In vertical layout, action buttons expand to full width.\n *\n * - **Timestamp:**\n * - Optional day and time display via `day` and `time` properties.\n *\n * ## Usage Guidelines\n *\n * Use `obc-message-menu-item` to present individual notifications, alerts, or messages within a scrollable list. Ideal for scenarios where users need to quickly scan items, expand for details, or take immediate action.\n *\n * - Use `single-line` for high-density lists where space is limited.\n * - Use `double-line` when the description needs more visibility in the collapsed state.\n * - Keep `stackVertical=false` (default) when actions should be quickly accessible inline.\n * - Use `stackVertical=true` when actions need more prominence or when space is narrow.\n * - Enable `enhancedIcon` to highlight important or priority messages.\n * - Use `isShelved` to indicate messages that have been temporarily set aside.\n *\n * ## Slots\n *\n * Text content for `title`, `description`, and `action-label` supports both props (for plain text) and slots (for rich HTML like `CO<sub>2</sub>`).\n * To use a slot, set the corresponding `has*Slot` prop to `true`.\n *\n * | Slot Name | Enabled By | Purpose |\n * |------------------|--------------------------|---------------------------------------------------|\n * | `title` | `hasTitleSlot=true` | Message title. Use slot for rich HTML. |\n * | `description` | `hasDescriptionSlot=true`| Message description. Use slot for rich HTML. |\n * | `action-label` | `hasActionLabelSlot=true`| Primary action button label. Use slot for rich HTML. |\n * | `primary-icon` | `hasPrimaryIcon=true` | Main icon representing message type or status. |\n * | `secondary-icon` | `hasSecondaryIcon=true` | Additional icon for secondary status or context. |\n * | `trailing-icon` | `hasTrailingIcon=true` (horizontal only) | Icon button after action buttons. |\n *\n * ## Events\n *\n * - `message-click` – Fired when the message item is clicked. Detail includes `{ open: boolean }`.\n * - `primary-action-click` – Fired when the primary action button is clicked.\n * - `secondary-action-click` – Fired when the secondary action button is clicked.\n *\n * ## Example\n *\n * Using props (simple text):\n * ```html\n * <obc-message-menu-item\n * size=\"double-line\"\n * title=\"System Update\"\n * description=\"A new update is available for installation.\"\n * day=\"Yesterday\"\n * time=\"14:32\"\n * primaryActionLabel=\"Install\"\n * hasPrimaryIcon\n * >\n * <obi-placeholder slot=\"primary-icon\"></obi-placeholder>\n * </obc-message-menu-item>\n * ```\n *\n * Using slots (rich HTML):\n * ```html\n * <obc-message-menu-item\n * size=\"double-line\"\n * day=\"Yesterday\"\n * time=\"14:32\"\n * hasPrimaryIcon\n * hasTitleSlot\n * hasDescriptionSlot\n * hasActionLabelSlot\n * >\n * <span slot=\"title\">High CO<sub>2</sub> level</span>\n * <span slot=\"description\">CO<sub>2</sub> concentration exceeds safe limits.</span>\n * <span slot=\"action-label\">Acknowledge</span>\n * <obi-placeholder slot=\"primary-icon\"></obi-placeholder>\n * </obc-message-menu-item>\n * ```\n *\n * @slot title - Message title (shown when `hasTitleSlot` is true).\n * @slot description - Message description (shown when `hasDescriptionSlot` is true).\n * @slot action-label - Primary action button label (shown when `hasActionLabelSlot` is true).\n * @slot primary-icon - Main icon representing the message type or status (shown when `hasPrimaryIcon` is true).\n * @slot secondary-icon - Additional icon for secondary status/context (shown when `hasSecondaryIcon` is true).\n * @slot trailing-icon - Icon after action buttons, horizontal layout only (shown when `hasTrailingIcon` is true).\n * @fires message-click {CustomEvent<{open: boolean}>} Fired when the message item is clicked.\n * @fires primary-action-click {CustomEvent<void>} Fired when the primary action button is clicked.\n * @fires secondary-action-click {CustomEvent<void>} Fired when the secondary action button is clicked.\n */\n@customElement('obc-message-menu-item')\nexport class ObcMessageMenuItem extends LitElement {\n // Layout properties\n @property({type: String}) size: ObcMessageMenuItemSize =\n ObcMessageMenuItemSize.SingleLine;\n @property({type: Boolean}) stackVertical = false;\n @property({type: Boolean}) enhancedIcon = false;\n @property({type: Boolean}) open = false;\n\n // Text content properties\n @property({type: String}) override title = '';\n @property({type: String}) description = '';\n @property({type: String}) day = '';\n @property({type: String}) time = '';\n @property({type: String}) primaryActionLabel = '';\n @property({type: String}) secondaryActionLabel = '';\n\n // Visibility properties for icons (slots)\n @property({type: Boolean}) hasPrimaryIcon = false;\n @property({type: Boolean}) hasSecondaryIcon = false;\n @property({type: Boolean}) hasTrailingIcon = false;\n @property({type: Boolean}) isShelved = false;\n\n @property({type: Boolean}) hasActionLabelSlot = false;\n\n private get activeSize() {\n if (this.open) {\n return 'multi-line';\n }\n return this.size;\n }\n\n private get hasTimestamp() {\n return this.time !== '' || this.day !== '';\n }\n\n private get hasDay() {\n return this.day !== '';\n }\n\n private get hasPrimaryAction() {\n return this.primaryActionLabel !== '' || this.hasActionLabelSlot;\n }\n\n private get hasSecondaryAction() {\n return this.secondaryActionLabel !== '';\n }\n\n private get isVertical() {\n return this.stackVertical;\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n // Only handle key events on the wrapper itself, not on nested interactive elements\n if (e.target !== e.currentTarget) {\n return;\n }\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.handleMessageClick();\n }\n }\n\n private handleMessageClick() {\n this.open = !this.open;\n\n this.dispatchEvent(\n new CustomEvent('message-click', {\n detail: {\n open: this.open,\n },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handlePrimaryActionClick(e: Event) {\n e.stopPropagation();\n\n this.dispatchEvent(\n new CustomEvent('primary-action-click', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleSecondaryActionClick(e: Event) {\n e.stopPropagation();\n\n this.dispatchEvent(\n new CustomEvent('secondary-action-click', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n override render() {\n return html`\n <div\n class=${classMap({\n wrapper: true,\n ['active-size-' + this.activeSize]: true,\n ['size-' + this.size]: true,\n ['enhanced-icon']: this.enhancedIcon,\n ['has-date']: this.hasTimestamp,\n ['stack-vertical']: this.stackVertical,\n ['stack-horizontal']: !this.stackVertical,\n })}\n role=\"button\"\n tabindex=\"0\"\n @click=${this.handleMessageClick}\n @keydown=${this.handleKeyDown}\n >\n <div class=\"content-container\">\n <div class=\"icon-container\">\n ${this.isShelved\n ? html`<div class=\"icon\">\n <obi-alerts-shelf></obi-alerts-shelf>\n </div>`\n : nothing}\n ${this.hasPrimaryIcon\n ? html`<div class=\"icon primary\">\n <slot name=\"primary-icon\"></slot>\n </div>`\n : nothing}\n ${this.hasSecondaryIcon\n ? html`<div class=\"icon secondary\">\n <slot name=\"secondary-icon\"></slot>\n </div>`\n : nothing}\n </div>\n <div class=\"text-container\">\n <div class=\"title-container\">\n <slot name=\"title\">${this.title}</slot>\n </div>\n <div class=\"description-container\">\n <slot name=\"description\">${this.description}</slot>\n </div>\n ${this.hasTimestamp\n ? html`<div class=\"date-container\">\n ${this.hasDay ? html`<span>${this.day}</span>` : nothing}\n <span>${this.time}</span>\n </div>`\n : nothing}\n <div class=\"chevron\">\n ${this.open\n ? html`<obi-chevron-up-google></obi-chevron-up-google>`\n : html`<obi-chevron-down-google></obi-chevron-down-google>`}\n </div>\n </div>\n </div>\n ${this.hasPrimaryAction ||\n this.hasSecondaryAction ||\n (this.hasTrailingIcon && !this.isVertical)\n ? html`<div class=\"action-button-container\" part=\"action-container\">\n ${this.hasSecondaryAction\n ? html`<obc-button\n variant=\"normal\"\n .fullWidth=${this.isVertical}\n @click=${this.handleSecondaryActionClick}\n >\n ${this.secondaryActionLabel}\n </obc-button>`\n : nothing}\n ${this.hasPrimaryAction\n ? html`<obc-button\n variant=\"normal\"\n .fullWidth=${this.isVertical}\n @click=${this.handlePrimaryActionClick}\n >\n ${this.hasActionLabelSlot\n ? html`<slot name=\"action-label\"></slot>`\n : this.primaryActionLabel}\n </obc-button>`\n : nothing}\n ${this.hasTrailingIcon && !this.isVertical\n ? html`<div class=\"trailing-icon\" part=\"trailing-icon\">\n <slot name=\"trailing-icon\"></slot>\n </div>`\n : nothing}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-message-menu-item': ObcMessageMenuItem;\n }\n}\n"],"names":["ObcMessageMenuItemSize"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"message-menu-item.js","sources":["../../../src/components/message-menu-item/message-menu-item.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './message-menu-item.css?inline';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../button/button.js';\nimport '../../icons/icon-chevron-down-google.js';\nimport '../../icons/icon-chevron-up-google.js';\nimport {customElement} from '../../decorator.js';\nimport '../../icons/icon-alerts-shelf.js';\n\nexport enum ObcMessageMenuItemSize {\n SingleLine = 'single-line',\n DoubleLine = 'double-line',\n}\n\n/**\n * `<obc-message-menu-item>` – An expandable message or notification item for use in message lists, notification panels, or alert menus.\n *\n * Displays a concise message row with optional icons, title, description, timestamp, and action buttons. Clicking the item expands it to reveal the full content. Designed for scannable lists where users may need to quickly review and act on individual messages.\n *\n * ## Features\n *\n * - **Size Variants:**\n * - `single-line`: Compact layout with title and description on one line (default).\n * - `double-line`: Two-line layout with title on top and description below.\n * - When clicked, both variants expand to show full multi-line content.\n *\n * - **Stack Direction:**\n * - `stackVertical=false` (default): Action buttons appear inline to the right of the content.\n * - `stackVertical=true`: Action buttons appear below the content, spanning full width.\n *\n * - **Icon Options:**\n * - Primary and secondary icon slots for visual context or status indicators.\n * - Enhanced icon mode (`enhancedIcon`) increases icon size for emphasis.\n * - Trailing icon slot (horizontal layout only) for additional actions.\n * - Shelved state (`isShelved`) displays a shelf icon automatically.\n *\n * - **Actions:**\n * - Supports up to two action buttons via `primaryActionLabel` and `secondaryActionLabel`.\n * - Each action can be independently disabled by setting `enablePrimaryAction` or `enableSecondaryAction` to `false`.\n * - In vertical layout, action buttons expand to full width.\n *\n * - **Timestamp:**\n * - Optional day and time display via `day` and `time` properties.\n *\n * ## Usage Guidelines\n *\n * Use `obc-message-menu-item` to present individual notifications, alerts, or messages within a scrollable list. Ideal for scenarios where users need to quickly scan items, expand for details, or take immediate action.\n *\n * - Use `single-line` for high-density lists where space is limited.\n * - Use `double-line` when the description needs more visibility in the collapsed state.\n * - Keep `stackVertical=false` (default) when actions should be quickly accessible inline.\n * - Use `stackVertical=true` when actions need more prominence or when space is narrow.\n * - Enable `enhancedIcon` to highlight important or priority messages.\n * - Use `isShelved` to indicate messages that have been temporarily set aside.\n * - Set `enablePrimaryAction` / `enableSecondaryAction` to `false` when an action is temporarily unavailable (e.g. awaiting a precondition) rather than removing the button.\n *\n * ## Slots\n *\n * Text content for `title`, `description`, and `action-label` supports both props (for plain text) and slots (for rich HTML like `CO<sub>2</sub>`).\n * To use a slot, set the corresponding `has*Slot` prop to `true`.\n *\n * | Slot Name | Enabled By | Purpose |\n * |------------------|--------------------------|---------------------------------------------------|\n * | `title` | `hasTitleSlot=true` | Message title. Use slot for rich HTML. |\n * | `description` | `hasDescriptionSlot=true`| Message description. Use slot for rich HTML. |\n * | `action-label` | `hasActionLabelSlot=true`| Primary action button label. Use slot for rich HTML. |\n * | `primary-icon` | `hasPrimaryIcon=true` | Main icon representing message type or status. |\n * | `secondary-icon` | `hasSecondaryIcon=true` | Additional icon for secondary status or context. |\n * | `trailing-icon` | `hasTrailingIcon=true` (horizontal only) | Icon button after action buttons. |\n *\n * ## Events\n *\n * - `message-click` – Fired when the message item is clicked. Detail includes `{ open: boolean }`.\n * - `primary-action-click` – Fired when the primary action button is clicked.\n * - `secondary-action-click` – Fired when the secondary action button is clicked.\n *\n * ## Example\n *\n * Using props (simple text):\n * ```html\n * <obc-message-menu-item\n * size=\"double-line\"\n * title=\"System Update\"\n * description=\"A new update is available for installation.\"\n * day=\"Yesterday\"\n * time=\"14:32\"\n * primaryActionLabel=\"Install\"\n * hasPrimaryIcon\n * >\n * <obi-placeholder slot=\"primary-icon\"></obi-placeholder>\n * </obc-message-menu-item>\n * ```\n *\n * Using slots (rich HTML):\n * ```html\n * <obc-message-menu-item\n * size=\"double-line\"\n * day=\"Yesterday\"\n * time=\"14:32\"\n * hasPrimaryIcon\n * hasTitleSlot\n * hasDescriptionSlot\n * hasActionLabelSlot\n * >\n * <span slot=\"title\">High CO<sub>2</sub> level</span>\n * <span slot=\"description\">CO<sub>2</sub> concentration exceeds safe limits.</span>\n * <span slot=\"action-label\">Acknowledge</span>\n * <obi-placeholder slot=\"primary-icon\"></obi-placeholder>\n * </obc-message-menu-item>\n * ```\n *\n * @slot title - Message title (shown when `hasTitleSlot` is true).\n * @slot description - Message description (shown when `hasDescriptionSlot` is true).\n * @slot action-label - Primary action button label (shown when `hasActionLabelSlot` is true).\n * @slot primary-icon - Main icon representing the message type or status (shown when `hasPrimaryIcon` is true).\n * @slot secondary-icon - Additional icon for secondary status/context (shown when `hasSecondaryIcon` is true).\n * @slot trailing-icon - Icon after action buttons, horizontal layout only (shown when `hasTrailingIcon` is true).\n * @fires message-click {CustomEvent<{open: boolean}>} Fired when the message item is clicked.\n * @fires primary-action-click {CustomEvent<void>} Fired when the primary action button is clicked.\n * @fires secondary-action-click {CustomEvent<void>} Fired when the secondary action button is clicked.\n */\n@customElement('obc-message-menu-item')\nexport class ObcMessageMenuItem extends LitElement {\n // Layout properties\n @property({type: String}) size: ObcMessageMenuItemSize =\n ObcMessageMenuItemSize.SingleLine;\n @property({type: Boolean}) stackVertical = false;\n @property({type: Boolean}) enhancedIcon = false;\n @property({type: Boolean}) open = false;\n\n // Text content properties\n @property({type: String}) override title = '';\n @property({type: String}) description = '';\n @property({type: String}) day = '';\n @property({type: String}) time = '';\n @property({type: String}) primaryActionLabel = '';\n @property({type: String}) secondaryActionLabel = '';\n @property({type: Boolean, attribute: false}) enablePrimaryAction = true;\n @property({type: Boolean, attribute: false}) enableSecondaryAction = true;\n\n // Visibility properties for icons (slots)\n @property({type: Boolean}) hasPrimaryIcon = false;\n @property({type: Boolean}) hasSecondaryIcon = false;\n @property({type: Boolean}) hasTrailingIcon = false;\n @property({type: Boolean}) isShelved = false;\n\n @property({type: Boolean}) hasActionLabelSlot = false;\n\n private get activeSize() {\n if (this.open) {\n return 'multi-line';\n }\n return this.size;\n }\n\n private get hasTimestamp() {\n return this.time !== '' || this.day !== '';\n }\n\n private get hasDay() {\n return this.day !== '';\n }\n\n private get hasPrimaryAction() {\n return this.primaryActionLabel !== '' || this.hasActionLabelSlot;\n }\n\n private get hasSecondaryAction() {\n return this.secondaryActionLabel !== '';\n }\n\n private get isVertical() {\n return this.stackVertical;\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n // Only handle key events on the wrapper itself, not on nested interactive elements\n if (e.target !== e.currentTarget) {\n return;\n }\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.handleMessageClick();\n }\n }\n\n private handleMessageClick() {\n this.open = !this.open;\n\n this.dispatchEvent(\n new CustomEvent('message-click', {\n detail: {\n open: this.open,\n },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handlePrimaryActionClick(e: Event) {\n e.stopPropagation();\n\n this.dispatchEvent(\n new CustomEvent('primary-action-click', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleSecondaryActionClick(e: Event) {\n e.stopPropagation();\n\n this.dispatchEvent(\n new CustomEvent('secondary-action-click', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n override render() {\n return html`\n <div\n class=${classMap({\n wrapper: true,\n ['active-size-' + this.activeSize]: true,\n ['size-' + this.size]: true,\n ['enhanced-icon']: this.enhancedIcon,\n ['has-date']: this.hasTimestamp,\n ['stack-vertical']: this.stackVertical,\n ['stack-horizontal']: !this.stackVertical,\n })}\n role=\"button\"\n tabindex=\"0\"\n @click=${this.handleMessageClick}\n @keydown=${this.handleKeyDown}\n >\n <div class=\"content-container\">\n <div class=\"icon-container\">\n ${this.isShelved\n ? html`<div class=\"icon\">\n <obi-alerts-shelf></obi-alerts-shelf>\n </div>`\n : nothing}\n ${this.hasPrimaryIcon\n ? html`<div class=\"icon primary\">\n <slot name=\"primary-icon\"></slot>\n </div>`\n : nothing}\n ${this.hasSecondaryIcon\n ? html`<div class=\"icon secondary\">\n <slot name=\"secondary-icon\"></slot>\n </div>`\n : nothing}\n </div>\n <div class=\"text-container\">\n <div class=\"title-container\">\n <slot name=\"title\">${this.title}</slot>\n </div>\n <div class=\"description-container\">\n <slot name=\"description\">${this.description}</slot>\n </div>\n ${this.hasTimestamp\n ? html`<div class=\"date-container\">\n ${this.hasDay ? html`<span>${this.day}</span>` : nothing}\n <span>${this.time}</span>\n </div>`\n : nothing}\n <div class=\"chevron\">\n ${this.open\n ? html`<obi-chevron-up-google></obi-chevron-up-google>`\n : html`<obi-chevron-down-google></obi-chevron-down-google>`}\n </div>\n </div>\n </div>\n ${this.hasPrimaryAction ||\n this.hasSecondaryAction ||\n (this.hasTrailingIcon && !this.isVertical)\n ? html`<div class=\"action-button-container\" part=\"action-container\">\n ${this.hasSecondaryAction\n ? html`<obc-button\n variant=\"normal\"\n .fullWidth=${this.isVertical}\n @click=${this.handleSecondaryActionClick}\n ?disabled=${!this.enableSecondaryAction}\n >\n ${this.secondaryActionLabel}\n </obc-button>`\n : nothing}\n ${this.hasPrimaryAction\n ? html`<obc-button\n variant=\"normal\"\n .fullWidth=${this.isVertical}\n @click=${this.handlePrimaryActionClick}\n ?disabled=${!this.enablePrimaryAction}\n >\n ${this.hasActionLabelSlot\n ? html`<slot name=\"action-label\"></slot>`\n : this.primaryActionLabel}\n </obc-button>`\n : nothing}\n ${this.hasTrailingIcon && !this.isVertical\n ? html`<div class=\"trailing-icon\" part=\"trailing-icon\">\n <slot name=\"trailing-icon\"></slot>\n </div>`\n : nothing}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-message-menu-item': ObcMessageMenuItem;\n }\n}\n"],"names":["ObcMessageMenuItemSize"],"mappings":";;;;;;;;;;;;;;;;;;;AAUO,IAAK,2CAAAA,4BAAL;AACLA,0BAAA,YAAA,IAAa;AACbA,0BAAA,YAAA,IAAa;AAFH,SAAAA;AAAA,GAAA,0BAAA,CAAA,CAAA;AAiHL,IAAM,qBAAN,cAAiC,WAAW;AAAA,EAA5C,cAAA;AAAA,UAAA,GAAA,SAAA;AAEqB,SAAA,OACxB;AACyB,SAAA,gBAAgB;AAChB,SAAA,eAAe;AACf,SAAA,OAAO;AAGR,SAAS,QAAQ;AACjB,SAAA,cAAc;AACd,SAAA,MAAM;AACN,SAAA,OAAO;AACP,SAAA,qBAAqB;AACrB,SAAA,uBAAuB;AACJ,SAAA,sBAAsB;AACtB,SAAA,wBAAwB;AAG1C,SAAA,iBAAiB;AACjB,SAAA,mBAAmB;AACnB,SAAA,kBAAkB;AAClB,SAAA,YAAY;AAEZ,SAAA,qBAAqB;AAAA,EAAA;AAAA,EAEhD,IAAY,aAAa;AACvB,QAAI,KAAK,MAAM;AACb,aAAO;AAAA,IACT;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAY,eAAe;AACzB,WAAO,KAAK,SAAS,MAAM,KAAK,QAAQ;AAAA,EAC1C;AAAA,EAEA,IAAY,SAAS;AACnB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAY,mBAAmB;AAC7B,WAAO,KAAK,uBAAuB,MAAM,KAAK;AAAA,EAChD;AAAA,EAEA,IAAY,qBAAqB;AAC/B,WAAO,KAAK,yBAAyB;AAAA,EACvC;AAAA,EAEA,IAAY,aAAa;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,cAAc,GAAkB;AAEtC,QAAI,EAAE,WAAW,EAAE,eAAe;AAChC;AAAA,IACF;AACA,QAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,QAAE,eAAA;AACF,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,qBAAqB;AAC3B,SAAK,OAAO,CAAC,KAAK;AAElB,SAAK;AAAA,MACH,IAAI,YAAY,iBAAiB;AAAA,QAC/B,QAAQ;AAAA,UACN,MAAM,KAAK;AAAA,QAAA;AAAA,QAEb,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAEL;AAAA,EAEQ,yBAAyB,GAAU;AACzC,MAAE,gBAAA;AAEF,SAAK;AAAA,MACH,IAAI,YAAY,wBAAwB;AAAA,QACtC,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAEL;AAAA,EAEQ,2BAA2B,GAAU;AAC3C,MAAE,gBAAA;AAEF,SAAK;AAAA,MACH,IAAI,YAAY,0BAA0B;AAAA,QACxC,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAEL;AAAA,EAES,SAAS;AAChB,WAAO;AAAA;AAAA,gBAEK,SAAS;AAAA,MACf,SAAS;AAAA,MACT,CAAC,iBAAiB,KAAK,UAAU,GAAG;AAAA,MACpC,CAAC,UAAU,KAAK,IAAI,GAAG;AAAA,MACvB,CAAC,eAAe,GAAG,KAAK;AAAA,MACxB,CAAC,UAAU,GAAG,KAAK;AAAA,MACnB,CAAC,gBAAgB,GAAG,KAAK;AAAA,MACzB,CAAC,kBAAkB,GAAG,CAAC,KAAK;AAAA,IAAA,CAC7B,CAAC;AAAA;AAAA;AAAA,iBAGO,KAAK,kBAAkB;AAAA,mBACrB,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA,cAIvB,KAAK,YACH;AAAA;AAAA,0BAGA,OAAO;AAAA,cACT,KAAK,iBACH;AAAA;AAAA,0BAGA,OAAO;AAAA,cACT,KAAK,mBACH;AAAA;AAAA,0BAGA,OAAO;AAAA;AAAA;AAAA;AAAA,mCAIY,KAAK,KAAK;AAAA;AAAA;AAAA,yCAGJ,KAAK,WAAW;AAAA;AAAA,cAE3C,KAAK,eACH;AAAA,oBACI,KAAK,SAAS,aAAa,KAAK,GAAG,YAAY,OAAO;AAAA,0BAChD,KAAK,IAAI;AAAA,0BAEnB,OAAO;AAAA;AAAA,gBAEP,KAAK,OACH,wDACA,yDAAyD;AAAA;AAAA;AAAA;AAAA,UAIjE,KAAK,oBACP,KAAK,sBACJ,KAAK,mBAAmB,CAAC,KAAK,aAC3B;AAAA,gBACI,KAAK,qBACH;AAAA;AAAA,iCAEe,KAAK,UAAU;AAAA,6BACnB,KAAK,0BAA0B;AAAA,gCAC5B,CAAC,KAAK,qBAAqB;AAAA;AAAA,sBAErC,KAAK,oBAAoB;AAAA,mCAE7B,OAAO;AAAA,gBACT,KAAK,mBACH;AAAA;AAAA,iCAEe,KAAK,UAAU;AAAA,6BACnB,KAAK,wBAAwB;AAAA,gCAC1B,CAAC,KAAK,mBAAmB;AAAA;AAAA,sBAEnC,KAAK,qBACH,0CACA,KAAK,kBAAkB;AAAA,mCAE7B,OAAO;AAAA,gBACT,KAAK,mBAAmB,CAAC,KAAK,aAC5B;AAAA;AAAA,4BAGA,OAAO;AAAA,sBAEb,OAAO;AAAA;AAAA;AAAA,EAGjB;AAGF;AAjMa,mBAgMK,SAAS,UAAU,YAAY;AA9LrB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAFb,mBAEe,WAAA,QAAA,CAAA;AAEC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAJd,mBAIgB,WAAA,iBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GALd,mBAKgB,WAAA,gBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GANd,mBAMgB,WAAA,QAAA,CAAA;AAGQ,gBAAA;AAAA,EAAlC,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GATb,mBASwB,WAAA,SAAA,CAAA;AACT,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAVb,mBAUe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAXb,mBAWe,WAAA,OAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAZb,mBAYe,WAAA,QAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAbb,mBAae,WAAA,sBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAdb,mBAce,WAAA,wBAAA,CAAA;AACmB,gBAAA;AAAA,EAA5C,SAAS,EAAC,MAAM,SAAS,WAAW,OAAM;AAAA,GAfhC,mBAekC,WAAA,uBAAA,CAAA;AACA,gBAAA;AAAA,EAA5C,SAAS,EAAC,MAAM,SAAS,WAAW,OAAM;AAAA,GAhBhC,mBAgBkC,WAAA,yBAAA,CAAA;AAGlB,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAnBd,mBAmBgB,WAAA,kBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GApBd,mBAoBgB,WAAA,oBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GArBd,mBAqBgB,WAAA,mBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAtBd,mBAsBgB,WAAA,aAAA,CAAA;AAEA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAxBd,mBAwBgB,WAAA,sBAAA,CAAA;AAxBhB,qBAAN,gBAAA;AAAA,EADN,cAAc,uBAAuB;AAAA,GACzB,kBAAA;"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
const componentStyle = css`
|
|
3
|
+
* {
|
|
4
|
+
-webkit-tap-highlight-color: transparent;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
:host {
|
|
8
|
+
display: inline-block;
|
|
9
|
+
line-height: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.wrapper {
|
|
13
|
+
display: inline-flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
width: fit-content;
|
|
16
|
+
--height: 24px;
|
|
17
|
+
--padding: 4px;
|
|
18
|
+
font-family: var(--font-family-main);
|
|
19
|
+
letter-spacing: var(--global-typography-generic-l-letter-spacing);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* The inner-wrapper is the box: its height (--height) is the full textbox
|
|
23
|
+
height, padding included. The content is sized to the cap height and
|
|
24
|
+
vertically centered, which leaves the padding as equal space above and
|
|
25
|
+
below. In engines that support text-box-trim the content box collapses to
|
|
26
|
+
the cap height exactly; in Firefox (no text-box-trim) the content keeps its
|
|
27
|
+
natural line box, so align-items:center + overflow:hidden crops it to the
|
|
28
|
+
same height instead. No padding here – the centering provides it.
|
|
29
|
+
(A small top padding could be added later to nudge the text up in Firefox.) */
|
|
30
|
+
|
|
31
|
+
.inner-wrapper {
|
|
32
|
+
box-sizing: border-box;
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: var(--alignment-justify, flex-end);
|
|
36
|
+
height: var(--height);
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* The spacer must share the content's exact font metrics so the width it
|
|
41
|
+
reserves equals the rendered content width. font-size-adjust scales the
|
|
42
|
+
font, so it has to match too. */
|
|
43
|
+
|
|
44
|
+
.content,
|
|
45
|
+
.length-spacer {
|
|
46
|
+
font-size: calc(var(--height) - 2 * var(--padding));
|
|
47
|
+
font-size-adjust: cap-height 1;
|
|
48
|
+
white-space: nowrap;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.content {
|
|
52
|
+
text-box-trim: trim-both;
|
|
53
|
+
text-box-edge: cap alphabetic;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.wrapper.size-xs .inner-wrapper {
|
|
57
|
+
--height: 16px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.wrapper.size-s .inner-wrapper {
|
|
61
|
+
--height: 20px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.wrapper.size-m .inner-wrapper {
|
|
65
|
+
--height: 24px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.wrapper.size-l .inner-wrapper {
|
|
69
|
+
--height: 32px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.wrapper.size-xl .inner-wrapper {
|
|
73
|
+
--height: 40px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.wrapper.font-weight-regular {
|
|
77
|
+
font-weight: var(--global-typography-generic-l-font-weight-regular);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.wrapper.font-weight-semibold {
|
|
81
|
+
font-weight: var(--global-typography-generic-l-font-weight-medium);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.wrapper.font-weight-bold {
|
|
85
|
+
font-weight: var(--global-typography-generic-l-font-weight-bold);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.wrapper.alignment-left {
|
|
89
|
+
--alignment-justify: flex-start;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.wrapper.alignment-center {
|
|
93
|
+
--alignment-justify: center;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.wrapper.alignment-right {
|
|
97
|
+
--alignment-justify: flex-end;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Reserves the box width from the \`length\` slot without occupying vertical
|
|
101
|
+
space. Acts as a minimum width so the box does not resize as visible
|
|
102
|
+
text changes. */
|
|
103
|
+
|
|
104
|
+
.length-spacer {
|
|
105
|
+
height: 0;
|
|
106
|
+
opacity: 0;
|
|
107
|
+
visibility: hidden;
|
|
108
|
+
overflow: hidden;
|
|
109
|
+
}
|
|
110
|
+
`;
|
|
111
|
+
export {
|
|
112
|
+
componentStyle as default
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=textbox.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textbox.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export declare enum ObcTextboxAlignment {
|
|
3
|
+
Left = "left",
|
|
4
|
+
Center = "center",
|
|
5
|
+
Right = "right"
|
|
6
|
+
}
|
|
7
|
+
export declare enum ObcTextboxSize {
|
|
8
|
+
xs = "xs",
|
|
9
|
+
s = "s",
|
|
10
|
+
m = "m",
|
|
11
|
+
l = "l",
|
|
12
|
+
xl = "xl"
|
|
13
|
+
}
|
|
14
|
+
export declare enum ObcTextboxFontWeight {
|
|
15
|
+
regular = "regular",
|
|
16
|
+
semibold = "semibold",
|
|
17
|
+
bold = "bold"
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* `<obc-textbox>` – A text container that renders inline text at a
|
|
21
|
+
* precise, cap-height-trimmed size with configurable alignment and reservable
|
|
22
|
+
* width.
|
|
23
|
+
*
|
|
24
|
+
* Use it to present short, read-only strings – such as values, labels, or
|
|
25
|
+
* units – where vertical metrics must line up exactly across rows and the
|
|
26
|
+
* horizontal footprint should stay stable while the text changes (for example
|
|
27
|
+
* a numeric value that updates frequently). Synonyms: text container, value
|
|
28
|
+
* box, label box.
|
|
29
|
+
*
|
|
30
|
+
* ## Features / Variants
|
|
31
|
+
* - **Size:** `xs`, `s`, `m` (default), `l`, `xl` – each maps to a fixed box
|
|
32
|
+
* height (16 / 20 / 24 / 32 / 40 px) with 4px padding above and below, giving
|
|
33
|
+
* cap heights of 8 / 12 / 16 / 24 / 32 px so text aligns to a predictable
|
|
34
|
+
* grid.
|
|
35
|
+
* - **Font weight:** `regular` (default), `semibold`, `bold`.
|
|
36
|
+
* - **Alignment:** `left`, `center`, `right` (default) – positions the text
|
|
37
|
+
* within the box's width when the box is wider than the content.
|
|
38
|
+
* - **Reserved width:** content placed in the `length` slot reserves a minimum
|
|
39
|
+
* width invisibly, so the box does not resize as the visible text changes.
|
|
40
|
+
* The box always shows all content – it never crops.
|
|
41
|
+
*
|
|
42
|
+
* ## Usage Guidelines
|
|
43
|
+
* - Pass the longest expected string to the `length` slot (e.g. `"888.8"` or
|
|
44
|
+
* `"Wind speed"`) so the box reserves space and does not jump in width as the
|
|
45
|
+
* visible value updates.
|
|
46
|
+
* - This is a display primitive for static text – use an input component for
|
|
47
|
+
* editable values.
|
|
48
|
+
*
|
|
49
|
+
* ## Slots
|
|
50
|
+
* | Slot | Renders when… | Purpose |
|
|
51
|
+
* |-----------|--------------------|------------------------------------------------------|
|
|
52
|
+
* | (default) | Always | The visible text content. |
|
|
53
|
+
* | `length` | Always (invisible) | Reserves a minimum width based on its content width. |
|
|
54
|
+
*
|
|
55
|
+
* @slot - The visible text content.
|
|
56
|
+
* @slot length - Reserves a minimum width based on its content width.
|
|
57
|
+
*/
|
|
58
|
+
export declare class ObcTextbox extends LitElement {
|
|
59
|
+
alignment: ObcTextboxAlignment;
|
|
60
|
+
size: ObcTextboxSize;
|
|
61
|
+
fontWeight: ObcTextboxFontWeight;
|
|
62
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
63
|
+
static styles: import('lit').CSSResult;
|
|
64
|
+
}
|
|
65
|
+
declare global {
|
|
66
|
+
interface HTMLElementTagNameMap {
|
|
67
|
+
'obc-textbox': ObcTextbox;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=textbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textbox.d.ts","sourceRoot":"","sources":["../../../src/components/textbox/textbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAkB,MAAM,KAAK,CAAC;AAMhD,oBAAY,mBAAmB;IAC7B,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,KAAK,UAAU;CAChB;AAED,oBAAY,cAAc;IACxB,EAAE,OAAO;IACT,CAAC,MAAM;IACP,CAAC,MAAM;IACP,CAAC,MAAM;IACP,EAAE,OAAO;CACV;AAED,oBAAY,oBAAoB;IAC9B,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,IAAI,SAAS;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBACa,UAAW,SAAQ,UAAU;IACd,SAAS,EAAE,mBAAmB,CAC5B;IACF,IAAI,EAAE,cAAc,CAAoB;IACxC,UAAU,EAAE,oBAAoB,CAC3B;IAEtB,MAAM;IAsBf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { unsafeCSS, LitElement, html } from "lit";
|
|
2
|
+
import { customElement } from "../../decorator.js";
|
|
3
|
+
import componentStyle from "./textbox.css.js";
|
|
4
|
+
import { property } from "lit/decorators.js";
|
|
5
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
8
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
9
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
10
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
11
|
+
if (decorator = decorators[i])
|
|
12
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
13
|
+
if (kind && result) __defProp(target, key, result);
|
|
14
|
+
return result;
|
|
15
|
+
};
|
|
16
|
+
var ObcTextboxAlignment = /* @__PURE__ */ ((ObcTextboxAlignment2) => {
|
|
17
|
+
ObcTextboxAlignment2["Left"] = "left";
|
|
18
|
+
ObcTextboxAlignment2["Center"] = "center";
|
|
19
|
+
ObcTextboxAlignment2["Right"] = "right";
|
|
20
|
+
return ObcTextboxAlignment2;
|
|
21
|
+
})(ObcTextboxAlignment || {});
|
|
22
|
+
var ObcTextboxSize = /* @__PURE__ */ ((ObcTextboxSize2) => {
|
|
23
|
+
ObcTextboxSize2["xs"] = "xs";
|
|
24
|
+
ObcTextboxSize2["s"] = "s";
|
|
25
|
+
ObcTextboxSize2["m"] = "m";
|
|
26
|
+
ObcTextboxSize2["l"] = "l";
|
|
27
|
+
ObcTextboxSize2["xl"] = "xl";
|
|
28
|
+
return ObcTextboxSize2;
|
|
29
|
+
})(ObcTextboxSize || {});
|
|
30
|
+
var ObcTextboxFontWeight = /* @__PURE__ */ ((ObcTextboxFontWeight2) => {
|
|
31
|
+
ObcTextboxFontWeight2["regular"] = "regular";
|
|
32
|
+
ObcTextboxFontWeight2["semibold"] = "semibold";
|
|
33
|
+
ObcTextboxFontWeight2["bold"] = "bold";
|
|
34
|
+
return ObcTextboxFontWeight2;
|
|
35
|
+
})(ObcTextboxFontWeight || {});
|
|
36
|
+
let ObcTextbox = class extends LitElement {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(...arguments);
|
|
39
|
+
this.alignment = "right";
|
|
40
|
+
this.size = "m";
|
|
41
|
+
this.fontWeight = "regular";
|
|
42
|
+
}
|
|
43
|
+
render() {
|
|
44
|
+
return html`
|
|
45
|
+
<div
|
|
46
|
+
class=${classMap({
|
|
47
|
+
wrapper: true,
|
|
48
|
+
[`alignment-${this.alignment}`]: true,
|
|
49
|
+
[`size-${this.size}`]: true,
|
|
50
|
+
[`font-weight-${this.fontWeight}`]: true
|
|
51
|
+
})}
|
|
52
|
+
>
|
|
53
|
+
<div class="inner-wrapper">
|
|
54
|
+
<div class="content">
|
|
55
|
+
<slot></slot>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="length-spacer" aria-hidden="true">
|
|
59
|
+
<slot name="length"></slot>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
ObcTextbox.styles = unsafeCSS(componentStyle);
|
|
66
|
+
__decorateClass([
|
|
67
|
+
property({ type: String })
|
|
68
|
+
], ObcTextbox.prototype, "alignment", 2);
|
|
69
|
+
__decorateClass([
|
|
70
|
+
property({ type: String })
|
|
71
|
+
], ObcTextbox.prototype, "size", 2);
|
|
72
|
+
__decorateClass([
|
|
73
|
+
property({ type: String })
|
|
74
|
+
], ObcTextbox.prototype, "fontWeight", 2);
|
|
75
|
+
ObcTextbox = __decorateClass([
|
|
76
|
+
customElement("obc-textbox")
|
|
77
|
+
], ObcTextbox);
|
|
78
|
+
export {
|
|
79
|
+
ObcTextbox,
|
|
80
|
+
ObcTextboxAlignment,
|
|
81
|
+
ObcTextboxFontWeight,
|
|
82
|
+
ObcTextboxSize
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=textbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textbox.js","sources":["../../../src/components/textbox/textbox.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './textbox.css?inline';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nexport enum ObcTextboxAlignment {\n Left = 'left',\n Center = 'center',\n Right = 'right',\n}\n\nexport enum ObcTextboxSize {\n xs = 'xs',\n s = 's',\n m = 'm',\n l = 'l',\n xl = 'xl',\n}\n\nexport enum ObcTextboxFontWeight {\n regular = 'regular',\n semibold = 'semibold',\n bold = 'bold',\n}\n\n/**\n * `<obc-textbox>` – A text container that renders inline text at a\n * precise, cap-height-trimmed size with configurable alignment and reservable\n * width.\n *\n * Use it to present short, read-only strings – such as values, labels, or\n * units – where vertical metrics must line up exactly across rows and the\n * horizontal footprint should stay stable while the text changes (for example\n * a numeric value that updates frequently). Synonyms: text container, value\n * box, label box.\n *\n * ## Features / Variants\n * - **Size:** `xs`, `s`, `m` (default), `l`, `xl` – each maps to a fixed box\n * height (16 / 20 / 24 / 32 / 40 px) with 4px padding above and below, giving\n * cap heights of 8 / 12 / 16 / 24 / 32 px so text aligns to a predictable\n * grid.\n * - **Font weight:** `regular` (default), `semibold`, `bold`.\n * - **Alignment:** `left`, `center`, `right` (default) – positions the text\n * within the box's width when the box is wider than the content.\n * - **Reserved width:** content placed in the `length` slot reserves a minimum\n * width invisibly, so the box does not resize as the visible text changes.\n * The box always shows all content – it never crops.\n *\n * ## Usage Guidelines\n * - Pass the longest expected string to the `length` slot (e.g. `\"888.8\"` or\n * `\"Wind speed\"`) so the box reserves space and does not jump in width as the\n * visible value updates.\n * - This is a display primitive for static text – use an input component for\n * editable values.\n *\n * ## Slots\n * | Slot | Renders when… | Purpose |\n * |-----------|--------------------|------------------------------------------------------|\n * | (default) | Always | The visible text content. |\n * | `length` | Always (invisible) | Reserves a minimum width based on its content width. |\n *\n * @slot - The visible text content.\n * @slot length - Reserves a minimum width based on its content width.\n */\n@customElement('obc-textbox')\nexport class ObcTextbox extends LitElement {\n @property({type: String}) alignment: ObcTextboxAlignment =\n ObcTextboxAlignment.Right;\n @property({type: String}) size: ObcTextboxSize = ObcTextboxSize.m;\n @property({type: String}) fontWeight: ObcTextboxFontWeight =\n ObcTextboxFontWeight.regular;\n\n override render() {\n return html`\n <div\n class=${classMap({\n wrapper: true,\n [`alignment-${this.alignment}`]: true,\n [`size-${this.size}`]: true,\n [`font-weight-${this.fontWeight}`]: true,\n })}\n >\n <div class=\"inner-wrapper\">\n <div class=\"content\">\n <slot></slot>\n </div>\n </div>\n <div class=\"length-spacer\" aria-hidden=\"true\">\n <slot name=\"length\"></slot>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-textbox': ObcTextbox;\n }\n}\n"],"names":["ObcTextboxAlignment","ObcTextboxSize","ObcTextboxFontWeight"],"mappings":";;;;;;;;;;;;;;;AAMO,IAAK,wCAAAA,yBAAL;AACLA,uBAAA,MAAA,IAAO;AACPA,uBAAA,QAAA,IAAS;AACTA,uBAAA,OAAA,IAAQ;AAHE,SAAAA;AAAA,GAAA,uBAAA,CAAA,CAAA;AAML,IAAK,mCAAAC,oBAAL;AACLA,kBAAA,IAAA,IAAK;AACLA,kBAAA,GAAA,IAAI;AACJA,kBAAA,GAAA,IAAI;AACJA,kBAAA,GAAA,IAAI;AACJA,kBAAA,IAAA,IAAK;AALK,SAAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAQL,IAAK,yCAAAC,0BAAL;AACLA,wBAAA,SAAA,IAAU;AACVA,wBAAA,UAAA,IAAW;AACXA,wBAAA,MAAA,IAAO;AAHG,SAAAA;AAAA,GAAA,wBAAA,CAAA,CAAA;AA8CL,IAAM,aAAN,cAAyB,WAAW;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,YACxB;AACwB,SAAA,OAAuB;AACvB,SAAA,aACxB;AAAA,EAAA;AAAA,EAEO,SAAS;AAChB,WAAO;AAAA;AAAA,gBAEK,SAAS;AAAA,MACf,SAAS;AAAA,MACT,CAAC,aAAa,KAAK,SAAS,EAAE,GAAG;AAAA,MACjC,CAAC,QAAQ,KAAK,IAAI,EAAE,GAAG;AAAA,MACvB,CAAC,eAAe,KAAK,UAAU,EAAE,GAAG;AAAA,IAAA,CACrC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYR;AAGF;AA9Ba,WA6BK,SAAS,UAAU,cAAc;AA5BvB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,WACe,WAAA,aAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,WAGe,WAAA,QAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,WAIe,WAAA,cAAA,CAAA;AAJf,aAAN,gBAAA;AAAA,EADN,cAAc,aAAa;AAAA,GACf,UAAA;"}
|
package/eslint.config.mjs
CHANGED
|
@@ -301,16 +301,11 @@ const openbridgePlugin = {
|
|
|
301
301
|
p.key.type === 'Identifier' &&
|
|
302
302
|
p.key.name === 'attribute'
|
|
303
303
|
);
|
|
304
|
-
const isBuildingBlock =
|
|
305
|
-
typeof context.filename === 'string' &&
|
|
306
|
-
context.filename.includes('building-blocks');
|
|
307
304
|
if (property?.value?.value === false) {
|
|
308
305
|
return;
|
|
309
306
|
}
|
|
310
|
-
let message =
|
|
311
|
-
|
|
312
|
-
message += ' or set Attribute: false on the property decorator';
|
|
313
|
-
}
|
|
307
|
+
let message =
|
|
308
|
+
'Prefer boolean property default values of false or set attribute: false on the property decorator';
|
|
314
309
|
context.report({
|
|
315
310
|
node,
|
|
316
311
|
message,
|
package/package.json
CHANGED
|
@@ -3,7 +3,11 @@ import {html, nothing} from 'lit';
|
|
|
3
3
|
import './alert-menu-item.js';
|
|
4
4
|
import '../../icons/icon-engine.js';
|
|
5
5
|
import '../alert-icon/alert-icon.js';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
ObcAlertMenuItem,
|
|
8
|
+
ObcAlertMenuItemActionState,
|
|
9
|
+
ObcAlertMenuItemStatus,
|
|
10
|
+
} from './alert-menu-item.js';
|
|
7
11
|
|
|
8
12
|
const meta: Meta<ObcAlertMenuItem> = {
|
|
9
13
|
title: 'Application Components/Alerts/Alert Menu Item',
|
|
@@ -17,6 +21,9 @@ const meta: Meta<ObcAlertMenuItem> = {
|
|
|
17
21
|
status: ObcAlertMenuItemStatus.Unacknowledged,
|
|
18
22
|
hasIcon: false,
|
|
19
23
|
shelved: false,
|
|
24
|
+
secondaryActionLabel: '',
|
|
25
|
+
primaryActionState: ObcAlertMenuItemActionState.Enabled,
|
|
26
|
+
secondaryActionState: ObcAlertMenuItemActionState.Enabled,
|
|
20
27
|
},
|
|
21
28
|
render: (args) => html`
|
|
22
29
|
<obc-alert-menu-item
|
|
@@ -27,6 +34,9 @@ const meta: Meta<ObcAlertMenuItem> = {
|
|
|
27
34
|
.shelved=${args.shelved}
|
|
28
35
|
.hasIcon=${args.hasIcon}
|
|
29
36
|
.status=${args.status}
|
|
37
|
+
.secondaryActionLabel=${args.secondaryActionLabel}
|
|
38
|
+
.primaryActionState=${args.primaryActionState}
|
|
39
|
+
.secondaryActionState=${args.secondaryActionState}
|
|
30
40
|
>
|
|
31
41
|
<obc-alert-icon slot="alert-icon" type="alarm" active></obc-alert-icon>
|
|
32
42
|
${args.hasIcon ? html`<obi-engine slot="icon"></obi-engine>` : nothing}
|
|
@@ -43,6 +53,15 @@ const meta: Meta<ObcAlertMenuItem> = {
|
|
|
43
53
|
},
|
|
44
54
|
hasIcon: {control: 'boolean'},
|
|
45
55
|
shelved: {control: 'boolean'},
|
|
56
|
+
secondaryActionLabel: {control: 'text'},
|
|
57
|
+
primaryActionState: {
|
|
58
|
+
control: 'select',
|
|
59
|
+
options: Object.values(ObcAlertMenuItemActionState),
|
|
60
|
+
},
|
|
61
|
+
secondaryActionState: {
|
|
62
|
+
control: 'select',
|
|
63
|
+
options: Object.values(ObcAlertMenuItemActionState),
|
|
64
|
+
},
|
|
46
65
|
},
|
|
47
66
|
};
|
|
48
67
|
|
|
@@ -83,3 +102,23 @@ export const NoAckWarning: Story = {
|
|
|
83
102
|
status: ObcAlertMenuItemStatus.NoAckWarning,
|
|
84
103
|
},
|
|
85
104
|
};
|
|
105
|
+
|
|
106
|
+
export const WithSecondaryAction: Story = {
|
|
107
|
+
args: {
|
|
108
|
+
secondaryActionLabel: 'Mute',
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const SecondaryActionDisabled: Story = {
|
|
113
|
+
args: {
|
|
114
|
+
secondaryActionLabel: 'Mute',
|
|
115
|
+
secondaryActionState: ObcAlertMenuItemActionState.Disabled,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const PrimaryActionNone: Story = {
|
|
120
|
+
args: {
|
|
121
|
+
secondaryActionLabel: 'Mute',
|
|
122
|
+
primaryActionState: ObcAlertMenuItemActionState.None,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
@@ -20,6 +20,18 @@ export enum ObcAlertMenuItemStatus {
|
|
|
20
20
|
Rectified = 'rectified',
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Appearance of an alert menu item action.
|
|
25
|
+
* - `enabled`: Action is shown and interactive (default).
|
|
26
|
+
* - `disabled`: Action is shown but cannot be triggered.
|
|
27
|
+
* - `none`: Action is removed and takes no space.
|
|
28
|
+
*/
|
|
29
|
+
export enum ObcAlertMenuItemActionState {
|
|
30
|
+
Enabled = 'enabled',
|
|
31
|
+
Disabled = 'disabled',
|
|
32
|
+
None = 'none',
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
/**
|
|
24
36
|
* `<obc-alert-menu-item>` – A list item component for displaying alert or notification entries with status, icons, and action controls.
|
|
25
37
|
*
|
|
@@ -33,7 +45,8 @@ export enum ObcAlertMenuItemStatus {
|
|
|
33
45
|
* - **Icon Support:** Optional secondary icon (e.g., system or source) and a primary alert icon. Tertiary "shelved" icon appears if the alert is shelved.
|
|
34
46
|
* - **Time and Day Display:** Optionally shows day and/or time for the alert occurrence.
|
|
35
47
|
* - **Expandable:** Can be toggled open/closed for additional details (via click).
|
|
36
|
-
* - **Action
|
|
48
|
+
* - **Action Buttons:** Displays an "ACK" button for unacknowledged alerts and an optional secondary action (label set via `secondaryActionLabel`); each triggers an event when clicked.
|
|
49
|
+
* - Each action's appearance is controlled independently via `primaryActionState` / `secondaryActionState` (`enabled`, `disabled`, or `none`).
|
|
37
50
|
* - **Animated Intro:** Optional animation when the item appears.
|
|
38
51
|
* - **Size Options:** Supports single-line or multi-line layouts (see `size` property).
|
|
39
52
|
*
|
|
@@ -44,6 +57,8 @@ export enum ObcAlertMenuItemStatus {
|
|
|
44
57
|
* - Provide a relevant icon in the `alert-icon` slot to visually indicate the alert type.
|
|
45
58
|
* - Use the `icon` slot for a source/system icon if needed.
|
|
46
59
|
* - Only show the "ACK" action for alerts that require acknowledgment.
|
|
60
|
+
* - Provide `secondaryActionLabel` to add a second action alongside ACK.
|
|
61
|
+
* - Use `primaryActionState` / `secondaryActionState` to temporarily disable an action (`disabled`) or remove it without leaving a gap (`none`).
|
|
47
62
|
* - Use the `shelved` property to indicate alerts that are temporarily deferred.
|
|
48
63
|
*
|
|
49
64
|
* ### Slots
|
|
@@ -54,6 +69,7 @@ export enum ObcAlertMenuItemStatus {
|
|
|
54
69
|
*
|
|
55
70
|
* ### Events
|
|
56
71
|
* - **ack-click** – Fired when the ACK action button is clicked.
|
|
72
|
+
* - **ack-secondary-click** – Fired when the secondary action button is clicked.
|
|
57
73
|
* - **item-click** – Fired when the alert menu item is clicked (toggles open/closed).
|
|
58
74
|
*
|
|
59
75
|
* ### Best Practices
|
|
@@ -81,6 +97,7 @@ export enum ObcAlertMenuItemStatus {
|
|
|
81
97
|
* @slot icon - Optional secondary icon (e.g., source/system).
|
|
82
98
|
*
|
|
83
99
|
* @fires ack-click {CustomEvent<void>} Fired when the ACK action button is clicked.
|
|
100
|
+
* @fires ack-secondary-click {CustomEvent<void>} Fired when the secondary action button is clicked.
|
|
84
101
|
* @fires item-click {CustomEvent<void>} Fired when the alert menu item is clicked.
|
|
85
102
|
*/
|
|
86
103
|
@customElement('obc-alert-menu-item')
|
|
@@ -146,10 +163,51 @@ export class ObcAlertMenuItem extends LitElement {
|
|
|
146
163
|
*/
|
|
147
164
|
@property({type: Boolean}) animateIntro = false;
|
|
148
165
|
|
|
166
|
+
/**
|
|
167
|
+
* The label for the secondary action button.
|
|
168
|
+
* Unlike the primary (ACK) action, the secondary label is not derived from
|
|
169
|
+
* `status`; it must be provided explicitly. The secondary action is only
|
|
170
|
+
* shown when a non-empty label is set and `secondaryActionState` is not
|
|
171
|
+
* `none`.
|
|
172
|
+
*/
|
|
173
|
+
@property({type: String}) secondaryActionLabel = '';
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Controls the appearance of the primary (ACK) action.
|
|
177
|
+
* See {@link ObcAlertMenuItemActionState} for the available states.
|
|
178
|
+
*/
|
|
179
|
+
@property({type: String}) primaryActionState: ObcAlertMenuItemActionState =
|
|
180
|
+
ObcAlertMenuItemActionState.Enabled;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Controls the appearance of the secondary action.
|
|
184
|
+
* See {@link ObcAlertMenuItemActionState} for the available states.
|
|
185
|
+
*/
|
|
186
|
+
@property({type: String}) secondaryActionState: ObcAlertMenuItemActionState =
|
|
187
|
+
ObcAlertMenuItemActionState.None;
|
|
188
|
+
|
|
149
189
|
private get primaryActionLabel() {
|
|
190
|
+
if (this.primaryActionState === ObcAlertMenuItemActionState.None) {
|
|
191
|
+
return '';
|
|
192
|
+
}
|
|
150
193
|
return this.status === ObcAlertMenuItemStatus.Unacknowledged ? 'ACK' : '';
|
|
151
194
|
}
|
|
152
195
|
|
|
196
|
+
private get secondaryActionLabelToShow() {
|
|
197
|
+
if (this.secondaryActionState === ObcAlertMenuItemActionState.None) {
|
|
198
|
+
return '';
|
|
199
|
+
}
|
|
200
|
+
return this.secondaryActionLabel;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private get primaryActionDisabled() {
|
|
204
|
+
return this.primaryActionState === ObcAlertMenuItemActionState.Disabled;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private get secondaryActionDisabled() {
|
|
208
|
+
return this.secondaryActionState === ObcAlertMenuItemActionState.Disabled;
|
|
209
|
+
}
|
|
210
|
+
|
|
153
211
|
private get hasTrailingIcon() {
|
|
154
212
|
// True when we need the action container but don't have an ACK button
|
|
155
213
|
return this.status !== ObcAlertMenuItemStatus.Unacknowledged;
|
|
@@ -164,6 +222,10 @@ export class ObcAlertMenuItem extends LitElement {
|
|
|
164
222
|
this.dispatchEvent(new CustomEvent('ack-click'));
|
|
165
223
|
}
|
|
166
224
|
|
|
225
|
+
private handleSecondaryActionClick() {
|
|
226
|
+
this.dispatchEvent(new CustomEvent('ack-secondary-click'));
|
|
227
|
+
}
|
|
228
|
+
|
|
167
229
|
override render() {
|
|
168
230
|
return html`
|
|
169
231
|
<obc-message-menu-item
|
|
@@ -172,6 +234,9 @@ export class ObcAlertMenuItem extends LitElement {
|
|
|
172
234
|
.day=${this.day}
|
|
173
235
|
.time=${this.time}
|
|
174
236
|
.primaryActionLabel=${this.primaryActionLabel}
|
|
237
|
+
.secondaryActionLabel=${this.secondaryActionLabelToShow}
|
|
238
|
+
.enablePrimaryAction=${!this.primaryActionDisabled}
|
|
239
|
+
.enableSecondaryAction=${!this.secondaryActionDisabled}
|
|
175
240
|
.size=${this.size}
|
|
176
241
|
.open=${this.open}
|
|
177
242
|
.hasSecondaryIcon=${this.hasIcon}
|
|
@@ -181,6 +246,7 @@ export class ObcAlertMenuItem extends LitElement {
|
|
|
181
246
|
hasPrimaryIcon
|
|
182
247
|
@message-click=${this.handleMessageClick}
|
|
183
248
|
@primary-action-click=${this.handleActionClick}
|
|
249
|
+
@secondary-action-click=${this.handleSecondaryActionClick}
|
|
184
250
|
>
|
|
185
251
|
<slot name="alert-icon" slot="primary-icon"></slot>
|
|
186
252
|
<slot name="title" slot="title">${this.title}</slot>
|
|
@@ -36,6 +36,8 @@ const meta: Meta<ObcMessageMenuItem> = {
|
|
|
36
36
|
time: {control: 'text'},
|
|
37
37
|
primaryActionLabel: {control: 'text'},
|
|
38
38
|
secondaryActionLabel: {control: 'text'},
|
|
39
|
+
enablePrimaryAction: {control: 'boolean'},
|
|
40
|
+
enableSecondaryAction: {control: 'boolean'},
|
|
39
41
|
// Icon slots
|
|
40
42
|
hasPrimaryIcon: {control: 'boolean'},
|
|
41
43
|
hasSecondaryIcon: {control: 'boolean'},
|
|
@@ -57,6 +59,8 @@ const meta: Meta<ObcMessageMenuItem> = {
|
|
|
57
59
|
time: '',
|
|
58
60
|
primaryActionLabel: '',
|
|
59
61
|
secondaryActionLabel: '',
|
|
62
|
+
enablePrimaryAction: true,
|
|
63
|
+
enableSecondaryAction: true,
|
|
60
64
|
hasPrimaryIcon: false,
|
|
61
65
|
hasSecondaryIcon: false,
|
|
62
66
|
hasTrailingIcon: false,
|
|
@@ -75,6 +79,8 @@ const meta: Meta<ObcMessageMenuItem> = {
|
|
|
75
79
|
.time=${args.time}
|
|
76
80
|
.primaryActionLabel=${args.primaryActionLabel}
|
|
77
81
|
.secondaryActionLabel=${args.secondaryActionLabel}
|
|
82
|
+
.enablePrimaryAction=${args.enablePrimaryAction}
|
|
83
|
+
.enableSecondaryAction=${args.enableSecondaryAction}
|
|
78
84
|
.hasPrimaryIcon=${args.hasPrimaryIcon}
|
|
79
85
|
.hasSecondaryIcon=${args.hasSecondaryIcon}
|
|
80
86
|
.hasTrailingIcon=${args.hasTrailingIcon}
|
|
@@ -259,6 +265,18 @@ export const HorizontalWithTwoActions: Story = {
|
|
|
259
265
|
},
|
|
260
266
|
};
|
|
261
267
|
|
|
268
|
+
export const HorizontalWithOneDisabledAction: Story = {
|
|
269
|
+
args: {
|
|
270
|
+
size: ObcMessageMenuItemSize.DoubleLine,
|
|
271
|
+
hasPrimaryIcon: true,
|
|
272
|
+
day: 'Yesterday',
|
|
273
|
+
time: '09:12:34',
|
|
274
|
+
primaryActionLabel: 'Action',
|
|
275
|
+
secondaryActionLabel: 'Action 2',
|
|
276
|
+
enableSecondaryAction: false,
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
|
|
262
280
|
export const HorizontalWithTrailingIcon: Story = {
|
|
263
281
|
args: {
|
|
264
282
|
size: ObcMessageMenuItemSize.DoubleLine,
|