@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.
Files changed (82) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +37 -33
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +28 -23
  4. package/dist/ar/poi/poi-base.d.ts +6 -0
  5. package/dist/ar/poi/poi-base.d.ts.map +1 -1
  6. package/dist/ar/poi/poi-base.js.map +1 -1
  7. package/dist/ar/poi-button/poi-button.d.ts +2 -2
  8. package/dist/ar/poi-button/poi-button.js.map +1 -1
  9. package/dist/components/accordion-card/accordion-card.d.ts.map +1 -1
  10. package/dist/components/accordion-card/accordion-card.js.map +1 -1
  11. package/dist/components/advice-message-item/advice-message-item.d.ts +4 -2
  12. package/dist/components/advice-message-item/advice-message-item.d.ts.map +1 -1
  13. package/dist/components/advice-message-item/advice-message-item.js +4 -2
  14. package/dist/components/advice-message-item/advice-message-item.js.map +1 -1
  15. package/dist/components/app-menu/app-menu.d.ts +1 -1
  16. package/dist/components/app-menu/app-menu.js +1 -1
  17. package/dist/components/app-menu/app-menu.js.map +1 -1
  18. package/dist/components/brilliance-menu/brilliance-menu.d.ts +8 -4
  19. package/dist/components/brilliance-menu/brilliance-menu.d.ts.map +1 -1
  20. package/dist/components/brilliance-menu/brilliance-menu.js +8 -4
  21. package/dist/components/brilliance-menu/brilliance-menu.js.map +1 -1
  22. package/dist/components/check-button/check-button.js.map +1 -1
  23. package/dist/components/checkbox/checkbox.d.ts +2 -2
  24. package/dist/components/checkbox/checkbox.js.map +1 -1
  25. package/dist/components/command-menu/command-menu.d.ts +1 -1
  26. package/dist/components/command-menu/command-menu.js +1 -1
  27. package/dist/components/command-menu/command-menu.js.map +1 -1
  28. package/dist/components/dropdown-button/dropdown-button.d.ts +2 -2
  29. package/dist/components/dropdown-button/dropdown-button.js +2 -2
  30. package/dist/components/dropdown-button/dropdown-button.js.map +1 -1
  31. package/dist/components/menu-button/menu-button.d.ts.map +1 -1
  32. package/dist/components/menu-button/menu-button.js.map +1 -1
  33. package/dist/components/navigation-item/navigation-item.d.ts +1 -5
  34. package/dist/components/navigation-item/navigation-item.d.ts.map +1 -1
  35. package/dist/components/navigation-item/navigation-item.js +0 -8
  36. package/dist/components/navigation-item/navigation-item.js.map +1 -1
  37. package/dist/components/navigation-item-group/navigation-item-group.d.ts +2 -1
  38. package/dist/components/navigation-item-group/navigation-item-group.d.ts.map +1 -1
  39. package/dist/components/navigation-item-group/navigation-item-group.js +2 -1
  40. package/dist/components/navigation-item-group/navigation-item-group.js.map +1 -1
  41. package/dist/components/notification-button/notification-button.d.ts +1 -1
  42. package/dist/components/notification-button/notification-button.js +1 -1
  43. package/dist/components/notification-button/notification-button.js.map +1 -1
  44. package/dist/components/notification-message-item/notification-message-item.d.ts +4 -2
  45. package/dist/components/notification-message-item/notification-message-item.d.ts.map +1 -1
  46. package/dist/components/notification-message-item/notification-message-item.js +4 -2
  47. package/dist/components/notification-message-item/notification-message-item.js.map +1 -1
  48. package/dist/components/pivot-item/pivot-item.d.ts +1 -1
  49. package/dist/components/pivot-item/pivot-item.js +1 -1
  50. package/dist/components/pivot-item/pivot-item.js.map +1 -1
  51. package/dist/components/slide-button/slide-button.d.ts.map +1 -1
  52. package/dist/components/slide-button/slide-button.js.map +1 -1
  53. package/dist/components/slider/slider.d.ts +2 -2
  54. package/dist/components/slider/slider.js +2 -2
  55. package/dist/components/slider/slider.js.map +1 -1
  56. package/dist/components/slider-double/slider-double.d.ts +2 -2
  57. package/dist/components/slider-double/slider-double.js +2 -2
  58. package/dist/components/slider-double/slider-double.js.map +1 -1
  59. package/dist/components/stepper-box/stepper-box.d.ts +4 -2
  60. package/dist/components/stepper-box/stepper-box.d.ts.map +1 -1
  61. package/dist/components/stepper-box/stepper-box.js +4 -2
  62. package/dist/components/stepper-box/stepper-box.js.map +1 -1
  63. package/dist/components/system-button/system-button.d.ts +1 -1
  64. package/dist/components/system-button/system-button.js +1 -1
  65. package/dist/components/system-button/system-button.js.map +1 -1
  66. package/dist/components/tabbed-card/tabbed-card.d.ts.map +1 -1
  67. package/dist/components/tabbed-card/tabbed-card.js.map +1 -1
  68. package/dist/components/toggle-button-option/toggle-button-option.d.ts +2 -1
  69. package/dist/components/toggle-button-option/toggle-button-option.d.ts.map +1 -1
  70. package/dist/components/toggle-button-option/toggle-button-option.js +2 -1
  71. package/dist/components/toggle-button-option/toggle-button-option.js.map +1 -1
  72. package/dist/components/toggle-button-vertical-group/toggle-button-vertical-group.js.map +1 -1
  73. package/dist/components/toggle-switch/toggle-switch.d.ts +1 -1
  74. package/dist/components/toggle-switch/toggle-switch.js +1 -1
  75. package/dist/components/toggle-switch/toggle-switch.js.map +1 -1
  76. package/dist/components/top-bar/top-bar.d.ts.map +1 -1
  77. package/dist/components/top-bar/top-bar.js.map +1 -1
  78. package/dist/components/topbar-message-item/topbar-message-item.js.map +1 -1
  79. package/dist/integration-systems/integration-dropdown-button/integration-dropdown-button.d.ts +1 -1
  80. package/dist/integration-systems/integration-dropdown-button/integration-dropdown-button.js +1 -1
  81. package/dist/integration-systems/integration-dropdown-button/integration-dropdown-button.js.map +1 -1
  82. package/package.json +1 -1
@@ -175,11 +175,13 @@ export declare class ObcNotificationMessageItem extends LitElement {
175
175
  private get mappedType();
176
176
  private get mappedSize();
177
177
  /**
178
- * @event message-click - Fired when the notification item is clicked (excluding the action area).
178
+ * Fired when the notification item is clicked (excluding the action area).
179
+ * @event message-click
179
180
  */
180
181
  private handleMessageClick;
181
182
  /**
182
- * @event action-click - Fired when the action button or icon is clicked.
183
+ * Fired when the action button or icon is clicked.
184
+ * @event action-click
183
185
  */
184
186
  private handleActionClick;
185
187
  render(): import('lit-html').TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"notification-message-item.d.ts","sourceRoot":"","sources":["../../../src/components/notification-message-item/notification-message-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAIzD,OAAO,+CAA+C,CAAC;AAKvD,OAAO,yCAAyC,CAAC;AACjD,OAAO,kCAAkC,CAAC;AAE1C,oBAAY,8BAA8B;IACxC,MAAM,WAAW;IACjB,UAAU,gBAAgB;IAC1B,cAAc,qBAAqB;IACnC,QAAQ,aAAa;CACtB;AAED,oBAAY,8BAA8B;IACxC,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,qBACa,0BAA2B,SAAQ,UAAU;IACxD;;;;OAIG;IACgC,KAAK,SAAM;IAE9C;;;;OAIG;IACuB,WAAW,SAAM;IAE3C;;;;OAIG;IACuB,IAAI,SAAM;IAEpC;;;;OAIG;IACuB,aAAa,SAAM;IAE7C;;;OAGG;IACuB,WAAW,SAAU;IAE/C;;;;;;OAMG;IACuB,IAAI,EAAE,8BAA8B,CACtB;IAExC;;;;OAIG;IACuB,IAAI,EAAE,8BAA8B,CACrB;IAEzC;;;OAGG;IAC0C,SAAS,EAAE,OAAO,CAAQ;IAEvE;;;;OAIG;IAC0C,eAAe,EAAE,OAAO,CAAQ;IAE7E;;;OAGG;IAC0C,aAAa,EAAE,OAAO,CAAQ;IAE3E;;;;OAIG;IACwB,aAAa,UAAS;IAEjD;;;;OAIG;IACwB,gBAAgB,UAAS;IAEpD;;;OAGG;IACwB,KAAK,UAAS;IAEzC;;;OAGG;IACwB,KAAK,UAAS;IAEzC;;;;OAIG;IACuB,SAAS,SAA4B;IAE/D,OAAO,KAAK,UAAU,GAiBrB;IAED,OAAO,KAAK,UAAU,GAQrB;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIhB,MAAM;IAyCf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,+BAA+B,EAAE,0BAA0B,CAAC;KAC7D;CACF"}
1
+ {"version":3,"file":"notification-message-item.d.ts","sourceRoot":"","sources":["../../../src/components/notification-message-item/notification-message-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAIzD,OAAO,+CAA+C,CAAC;AAKvD,OAAO,yCAAyC,CAAC;AACjD,OAAO,kCAAkC,CAAC;AAE1C,oBAAY,8BAA8B;IACxC,MAAM,WAAW;IACjB,UAAU,gBAAgB;IAC1B,cAAc,qBAAqB;IACnC,QAAQ,aAAa;CACtB;AAED,oBAAY,8BAA8B;IACxC,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,qBACa,0BAA2B,SAAQ,UAAU;IACxD;;;;OAIG;IACgC,KAAK,SAAM;IAE9C;;;;OAIG;IACuB,WAAW,SAAM;IAE3C;;;;OAIG;IACuB,IAAI,SAAM;IAEpC;;;;OAIG;IACuB,aAAa,SAAM;IAE7C;;;OAGG;IACuB,WAAW,SAAU;IAE/C;;;;;;OAMG;IACuB,IAAI,EAAE,8BAA8B,CACtB;IAExC;;;;OAIG;IACuB,IAAI,EAAE,8BAA8B,CACrB;IAEzC;;;OAGG;IAC0C,SAAS,EAAE,OAAO,CAAQ;IAEvE;;;;OAIG;IAC0C,eAAe,EAAE,OAAO,CAAQ;IAE7E;;;OAGG;IAC0C,aAAa,EAAE,OAAO,CAAQ;IAE3E;;;;OAIG;IACwB,aAAa,UAAS;IAEjD;;;;OAIG;IACwB,gBAAgB,UAAS;IAEpD;;;OAGG;IACwB,KAAK,UAAS;IAEzC;;;OAGG;IACwB,KAAK,UAAS;IAEzC;;;;OAIG;IACuB,SAAS,SAA4B;IAE/D,OAAO,KAAK,UAAU,GAiBrB;IAED,OAAO,KAAK,UAAU,GAQrB;IAED;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAIhB,MAAM;IAyCf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,+BAA+B,EAAE,0BAA0B,CAAC;KAC7D;CACF"}
@@ -68,13 +68,15 @@ let ObcNotificationMessageItem = class extends LitElement {
68
68
  return this.size === "tall" ? ObcTopbarMessageItemSize.Tall : ObcTopbarMessageItemSize.Regular;
69
69
  }
70
70
  /**
71
- * @event message-click - Fired when the notification item is clicked (excluding the action area).
71
+ * Fired when the notification item is clicked (excluding the action area).
72
+ * @event message-click
72
73
  */
73
74
  handleMessageClick() {
74
75
  this.dispatchEvent(new CustomEvent("message-click"));
75
76
  }
76
77
  /**
77
- * @event action-click - Fired when the action button or icon is clicked.
78
+ * Fired when the action button or icon is clicked.
79
+ * @event action-click
78
80
  */
79
81
  handleActionClick() {
80
82
  this.dispatchEvent(new CustomEvent("action-click"));
@@ -1 +1 @@
1
- {"version":3,"file":"notification-message-item.js","sources":["../../../src/components/notification-message-item/notification-message-item.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './notification-message-item.css?inline';\nimport '../topbar-message-item/topbar-message-item.js';\nimport {\n ObcTopbarMessageItemType,\n ObcTopbarMessageItemSize,\n} from '../topbar-message-item/topbar-message-item.js';\nimport '../../icons/icon-notification-filled.js';\nimport '../../icons/icon-close-google.js';\n\nexport enum ObcNotificationMessageItemType {\n Simple = 'simple',\n WithButton = 'with-button',\n WithIconButton = 'with-icon-button',\n Inactive = 'inactive',\n}\n\nexport enum ObcNotificationMessageItemSize {\n Regular = 'regular',\n Tall = 'tall',\n}\n\n/**\n * `<obc-notification-message-item>` – A notification message component for displaying alerts, messages, and status updates in topbars or notification panels.\n *\n * This component presents concise notification items with optional actions, timestamps, and icons. It is designed for use in notification trays, panels, or topbars, providing a consistent and scannable format for system or application messages.\n *\n * Appears as a single notification row, supporting primary and secondary icons, title, description, timestamps, and action buttons or icons. Can also display an empty/inactive state when no notifications are present.\n *\n * ## Features\n * - **Variants (type):**\n * - `simple` (default): Basic notification with icon, title, description, and timestamp.\n * - `with-button`: Includes a text action button (e.g., \"View\", \"Acknowledge\").\n * - `with-icon-button`: Shows an icon action (e.g., close or dismiss).\n * - `inactive`: Displays an empty or inactive state message (e.g., \"No active notifications\").\n * - **Size Options (size):**\n * - `regular` (default): Standard compact layout.\n * - `tall`: Expanded layout for longer content or increased prominence.\n * - **Content Controls:**\n * - Show/hide title, description, primary timestamp, secondary timestamp, and secondary icon via boolean properties.\n * - Customizable empty state text.\n * - **Icon Support:**\n * - Always displays a primary notification icon.\n * - Optional secondary icon slot for additional status or priority indicators.\n * - **Action and Interaction:**\n * - Supports both text and icon actions based on type.\n * - Emits events for message and action clicks.\n * - **Empty/Inactive State:**\n * - Can display a placeholder message when no notifications are present.\n *\n * ## Usage Guidelines\n * Use `obc-notification-message-item` to display individual notification entries in a notification panel, topbar, or similar UI area. Ideal for presenting system alerts, status updates, or actionable messages that require user attention or acknowledgment.\n *\n * - Use the `simple` type for informational messages without actions.\n * - Use `with-button` when the notification requires a text button action (e.g., \"View\", \"Dismiss\").\n * - Use `with-icon-button` when the notification requires an icon button action (e.g., close).\n * - Use the `inactive` type (or set `empty` to true) to indicate that there are no active notifications.\n * - Prefer concise titles and descriptions for readability. Truncation is handled automatically for long content.\n * - For persistent or multi-line notifications, consider using the `tall` size.\n * - Only use one primary action per notification to avoid overwhelming the user.\n *\n * ## Slots\n * | Slot Name | Renders When... | Purpose |\n * |-------------------|----------------------------------------|--------------------------------------------------------------|\n * | `secondary-icon` | `hasSecondaryIcon` is true | Additional icon for status/priority (e.g., warning, info). |\n *\n * ## Events\n * - `message-click` – Fired when the notification item is clicked (excluding action area).\n * - `action-click` – Fired when the action button or icon is clicked.\n *\n * ## Best Practices and Constraints\n * - Only one action (button or icon) should be used per notification based on the type.\n * - Use the `inactive` type (or `empty=true`) for empty states; avoid mixing both.\n * - The `large` and `empty` properties are deprecated; use `size=\"tall\"` and `type=\"inactive\"` instead.\n * - For accessibility, ensure action labels are descriptive and icons have appropriate context.\n *\n * ## Example\n * ```html\n * <obc-notification-message-item\n * type=\"with-button\"\n * title=\"System Update\"\n * description=\"Your system has been updated successfully\"\n * time=\"10:30:15\"\n * actionLabel=\"View\"\n * >\n * <obi-warning-icon slot=\"secondary-icon\"></obi-warning-icon>\n * </obc-notification-message-item>\n * ```\n *\n * @slot secondary-icon - Additional icon for status/priority (shown when `hasSecondaryIcon` is true).\n * @fires {CustomEvent<void>} message-click - Fired when the notification item is clicked.\n * @fires {CustomEvent<void>} action-click - Fired when the action button or icon is clicked.\n * @beta\n */\n@customElement('obc-notification-message-item')\nexport class ObcNotificationMessageItem extends LitElement {\n /**\n * Title or heading for the notification.\n * Shown in the title slot if `hasTitle` is true.\n * @availableWhen showTitle==true && type!=Inactive && empty==false\n */\n @property({type: String}) override title = '';\n\n /**\n * Detailed message text for the notification.\n * Shown in the description slot if `hasDescription` is true.\n * @availableWhen showDescription==true && type!=Inactive && empty==false\n */\n @property({type: String}) description = '';\n\n /**\n * Primary timestamp to display (e.g., \"09:12:46\").\n * Shown in the time slot if `hasTimestamp` is true.\n * @availableWhen showTimestamp==true && type!=Inactive && empty==false\n */\n @property({type: String}) time = '';\n\n /**\n * Secondary timestamp (e.g., relative time like \"2m ago\").\n * Shown in the time-secondary slot if `hasTimestamp2` is true.\n * @availableWhen hasTimestamp2==true && type!=Inactive && empty==false\n */\n @property({type: String}) timeSecondary = '';\n\n /**\n * Label for the action button (used when `actionType` is \"button\").\n * @availableWhen type==WithButton\n */\n @property({type: String}) actionLabel = 'View';\n\n /**\n * Display type of the notification.\n * - `simple`: Basic notification (default).\n * - `with-button`: Includes a text action button.\n * - `with-icon-button`: Includes an icon action.\n * - `inactive`: Shows empty/inactive state.\n */\n @property({type: String}) type: ObcNotificationMessageItemType =\n ObcNotificationMessageItemType.Simple;\n\n /**\n * Size variant of the notification.\n * - `regular`: Standard compact layout (default).\n * - `tall`: Expanded layout for longer content.\n */\n @property({type: String}) size: ObcNotificationMessageItemSize =\n ObcNotificationMessageItemSize.Regular;\n\n /**\n * Whether to show the title.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean, attribute: false}) showTitle: boolean = true;\n\n /**\n * Whether to show the description.\n * If false, the description slot is omitted.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean, attribute: false}) showDescription: boolean = true;\n\n /**\n * Whether to show the primary timestamp.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean, attribute: false}) showTimestamp: boolean = true;\n\n /**\n * Whether to show the secondary timestamp.\n * If false, the time-secondary slot is omitted.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean}) hasTimestamp2 = false;\n\n /**\n * Whether to show the secondary icon overlay.\n * If true, renders the `secondary-icon` slot.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean}) hasSecondaryIcon = false;\n\n /**\n * **DEPRECATED** – Use `size=\"tall\"` instead.\n * If true, uses the tall layout.\n */\n @property({type: Boolean}) large = false;\n\n /**\n * **DEPRECATED** – Use `type=\"inactive\"` instead.\n * If true, shows the empty/inactive state.\n */\n @property({type: Boolean}) empty = false;\n\n /**\n * Text to show in the empty/inactive state.\n * Used in the `empty` slot when `type=\"inactive\"` or `empty` is true.\n * @availableWhen type==Inactive || empty==true\n */\n @property({type: String}) emptyText = 'No active notification';\n\n private get mappedType(): ObcTopbarMessageItemType {\n // Handle empty/inactive state\n if (this.empty || this.type === ObcNotificationMessageItemType.Inactive) {\n return ObcTopbarMessageItemType.Inactive;\n }\n\n // Use the specified type\n switch (this.type) {\n case ObcNotificationMessageItemType.WithButton:\n return ObcTopbarMessageItemType.WithButton;\n case ObcNotificationMessageItemType.WithIconButton:\n return ObcTopbarMessageItemType.WithIconButton;\n case ObcNotificationMessageItemType.Simple:\n return ObcTopbarMessageItemType.Simple;\n default:\n return ObcTopbarMessageItemType.Simple;\n }\n }\n\n private get mappedSize(): ObcTopbarMessageItemSize {\n // Handle deprecated 'large' property\n if (this.large) {\n return ObcTopbarMessageItemSize.Tall;\n }\n return this.size === ObcNotificationMessageItemSize.Tall\n ? ObcTopbarMessageItemSize.Tall\n : ObcTopbarMessageItemSize.Regular;\n }\n\n /**\n * @event message-click - Fired when the notification item is clicked (excluding the action area).\n */\n private handleMessageClick() {\n this.dispatchEvent(new CustomEvent('message-click'));\n }\n\n /**\n * @event action-click - Fired when the action button or icon is clicked.\n */\n private handleActionClick() {\n this.dispatchEvent(new CustomEvent('action-click'));\n }\n\n override render() {\n return html`\n <obc-topbar-message-item\n .type=${this.mappedType}\n .size=${this.mappedSize}\n .showTitle=${this.showTitle}\n .showDescription=${this.showDescription}\n .showTimestamp=${this.showTimestamp}\n .hasTimestamp2=${this.hasTimestamp2}\n .hasSecondaryIcon=${this.hasSecondaryIcon}\n @message-click=${this.handleMessageClick}\n @action-click=${this.handleActionClick}\n >\n <obi-notification-filled slot=\"primary-icon\"></obi-notification-filled>\n\n ${this.hasSecondaryIcon\n ? html`<slot name=\"secondary-icon\" slot=\"secondary-icon\"></slot>`\n : nothing}\n ${this.title && this.showTitle\n ? html`<span slot=\"title\">${this.title}</span>`\n : nothing}\n ${this.description && this.showDescription\n ? html`<span slot=\"description\">${this.description}</span>`\n : nothing}\n ${this.time && this.showTimestamp\n ? html`<span slot=\"time\">${this.time}</span>`\n : nothing}\n ${this.timeSecondary && this.hasTimestamp2\n ? html`<span slot=\"time-secondary\">${this.timeSecondary}</span>`\n : nothing}\n ${this.type === ObcNotificationMessageItemType.WithButton\n ? html`<span slot=\"action-text\">${this.actionLabel}</span>`\n : this.type === ObcNotificationMessageItemType.WithIconButton\n ? html`<obi-close-google slot=\"action-icon\"></obi-close-google>`\n : nothing}\n\n <span slot=\"empty\">${this.emptyText}</span>\n </obc-topbar-message-item>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-notification-message-item': ObcNotificationMessageItem;\n }\n}\n"],"names":["ObcNotificationMessageItemType","ObcNotificationMessageItemSize"],"mappings":"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"}
1
+ {"version":3,"file":"notification-message-item.js","sources":["../../../src/components/notification-message-item/notification-message-item.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './notification-message-item.css?inline';\nimport '../topbar-message-item/topbar-message-item.js';\nimport {\n ObcTopbarMessageItemType,\n ObcTopbarMessageItemSize,\n} from '../topbar-message-item/topbar-message-item.js';\nimport '../../icons/icon-notification-filled.js';\nimport '../../icons/icon-close-google.js';\n\nexport enum ObcNotificationMessageItemType {\n Simple = 'simple',\n WithButton = 'with-button',\n WithIconButton = 'with-icon-button',\n Inactive = 'inactive',\n}\n\nexport enum ObcNotificationMessageItemSize {\n Regular = 'regular',\n Tall = 'tall',\n}\n\n/**\n * `<obc-notification-message-item>` – A notification message component for displaying alerts, messages, and status updates in topbars or notification panels.\n *\n * This component presents concise notification items with optional actions, timestamps, and icons. It is designed for use in notification trays, panels, or topbars, providing a consistent and scannable format for system or application messages.\n *\n * Appears as a single notification row, supporting primary and secondary icons, title, description, timestamps, and action buttons or icons. Can also display an empty/inactive state when no notifications are present.\n *\n * ## Features\n * - **Variants (type):**\n * - `simple` (default): Basic notification with icon, title, description, and timestamp.\n * - `with-button`: Includes a text action button (e.g., \"View\", \"Acknowledge\").\n * - `with-icon-button`: Shows an icon action (e.g., close or dismiss).\n * - `inactive`: Displays an empty or inactive state message (e.g., \"No active notifications\").\n * - **Size Options (size):**\n * - `regular` (default): Standard compact layout.\n * - `tall`: Expanded layout for longer content or increased prominence.\n * - **Content Controls:**\n * - Show/hide title, description, primary timestamp, secondary timestamp, and secondary icon via boolean properties.\n * - Customizable empty state text.\n * - **Icon Support:**\n * - Always displays a primary notification icon.\n * - Optional secondary icon slot for additional status or priority indicators.\n * - **Action and Interaction:**\n * - Supports both text and icon actions based on type.\n * - Emits events for message and action clicks.\n * - **Empty/Inactive State:**\n * - Can display a placeholder message when no notifications are present.\n *\n * ## Usage Guidelines\n * Use `obc-notification-message-item` to display individual notification entries in a notification panel, topbar, or similar UI area. Ideal for presenting system alerts, status updates, or actionable messages that require user attention or acknowledgment.\n *\n * - Use the `simple` type for informational messages without actions.\n * - Use `with-button` when the notification requires a text button action (e.g., \"View\", \"Dismiss\").\n * - Use `with-icon-button` when the notification requires an icon button action (e.g., close).\n * - Use the `inactive` type (or set `empty` to true) to indicate that there are no active notifications.\n * - Prefer concise titles and descriptions for readability. Truncation is handled automatically for long content.\n * - For persistent or multi-line notifications, consider using the `tall` size.\n * - Only use one primary action per notification to avoid overwhelming the user.\n *\n * ## Slots\n * | Slot Name | Renders When... | Purpose |\n * |-------------------|----------------------------------------|--------------------------------------------------------------|\n * | `secondary-icon` | `hasSecondaryIcon` is true | Additional icon for status/priority (e.g., warning, info). |\n *\n * ## Events\n * - `message-click` – Fired when the notification item is clicked (excluding action area).\n * - `action-click` – Fired when the action button or icon is clicked.\n *\n * ## Best Practices and Constraints\n * - Only one action (button or icon) should be used per notification based on the type.\n * - Use the `inactive` type (or `empty=true`) for empty states; avoid mixing both.\n * - The `large` and `empty` properties are deprecated; use `size=\"tall\"` and `type=\"inactive\"` instead.\n * - For accessibility, ensure action labels are descriptive and icons have appropriate context.\n *\n * ## Example\n * ```html\n * <obc-notification-message-item\n * type=\"with-button\"\n * title=\"System Update\"\n * description=\"Your system has been updated successfully\"\n * time=\"10:30:15\"\n * actionLabel=\"View\"\n * >\n * <obi-warning-icon slot=\"secondary-icon\"></obi-warning-icon>\n * </obc-notification-message-item>\n * ```\n *\n * @slot secondary-icon - Additional icon for status/priority (shown when `hasSecondaryIcon` is true).\n * @fires {CustomEvent<void>} message-click - Fired when the notification item is clicked.\n * @fires {CustomEvent<void>} action-click - Fired when the action button or icon is clicked.\n * @beta\n */\n@customElement('obc-notification-message-item')\nexport class ObcNotificationMessageItem extends LitElement {\n /**\n * Title or heading for the notification.\n * Shown in the title slot if `hasTitle` is true.\n * @availableWhen showTitle==true && type!=Inactive && empty==false\n */\n @property({type: String}) override title = '';\n\n /**\n * Detailed message text for the notification.\n * Shown in the description slot if `hasDescription` is true.\n * @availableWhen showDescription==true && type!=Inactive && empty==false\n */\n @property({type: String}) description = '';\n\n /**\n * Primary timestamp to display (e.g., \"09:12:46\").\n * Shown in the time slot if `hasTimestamp` is true.\n * @availableWhen showTimestamp==true && type!=Inactive && empty==false\n */\n @property({type: String}) time = '';\n\n /**\n * Secondary timestamp (e.g., relative time like \"2m ago\").\n * Shown in the time-secondary slot if `hasTimestamp2` is true.\n * @availableWhen hasTimestamp2==true && type!=Inactive && empty==false\n */\n @property({type: String}) timeSecondary = '';\n\n /**\n * Label for the action button (used when `actionType` is \"button\").\n * @availableWhen type==WithButton\n */\n @property({type: String}) actionLabel = 'View';\n\n /**\n * Display type of the notification.\n * - `simple`: Basic notification (default).\n * - `with-button`: Includes a text action button.\n * - `with-icon-button`: Includes an icon action.\n * - `inactive`: Shows empty/inactive state.\n */\n @property({type: String}) type: ObcNotificationMessageItemType =\n ObcNotificationMessageItemType.Simple;\n\n /**\n * Size variant of the notification.\n * - `regular`: Standard compact layout (default).\n * - `tall`: Expanded layout for longer content.\n */\n @property({type: String}) size: ObcNotificationMessageItemSize =\n ObcNotificationMessageItemSize.Regular;\n\n /**\n * Whether to show the title.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean, attribute: false}) showTitle: boolean = true;\n\n /**\n * Whether to show the description.\n * If false, the description slot is omitted.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean, attribute: false}) showDescription: boolean = true;\n\n /**\n * Whether to show the primary timestamp.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean, attribute: false}) showTimestamp: boolean = true;\n\n /**\n * Whether to show the secondary timestamp.\n * If false, the time-secondary slot is omitted.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean}) hasTimestamp2 = false;\n\n /**\n * Whether to show the secondary icon overlay.\n * If true, renders the `secondary-icon` slot.\n * @availableWhen type!=Inactive && empty==false\n */\n @property({type: Boolean}) hasSecondaryIcon = false;\n\n /**\n * **DEPRECATED** – Use `size=\"tall\"` instead.\n * If true, uses the tall layout.\n */\n @property({type: Boolean}) large = false;\n\n /**\n * **DEPRECATED** – Use `type=\"inactive\"` instead.\n * If true, shows the empty/inactive state.\n */\n @property({type: Boolean}) empty = false;\n\n /**\n * Text to show in the empty/inactive state.\n * Used in the `empty` slot when `type=\"inactive\"` or `empty` is true.\n * @availableWhen type==Inactive || empty==true\n */\n @property({type: String}) emptyText = 'No active notification';\n\n private get mappedType(): ObcTopbarMessageItemType {\n // Handle empty/inactive state\n if (this.empty || this.type === ObcNotificationMessageItemType.Inactive) {\n return ObcTopbarMessageItemType.Inactive;\n }\n\n // Use the specified type\n switch (this.type) {\n case ObcNotificationMessageItemType.WithButton:\n return ObcTopbarMessageItemType.WithButton;\n case ObcNotificationMessageItemType.WithIconButton:\n return ObcTopbarMessageItemType.WithIconButton;\n case ObcNotificationMessageItemType.Simple:\n return ObcTopbarMessageItemType.Simple;\n default:\n return ObcTopbarMessageItemType.Simple;\n }\n }\n\n private get mappedSize(): ObcTopbarMessageItemSize {\n // Handle deprecated 'large' property\n if (this.large) {\n return ObcTopbarMessageItemSize.Tall;\n }\n return this.size === ObcNotificationMessageItemSize.Tall\n ? ObcTopbarMessageItemSize.Tall\n : ObcTopbarMessageItemSize.Regular;\n }\n\n /**\n * Fired when the notification item is clicked (excluding the action area).\n * @event message-click\n */\n private handleMessageClick() {\n this.dispatchEvent(new CustomEvent('message-click'));\n }\n\n /**\n * Fired when the action button or icon is clicked.\n * @event action-click\n */\n private handleActionClick() {\n this.dispatchEvent(new CustomEvent('action-click'));\n }\n\n override render() {\n return html`\n <obc-topbar-message-item\n .type=${this.mappedType}\n .size=${this.mappedSize}\n .showTitle=${this.showTitle}\n .showDescription=${this.showDescription}\n .showTimestamp=${this.showTimestamp}\n .hasTimestamp2=${this.hasTimestamp2}\n .hasSecondaryIcon=${this.hasSecondaryIcon}\n @message-click=${this.handleMessageClick}\n @action-click=${this.handleActionClick}\n >\n <obi-notification-filled slot=\"primary-icon\"></obi-notification-filled>\n\n ${this.hasSecondaryIcon\n ? html`<slot name=\"secondary-icon\" slot=\"secondary-icon\"></slot>`\n : nothing}\n ${this.title && this.showTitle\n ? html`<span slot=\"title\">${this.title}</span>`\n : nothing}\n ${this.description && this.showDescription\n ? html`<span slot=\"description\">${this.description}</span>`\n : nothing}\n ${this.time && this.showTimestamp\n ? html`<span slot=\"time\">${this.time}</span>`\n : nothing}\n ${this.timeSecondary && this.hasTimestamp2\n ? html`<span slot=\"time-secondary\">${this.timeSecondary}</span>`\n : nothing}\n ${this.type === ObcNotificationMessageItemType.WithButton\n ? html`<span slot=\"action-text\">${this.actionLabel}</span>`\n : this.type === ObcNotificationMessageItemType.WithIconButton\n ? html`<obi-close-google slot=\"action-icon\"></obi-close-google>`\n : nothing}\n\n <span slot=\"empty\">${this.emptyText}</span>\n </obc-topbar-message-item>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-notification-message-item': ObcNotificationMessageItem;\n }\n}\n"],"names":["ObcNotificationMessageItemType","ObcNotificationMessageItemSize"],"mappings":"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"}
@@ -106,7 +106,7 @@ export declare class ObcPivotItem extends LitElement {
106
106
  /**
107
107
  * Handles click events. Emits `selected` when the item is not disabled or already selected.
108
108
  *
109
- * @fires {CustomEvent<{value: string}>} selected - When the item is clicked and becomes selected
109
+ * @fires selected
110
110
  */
111
111
  private onClick;
112
112
  render(): import('lit-html').TemplateResult<1>;
@@ -32,7 +32,7 @@ let ObcPivotItem = class extends LitElement {
32
32
  /**
33
33
  * Handles click events. Emits `selected` when the item is not disabled or already selected.
34
34
  *
35
- * @fires {CustomEvent<{value: string}>} selected - When the item is clicked and becomes selected
35
+ * @fires selected
36
36
  */
37
37
  onClick() {
38
38
  if (this.disabled || this.selected) {
@@ -1 +1 @@
1
- {"version":3,"file":"pivot-item.js","sources":["../../../src/components/pivot-item/pivot-item.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {customElement} from '../../decorator.js';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport compentStyle from './pivot-item.css?inline';\n\n/**\n * The layout direction for a pivot item.\n * - `horizontal`: Arranges items in a row (default).\n * - `vertical`: Arranges items in a column.\n */\nexport enum ObcPivotItemDirection {\n horizontal = 'horizontal',\n vertical = 'vertical',\n}\n\n/**\n * `<obc-pivot-item>` – A selectable tab or navigation item for use in pivot/tab bars and segmented controls.\n *\n * Represents a single option within a group of pivot items, supporting icon-only, label-only, or combined icon+label layouts. Designed for navigation or view switching scenarios where users select one option from a set. Can be arranged horizontally or vertically to fit different UI layouts.\n *\n * ---\n *\n * ### Features\n * - **Direction:** Supports `horizontal` (default) or `vertical` layout, adapting to the orientation of the containing group.\n * - **Icon and Label Options:** Can display a leading icon (via the `icon` slot), a text label (via the `label` property), or both. Each can be toggled independently.\n * - **Selection State:** Indicates the currently selected item with a visual highlight (active tab stroke). Only one item should be selected in a group at a time.\n * - **Disabled State:** Can be disabled to prevent interaction and visually indicate inactivity.\n *\n * ---\n *\n * ### Usage Guidelines\n * Use `obc-pivot-item` within an `obc-pivot-item-group` to create tab bars, segmented controls, or navigation rails. Ideal for switching between views, pages, or content sections. Choose horizontal orientation for top navigation bars and vertical for side navigation or tool selectors. Use icons for compact layouts or when representing actions visually; combine with labels for clarity. Avoid using for persistent navigation (use a menu or list instead).\n *\n * **TODO(designer):** Confirm if there are recommended limits on icon or label length, and if divider usage is preferred in certain layouts.\n *\n * ---\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |-----------|------------------------|-------------------------------------------|\n * | icon | `hasLeadingIcon` true | Leading icon representing the item. Place an icon such as `<obi-home slot=\"icon\"></obi-home>`. |\n *\n * ---\n *\n * ### Events\n * - `selected` – Fired when the item is clicked and becomes selected. Event detail: `{ value: string }`.\n *\n * ---\n *\n * ### Example:\n * ```\n * <obc-pivot-item\n * value=\"home\"\n * label=\"Home\"\n * hasLeadingIcon\n * hasLabel\n * >\n * <obi-home slot=\"icon\"></obi-home>\n * </obc-pivot-item>\n * ```\n * In this example, the item displays a home icon and a label. When clicked (and not already selected/disabled), it emits a `selected` event.\n *\n * @slot icon - Leading icon slot (shown when `hasLeadingIcon` is true)\n * @fires {CustomEvent<{value: string}>} selected - When the item is clicked and becomes selected\n * @stable\n */\n@customElement('obc-pivot-item')\nexport class ObcPivotItem extends LitElement {\n /**\n * The value associated with this pivot item. Used to identify the item within a group.\n *\n * Set a unique value for each item in a group to track selection state.\n */\n @property({type: String}) value = '';\n\n /**\n * Whether this item is currently selected. Only one item should be selected in a group.\n *\n * When `true`, the item is visually highlighted and does not emit the `selected` event on click.\n */\n @property({type: Boolean, reflect: true}) selected = false;\n\n /**\n * Layout direction for the item: `horizontal` (default) or `vertical`.\n * Should match the direction of the containing group.\n *\n * Use `horizontal` for row/tab layouts and `vertical` for column/rail layouts.\n */\n @property({type: String}) direction: ObcPivotItemDirection =\n ObcPivotItemDirection.horizontal;\n\n /**\n * Whether to display a leading icon. If true, renders the `icon` slot.\n *\n * Place an icon element (e.g., `<obi-home slot=\"icon\"></obi-home>`) in the slot to show an icon.\n */\n @property({type: Boolean}) hasLeadingIcon = false;\n\n /**\n * Whether to display a text label. If true and `label` is non-empty, shows the label.\n *\n * Use in combination with `hasLeadingIcon` for icon+label layouts.\n */\n @property({type: Boolean}) hasLabel = false;\n\n /**\n * The text label to display for the item. Only shown if `hasLabel` is true and label is non-empty.\n *\n * Keep labels concise for best appearance, especially in horizontal layouts.\n */\n @property({type: String}) label = '';\n\n /**\n * Disables the item, preventing interaction and applying a disabled style.\n *\n * When `true`, the item cannot be selected and is visually muted.\n */\n @property({type: Boolean}) disabled = false;\n\n /**\n * Handles click events. Emits `selected` when the item is not disabled or already selected.\n *\n * @fires {CustomEvent<{value: string}>} selected - When the item is clicked and becomes selected\n */\n private onClick() {\n // Don't allow clicking if disabled OR already selected\n if (this.disabled || this.selected) {\n return;\n }\n\n this.dispatchEvent(\n new CustomEvent('selected', {\n detail: {value: this.value},\n bubbles: true,\n composed: true,\n })\n );\n }\n\n override render() {\n const isVertical = this.direction === ObcPivotItemDirection.vertical;\n const shouldShowLabel = this.hasLabel && this.label.trim().length > 0;\n\n const classes = classMap({\n wrapper: true,\n selected: this.selected,\n 'direction-vertical': isVertical,\n 'direction-horizontal': !isVertical,\n 'has-leading-icon': this.hasLeadingIcon,\n 'has-label': this.hasLabel,\n disabled: this.disabled,\n });\n\n return html`\n <button\n class=${classes}\n @click=${this.onClick}\n ?disabled=${this.disabled}\n aria-pressed=${this.selected}\n >\n <div class=\"visible-wrapper\">\n <div class=\"placeholder\">\n <div class=\"icon-label-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"icon\">\n <slot name=\"icon\"></slot>\n </div>`\n : nothing}\n ${shouldShowLabel\n ? html`<div class=\"label\">${this.label}</div>`\n : nothing}\n </div>\n </div>\n </div>\n\n <div class=\"selected-container\">\n <div class=\"active-tab-stroke\"></div>\n </div>\n </button>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-pivot-item': ObcPivotItem;\n }\n}\n"],"names":["ObcPivotItemDirection"],"mappings":";;;;;;;;;;;;;;;AAWO,IAAK,0CAAAA,2BAAL;AACLA,yBAAA,YAAA,IAAa;AACbA,yBAAA,UAAA,IAAW;AAFD,SAAAA;AAAA,GAAA,yBAAA,CAAA,CAAA;AAyDL,IAAM,eAAN,cAA2B,WAAW;AAAA,EAAtC,cAAA;AAAA,UAAA,GAAA,SAAA;AAMqB,SAAA,QAAQ;AAOQ,SAAA,WAAW;AAQ3B,SAAA,YACxB;AAOyB,SAAA,iBAAiB;AAOjB,SAAA,WAAW;AAOZ,SAAA,QAAQ;AAOP,SAAA,WAAW;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO9B,UAAU;AAEhB,QAAI,KAAK,YAAY,KAAK,UAAU;AAClC;AAAA,IACF;AAEA,SAAK;AAAA,MACH,IAAI,YAAY,YAAY;AAAA,QAC1B,QAAQ,EAAC,OAAO,KAAK,MAAA;AAAA,QACrB,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAEL;AAAA,EAES,SAAS;AAChB,UAAM,aAAa,KAAK,cAAc;AACtC,UAAM,kBAAkB,KAAK,YAAY,KAAK,MAAM,KAAA,EAAO,SAAS;AAEpE,UAAM,UAAU,SAAS;AAAA,MACvB,SAAS;AAAA,MACT,UAAU,KAAK;AAAA,MACf,sBAAsB;AAAA,MACtB,wBAAwB,CAAC;AAAA,MACzB,oBAAoB,KAAK;AAAA,MACzB,aAAa,KAAK;AAAA,MAClB,UAAU,KAAK;AAAA,IAAA,CAChB;AAED,WAAO;AAAA;AAAA,gBAEK,OAAO;AAAA,iBACN,KAAK,OAAO;AAAA,oBACT,KAAK,QAAQ;AAAA,uBACV,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKpB,KAAK,iBACH;AAAA;AAAA,4BAGA,OAAO;AAAA,gBACT,kBACE,0BAA0B,KAAK,KAAK,WACpC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUvB;AAGF;AApHa,aAmHK,SAAS,UAAU,YAAY;AA7GrB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GANb,aAMe,WAAA,SAAA,CAAA;AAOgB,gBAAA;AAAA,EAAzC,SAAS,EAAC,MAAM,SAAS,SAAS,MAAK;AAAA,GAb7B,aAa+B,WAAA,YAAA,CAAA;AAQhB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GArBb,aAqBe,WAAA,aAAA,CAAA;AAQC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA7Bd,aA6BgB,WAAA,kBAAA,CAAA;AAOA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GApCd,aAoCgB,WAAA,YAAA,CAAA;AAOD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA3Cb,aA2Ce,WAAA,SAAA,CAAA;AAOC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAlDd,aAkDgB,WAAA,YAAA,CAAA;AAlDhB,eAAN,gBAAA;AAAA,EADN,cAAc,gBAAgB;AAAA,GAClB,YAAA;"}
1
+ {"version":3,"file":"pivot-item.js","sources":["../../../src/components/pivot-item/pivot-item.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {customElement} from '../../decorator.js';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport compentStyle from './pivot-item.css?inline';\n\n/**\n * The layout direction for a pivot item.\n * - `horizontal`: Arranges items in a row (default).\n * - `vertical`: Arranges items in a column.\n */\nexport enum ObcPivotItemDirection {\n horizontal = 'horizontal',\n vertical = 'vertical',\n}\n\n/**\n * `<obc-pivot-item>` – A selectable tab or navigation item for use in pivot/tab bars and segmented controls.\n *\n * Represents a single option within a group of pivot items, supporting icon-only, label-only, or combined icon+label layouts. Designed for navigation or view switching scenarios where users select one option from a set. Can be arranged horizontally or vertically to fit different UI layouts.\n *\n * ---\n *\n * ### Features\n * - **Direction:** Supports `horizontal` (default) or `vertical` layout, adapting to the orientation of the containing group.\n * - **Icon and Label Options:** Can display a leading icon (via the `icon` slot), a text label (via the `label` property), or both. Each can be toggled independently.\n * - **Selection State:** Indicates the currently selected item with a visual highlight (active tab stroke). Only one item should be selected in a group at a time.\n * - **Disabled State:** Can be disabled to prevent interaction and visually indicate inactivity.\n *\n * ---\n *\n * ### Usage Guidelines\n * Use `obc-pivot-item` within an `obc-pivot-item-group` to create tab bars, segmented controls, or navigation rails. Ideal for switching between views, pages, or content sections. Choose horizontal orientation for top navigation bars and vertical for side navigation or tool selectors. Use icons for compact layouts or when representing actions visually; combine with labels for clarity. Avoid using for persistent navigation (use a menu or list instead).\n *\n * **TODO(designer):** Confirm if there are recommended limits on icon or label length, and if divider usage is preferred in certain layouts.\n *\n * ---\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |-----------|------------------------|-------------------------------------------|\n * | icon | `hasLeadingIcon` true | Leading icon representing the item. Place an icon such as `<obi-home slot=\"icon\"></obi-home>`. |\n *\n * ---\n *\n * ### Events\n * - `selected` – Fired when the item is clicked and becomes selected. Event detail: `{ value: string }`.\n *\n * ---\n *\n * ### Example:\n * ```\n * <obc-pivot-item\n * value=\"home\"\n * label=\"Home\"\n * hasLeadingIcon\n * hasLabel\n * >\n * <obi-home slot=\"icon\"></obi-home>\n * </obc-pivot-item>\n * ```\n * In this example, the item displays a home icon and a label. When clicked (and not already selected/disabled), it emits a `selected` event.\n *\n * @slot icon - Leading icon slot (shown when `hasLeadingIcon` is true)\n * @fires {CustomEvent<{value: string}>} selected - When the item is clicked and becomes selected\n * @stable\n */\n@customElement('obc-pivot-item')\nexport class ObcPivotItem extends LitElement {\n /**\n * The value associated with this pivot item. Used to identify the item within a group.\n *\n * Set a unique value for each item in a group to track selection state.\n */\n @property({type: String}) value = '';\n\n /**\n * Whether this item is currently selected. Only one item should be selected in a group.\n *\n * When `true`, the item is visually highlighted and does not emit the `selected` event on click.\n */\n @property({type: Boolean, reflect: true}) selected = false;\n\n /**\n * Layout direction for the item: `horizontal` (default) or `vertical`.\n * Should match the direction of the containing group.\n *\n * Use `horizontal` for row/tab layouts and `vertical` for column/rail layouts.\n */\n @property({type: String}) direction: ObcPivotItemDirection =\n ObcPivotItemDirection.horizontal;\n\n /**\n * Whether to display a leading icon. If true, renders the `icon` slot.\n *\n * Place an icon element (e.g., `<obi-home slot=\"icon\"></obi-home>`) in the slot to show an icon.\n */\n @property({type: Boolean}) hasLeadingIcon = false;\n\n /**\n * Whether to display a text label. If true and `label` is non-empty, shows the label.\n *\n * Use in combination with `hasLeadingIcon` for icon+label layouts.\n */\n @property({type: Boolean}) hasLabel = false;\n\n /**\n * The text label to display for the item. Only shown if `hasLabel` is true and label is non-empty.\n *\n * Keep labels concise for best appearance, especially in horizontal layouts.\n */\n @property({type: String}) label = '';\n\n /**\n * Disables the item, preventing interaction and applying a disabled style.\n *\n * When `true`, the item cannot be selected and is visually muted.\n */\n @property({type: Boolean}) disabled = false;\n\n /**\n * Handles click events. Emits `selected` when the item is not disabled or already selected.\n *\n * @fires selected\n */\n private onClick() {\n // Don't allow clicking if disabled OR already selected\n if (this.disabled || this.selected) {\n return;\n }\n\n this.dispatchEvent(\n new CustomEvent('selected', {\n detail: {value: this.value},\n bubbles: true,\n composed: true,\n })\n );\n }\n\n override render() {\n const isVertical = this.direction === ObcPivotItemDirection.vertical;\n const shouldShowLabel = this.hasLabel && this.label.trim().length > 0;\n\n const classes = classMap({\n wrapper: true,\n selected: this.selected,\n 'direction-vertical': isVertical,\n 'direction-horizontal': !isVertical,\n 'has-leading-icon': this.hasLeadingIcon,\n 'has-label': this.hasLabel,\n disabled: this.disabled,\n });\n\n return html`\n <button\n class=${classes}\n @click=${this.onClick}\n ?disabled=${this.disabled}\n aria-pressed=${this.selected}\n >\n <div class=\"visible-wrapper\">\n <div class=\"placeholder\">\n <div class=\"icon-label-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"icon\">\n <slot name=\"icon\"></slot>\n </div>`\n : nothing}\n ${shouldShowLabel\n ? html`<div class=\"label\">${this.label}</div>`\n : nothing}\n </div>\n </div>\n </div>\n\n <div class=\"selected-container\">\n <div class=\"active-tab-stroke\"></div>\n </div>\n </button>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-pivot-item': ObcPivotItem;\n }\n}\n"],"names":["ObcPivotItemDirection"],"mappings":";;;;;;;;;;;;;;;AAWO,IAAK,0CAAAA,2BAAL;AACLA,yBAAA,YAAA,IAAa;AACbA,yBAAA,UAAA,IAAW;AAFD,SAAAA;AAAA,GAAA,yBAAA,CAAA,CAAA;AAyDL,IAAM,eAAN,cAA2B,WAAW;AAAA,EAAtC,cAAA;AAAA,UAAA,GAAA,SAAA;AAMqB,SAAA,QAAQ;AAOQ,SAAA,WAAW;AAQ3B,SAAA,YACxB;AAOyB,SAAA,iBAAiB;AAOjB,SAAA,WAAW;AAOZ,SAAA,QAAQ;AAOP,SAAA,WAAW;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO9B,UAAU;AAEhB,QAAI,KAAK,YAAY,KAAK,UAAU;AAClC;AAAA,IACF;AAEA,SAAK;AAAA,MACH,IAAI,YAAY,YAAY;AAAA,QAC1B,QAAQ,EAAC,OAAO,KAAK,MAAA;AAAA,QACrB,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAEL;AAAA,EAES,SAAS;AAChB,UAAM,aAAa,KAAK,cAAc;AACtC,UAAM,kBAAkB,KAAK,YAAY,KAAK,MAAM,KAAA,EAAO,SAAS;AAEpE,UAAM,UAAU,SAAS;AAAA,MACvB,SAAS;AAAA,MACT,UAAU,KAAK;AAAA,MACf,sBAAsB;AAAA,MACtB,wBAAwB,CAAC;AAAA,MACzB,oBAAoB,KAAK;AAAA,MACzB,aAAa,KAAK;AAAA,MAClB,UAAU,KAAK;AAAA,IAAA,CAChB;AAED,WAAO;AAAA;AAAA,gBAEK,OAAO;AAAA,iBACN,KAAK,OAAO;AAAA,oBACT,KAAK,QAAQ;AAAA,uBACV,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKpB,KAAK,iBACH;AAAA;AAAA,4BAGA,OAAO;AAAA,gBACT,kBACE,0BAA0B,KAAK,KAAK,WACpC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUvB;AAGF;AApHa,aAmHK,SAAS,UAAU,YAAY;AA7GrB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GANb,aAMe,WAAA,SAAA,CAAA;AAOgB,gBAAA;AAAA,EAAzC,SAAS,EAAC,MAAM,SAAS,SAAS,MAAK;AAAA,GAb7B,aAa+B,WAAA,YAAA,CAAA;AAQhB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GArBb,aAqBe,WAAA,aAAA,CAAA;AAQC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA7Bd,aA6BgB,WAAA,kBAAA,CAAA;AAOA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GApCd,aAoCgB,WAAA,YAAA,CAAA;AAOD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA3Cb,aA2Ce,WAAA,SAAA,CAAA;AAOC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAlDd,aAkDgB,WAAA,YAAA,CAAA;AAlDhB,eAAN,gBAAA;AAAA,EADN,cAAc,gBAAgB;AAAA,GAClB,YAAA;"}
@@ -1 +1 @@
1
- {"version":3,"file":"slide-button.d.ts","sourceRoot":"","sources":["../../../src/components/slide-button/slide-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,iDAAiD,CAAC;AAGzD,MAAM,MAAM,wBAAwB,GAAG,WAAW,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAC,CAAC,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,qBACa,cAAe,SAAQ,UAAU;IAC5C;;OAEG;IACwB,QAAQ,UAAS;IAE5C;;OAEG;IACwB,cAAc,UAAS;IAElD;;OAEG;IACwB,UAAU,UAAS;IAE9C;;OAEG;IACwB,WAAW,UAAS;IAEtC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;IAEvC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,cAAc,CAAO;IAG7B,OAAO,CAAC,SAAS,CAAC,CAAc;IAGhC,OAAO,CAAC,kBAAkB,CAAC,CAAc;IAEzC,OAAO,CAAC,WAAW,CAiBjB;IAEF,OAAO,CAAC,UAAU,CAchB;IAEF,OAAO,CAAC,SAAS,CAyBf;IAEF,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,aAAa,CAMnB;IAEF,OAAO,CAAC,wBAAwB,CAAuC;IAEvE,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,cAAc;IAUb,YAAY;IAUZ,MAAM;IA4Df,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,cAAc,CAAC;KACpC;CACF"}
1
+ {"version":3,"file":"slide-button.d.ts","sourceRoot":"","sources":["../../../src/components/slide-button/slide-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,iDAAiD,CAAC;AAGzD,MAAM,MAAM,wBAAwB,GAAG,WAAW,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAC,CAAC,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,qBACa,cAAe,SAAQ,UAAU;IAC5C;;OAEG;IACwB,QAAQ,UAAS;IAE5C;;OAEG;IACwB,cAAc,UAAS;IAElD;;OAEG;IACwB,UAAU,UAAS;IAE9C;;OAEG;IACwB,WAAW,UAAS;IAEtC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;IAEvC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,cAAc,CAAO;IAG7B,OAAO,CAAC,SAAS,CAAC,CAAc;IAGhC,OAAO,CAAC,kBAAkB,CAAC,CAAc;IAEzC,OAAO,CAAC,WAAW,CAiBjB;IAEF,OAAO,CAAC,UAAU,CAchB;IAEF,OAAO,CAAC,SAAS,CAyBf;IAEF,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,aAAa,CAMnB;IAEF,OAAO,CAAC,wBAAwB,CAAuC;IAEvE,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,cAAc;IAUb,YAAY;IAUZ,MAAM;IA4Df,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,cAAc,CAAC;KACpC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"slide-button.js","sources":["../../../src/components/slide-button/slide-button.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport componentStyle from './slide-button.css?inline';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport '../../icons/icon-chevron-double-right-google.js';\nimport {customElement} from '../../decorator.js';\n\nexport type ObcSlideButtonSlideEvent = CustomEvent<{completed: boolean}>;\n\n/**\n * `<obc-slide-button>` – A slide-to-confirm button that requires users to drag the button to the end of a track to trigger an action.\n *\n * Appears as a horizontal button with a draggable handle. The user must slide the handle to the right to complete the action, helping prevent accidental activations. Commonly used for critical or irreversible actions where explicit user intent is required (e.g., \"Delete\", \"Confirm\", \"Unlock\").\n *\n * ---\n *\n * ### Features\n * - **Slide-to-activate interaction:** Requires a deliberate sliding gesture to trigger the action, reducing accidental clicks.\n * - **Disabled state:** Can be disabled to prevent interaction (`disabled` property).\n * - **Leading icon (optional):** Supports a leading icon via the `leading-icon` slot, controlled by the `hasLeadingIcon` property.\n * - **Custom label:** Label text is provided via the `label` slot.\n * - **Auto-disable option:** When `autoDisable` is true, the button disables itself after a successful slide, preventing repeated actions.\n * - **Hug content:** The `hugContent` property allows the button to shrink to fit its content, rather than stretching to full width.\n * - **Visual feedback:** Provides animated feedback when sliding and snapping back if not completed.\n * - **Trailing icon:** Always displays a trailing double-chevron icon to indicate sliding direction.\n * - **Keyboard accessible:** The handle is focusable; `Enter` or `Space` triggers the action (with the same `slide` event and `autoDisable` behavior as a completed drag).\n *\n * ---\n *\n * ### Usage Guidelines\n * Use `obc-slide-button` for actions that require extra confirmation or where accidental activation could have significant consequences. Typical scenarios include confirming deletions, submitting irreversible forms, or unlocking sensitive features. Avoid using for routine or low-risk actions where a standard button suffices.\n *\n * - The sliding gesture provides a clear affordance for intentional actions.\n * - If you want the button to automatically disable after use (e.g., to prevent double submissions), set `autoDisable` to true.\n * - For best usability, keep the label concise and action-oriented (e.g., \"Slide to confirm\", \"Slide to delete\").\n * - The leading icon is optional and can be omitted for a simpler appearance.\n * - The button will snap back if the slide is not completed past the threshold.\n * - Only one slide button should be used for a given action to avoid confusion.\n * - Keyboard users activate with `Enter`/`Space` (single press — Tab + activation is considered deliberate). Provide `aria-label` on the host if the slotted label is not descriptive on its own (`aria-labelledby` is not supported — ID references cannot cross the shadow boundary).\n *\n * **TODO(designer):** Confirm if there are recommended minimum/maximum label lengths or if there are accessibility guidelines for color contrast and drag affordance.\n *\n * ---\n *\n * ### Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * | -------------- | --------------------- | --------------------------------------------- |\n * | leading-icon | `hasLeadingIcon` true | Icon at the start of the button (optional) |\n * | label | Always | Main label text for the button |\n *\n * ---\n *\n * ### Properties and Attributes\n * - `disabled` (boolean): Disables the button and prevents interaction. When true, the button is visually muted and cannot be slid.\n * - `hasLeadingIcon` (boolean): Controls whether the leading icon slot is shown. Set to false to hide the icon area.\n * - `hugContent` (boolean): If true, the button shrinks to fit its content instead of stretching to full width.\n * - `autoDisable` (boolean): When true, the button automatically disables itself after a successful slide action.\n *\n * ---\n *\n * ### Events\n * - `slide` – Fired when the slide action is completed (i.e., the handle is dragged past the threshold). The event detail contains `{completed: true}`.\n *\n * ---\n *\n * ### Example\n *\n * ```html\n * <obc-slide-button autoDisable>\n * <obi-placeholder slot=\"leading-icon\"></obi-placeholder>\n * <span slot=\"label\">Slide to confirm</span>\n * </obc-slide-button>\n * ```\n * In this example, the button displays a leading icon and a label. After sliding to the end, it disables itself automatically.\n *\n * @slot leading-icon - The icon to display at the start of the button content (shown when `hasLeadingIcon` is true).\n * @slot label - The label text to display in the button.\n * @fires {ObcSlideButtonSlideEvent} slide - Emitted when the slide action is completed.\n * @experimental\n */\n@customElement('obc-slide-button')\nexport class ObcSlideButton extends LitElement {\n /**\n * Whether the slide button is disabled. When true, the button cannot be interacted with and appears visually muted.\n */\n @property({type: Boolean}) disabled = false;\n\n /**\n * Whether to show the leading icon slot. Set to true to show the icon area at the start of the button.\n */\n @property({type: Boolean}) hasLeadingIcon = false;\n\n /**\n * Whether the button should hug its content. When true, the button width shrinks to fit its content instead of stretching to fill the container.\n */\n @property({type: Boolean}) hugContent = false;\n\n /**\n * Whether to automatically disable the button after a successful slide. When true, the button disables itself after the slide action completes.\n */\n @property({type: Boolean}) autoDisable = false;\n\n @state() private dragging = false;\n @state() private animatingBack = false;\n\n private dragStartX = 0;\n private dragCurrentX = 0;\n private dragOffset = 0;\n private trackWidth = 0;\n private buttonWidth = 0;\n private slideThreshold = 0.8;\n\n @query('.slide-button')\n private buttonRef?: HTMLElement;\n\n @query('.visual-container')\n private visualContainerRef?: HTMLElement;\n\n private onDragStart = (e: MouseEvent | TouchEvent) => {\n if (this.disabled) return;\n\n this.dragging = true;\n if (e instanceof MouseEvent) {\n this.dragStartX = e.clientX;\n } else {\n this.dragStartX = e.touches[0].clientX;\n }\n this.dragCurrentX = this.dragStartX;\n this.trackWidth = this.visualContainerRef?.offsetWidth || 0;\n this.buttonWidth = this.buttonRef?.offsetWidth || 0;\n\n window.addEventListener('mousemove', this.onDragMove);\n window.addEventListener('touchmove', this.onDragMove, {passive: false});\n window.addEventListener('mouseup', this.onDragEnd);\n window.addEventListener('touchend', this.onDragEnd);\n };\n\n private onDragMove = (e: MouseEvent | TouchEvent) => {\n if (!this.dragging) return;\n\n let clientX;\n if (e instanceof MouseEvent) {\n clientX = e.clientX;\n } else {\n clientX = e.touches[0].clientX;\n e.preventDefault();\n }\n\n this.dragCurrentX = clientX;\n this.dragOffset = this.dragCurrentX - this.dragStartX;\n this.requestUpdate();\n };\n\n private onDragEnd = () => {\n if (!this.dragging) return;\n\n this.dragging = false;\n this.animatingBack = true;\n\n const maxOffset = this.trackWidth - this.buttonWidth;\n const dragProgress = Math.max(0, this.dragOffset) / maxOffset;\n\n if (dragProgress >= this.slideThreshold) {\n this.completeSlide();\n }\n\n this.dragOffset = 0;\n this.requestUpdate();\n\n setTimeout(() => {\n this.animatingBack = false;\n this.requestUpdate();\n }, this.getResetDurationMs());\n\n window.removeEventListener('mousemove', this.onDragMove);\n window.removeEventListener('touchmove', this.onDragMove);\n window.removeEventListener('mouseup', this.onDragEnd);\n window.removeEventListener('touchend', this.onDragEnd);\n };\n\n private getResetDurationMs(): number {\n const resetDuration = getComputedStyle(this).getPropertyValue(\n '--slide-button-reset-duration'\n );\n return parseFloat(resetDuration) * 1000;\n }\n\n private completeSlide() {\n /**\n * Emitted when the slide action is completed (handle dragged past the\n * @fires {ObcSlideButtonSlideEvent} slide - threshold or activated via keyboard).\n */\n this.dispatchEvent(new CustomEvent('slide', {detail: {completed: true}}));\n\n if (this.autoDisable) {\n setTimeout(() => {\n this.disabled = true;\n this.requestUpdate();\n }, this.getResetDurationMs());\n }\n }\n\n private handleKeydown = (e: KeyboardEvent) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n e.preventDefault();\n if (this.disabled) return;\n this.completeSlide();\n this.playKeyboardFeedback();\n };\n\n private keyboardFeedbackTimeouts: ReturnType<typeof setTimeout>[] = [];\n\n private playKeyboardFeedback() {\n this.keyboardFeedbackTimeouts.forEach(clearTimeout);\n this.keyboardFeedbackTimeouts = [];\n this.trackWidth = this.visualContainerRef?.offsetWidth || 0;\n this.buttonWidth = this.buttonRef?.offsetWidth || 0;\n this.dragOffset = this.trackWidth - this.buttonWidth;\n this.animatingBack = true;\n this.requestUpdate();\n const durationMs = this.getResetDurationMs();\n this.keyboardFeedbackTimeouts.push(\n setTimeout(() => {\n this.dragOffset = 0;\n this.requestUpdate();\n this.keyboardFeedbackTimeouts.push(\n setTimeout(() => {\n this.animatingBack = false;\n this.requestUpdate();\n }, durationMs)\n );\n }, durationMs)\n );\n }\n\n private getButtonStyle() {\n if (!this.dragging && !this.animatingBack) return '';\n\n const maxOffset = this.trackWidth - this.buttonWidth + 1;\n let left = Math.max(-1, this.dragOffset - 1);\n left = Math.min(left, maxOffset - 1);\n\n return `left: ${left}px;`;\n }\n\n override firstUpdated() {\n const resizeObserver = new ResizeObserver(() => {\n this.trackWidth = this.visualContainerRef?.offsetWidth || 0;\n this.buttonWidth = this.buttonRef?.offsetWidth || 0;\n });\n if (this.visualContainerRef)\n resizeObserver.observe(this.visualContainerRef);\n if (this.buttonRef) resizeObserver.observe(this.buttonRef);\n }\n\n override render() {\n const containerClasses = {\n 'slide-button-container': true,\n dragging: this.dragging,\n 'animating-back': this.animatingBack,\n disabled: this.disabled,\n 'hug-content': this.hugContent,\n };\n\n const visualClasses = {\n 'visual-container': true,\n };\n\n const buttonClasses = {\n 'slide-button': true,\n 'has-leading-icon': this.hasLeadingIcon,\n };\n\n const forwardedAriaLabel = this.getAttribute('aria-label') ?? undefined;\n\n return html`\n <div class=${classMap(containerClasses)}>\n <div class=${classMap(visualClasses)}>\n <div\n class=\"button-touch-target\"\n style=${this.getButtonStyle()}\n role=\"button\"\n tabindex=${this.disabled ? '-1' : '0'}\n aria-disabled=${this.disabled ? 'true' : 'false'}\n aria-label=${ifDefined(forwardedAriaLabel)}\n @mousedown=${this.onDragStart}\n @touchstart=${this.onDragStart}\n @keydown=${this.handleKeydown}\n >\n <div class=${classMap(buttonClasses)}>\n <div class=\"button-content\">\n ${this.hasLeadingIcon\n ? html`\n <div class=\"leading-icon\">\n <slot name=\"leading-icon\"></slot>\n </div>\n `\n : nothing}\n <div class=\"button-label\">\n <slot name=\"label\"></slot>\n </div>\n </div>\n </div>\n </div>\n <div class=\"trailing-icon-area\">\n <obi-chevron-double-right-google\n class=\"trailing-icon\"\n aria-hidden=\"true\"\n ></obi-chevron-double-right-google>\n </div>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-slide-button': ObcSlideButton;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slide-button.js","sources":["../../../src/components/slide-button/slide-button.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport componentStyle from './slide-button.css?inline';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport '../../icons/icon-chevron-double-right-google.js';\nimport {customElement} from '../../decorator.js';\n\nexport type ObcSlideButtonSlideEvent = CustomEvent<{completed: boolean}>;\n\n/**\n * `<obc-slide-button>` – A slide-to-confirm button that requires users to drag the button to the end of a track to trigger an action.\n *\n * Appears as a horizontal button with a draggable handle. The user must slide the handle to the right to complete the action, helping prevent accidental activations. Commonly used for critical or irreversible actions where explicit user intent is required (e.g., \"Delete\", \"Confirm\", \"Unlock\").\n *\n * ---\n *\n * ### Features\n * - **Slide-to-activate interaction:** Requires a deliberate sliding gesture to trigger the action, reducing accidental clicks.\n * - **Disabled state:** Can be disabled to prevent interaction (`disabled` property).\n * - **Leading icon (optional):** Supports a leading icon via the `leading-icon` slot, controlled by the `hasLeadingIcon` property.\n * - **Custom label:** Label text is provided via the `label` slot.\n * - **Auto-disable option:** When `autoDisable` is true, the button disables itself after a successful slide, preventing repeated actions.\n * - **Hug content:** The `hugContent` property allows the button to shrink to fit its content, rather than stretching to full width.\n * - **Visual feedback:** Provides animated feedback when sliding and snapping back if not completed.\n * - **Trailing icon:** Always displays a trailing double-chevron icon to indicate sliding direction.\n * - **Keyboard accessible:** The handle is focusable; `Enter` or `Space` triggers the action (with the same `slide` event and `autoDisable` behavior as a completed drag).\n *\n * ---\n *\n * ### Usage Guidelines\n * Use `obc-slide-button` for actions that require extra confirmation or where accidental activation could have significant consequences. Typical scenarios include confirming deletions, submitting irreversible forms, or unlocking sensitive features. Avoid using for routine or low-risk actions where a standard button suffices.\n *\n * - The sliding gesture provides a clear affordance for intentional actions.\n * - If you want the button to automatically disable after use (e.g., to prevent double submissions), set `autoDisable` to true.\n * - For best usability, keep the label concise and action-oriented (e.g., \"Slide to confirm\", \"Slide to delete\").\n * - The leading icon is optional and can be omitted for a simpler appearance.\n * - The button will snap back if the slide is not completed past the threshold.\n * - Only one slide button should be used for a given action to avoid confusion.\n * - Keyboard users activate with `Enter`/`Space` (single press — Tab + activation is considered deliberate). Provide `aria-label` on the host if the slotted label is not descriptive on its own (`aria-labelledby` is not supported — ID references cannot cross the shadow boundary).\n *\n * **TODO(designer):** Confirm if there are recommended minimum/maximum label lengths or if there are accessibility guidelines for color contrast and drag affordance.\n *\n * ---\n *\n * ### Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * | -------------- | --------------------- | --------------------------------------------- |\n * | leading-icon | `hasLeadingIcon` true | Icon at the start of the button (optional) |\n * | label | Always | Main label text for the button |\n *\n * ---\n *\n * ### Properties and Attributes\n * - `disabled` (boolean): Disables the button and prevents interaction. When true, the button is visually muted and cannot be slid.\n * - `hasLeadingIcon` (boolean): Controls whether the leading icon slot is shown. Set to false to hide the icon area.\n * - `hugContent` (boolean): If true, the button shrinks to fit its content instead of stretching to full width.\n * - `autoDisable` (boolean): When true, the button automatically disables itself after a successful slide action.\n *\n * ---\n *\n * ### Events\n * - `slide` – Fired when the slide action is completed (i.e., the handle is dragged past the threshold). The event detail contains `{completed: true}`.\n *\n * ---\n *\n * ### Example\n *\n * ```html\n * <obc-slide-button autoDisable>\n * <obi-placeholder slot=\"leading-icon\"></obi-placeholder>\n * <span slot=\"label\">Slide to confirm</span>\n * </obc-slide-button>\n * ```\n * In this example, the button displays a leading icon and a label. After sliding to the end, it disables itself automatically.\n *\n * @slot leading-icon - The icon to display at the start of the button content (shown when `hasLeadingIcon` is true).\n * @slot label - The label text to display in the button.\n * @fires {ObcSlideButtonSlideEvent} slide - Emitted when the slide action is completed.\n * @experimental\n */\n@customElement('obc-slide-button')\nexport class ObcSlideButton extends LitElement {\n /**\n * Whether the slide button is disabled. When true, the button cannot be interacted with and appears visually muted.\n */\n @property({type: Boolean}) disabled = false;\n\n /**\n * Whether to show the leading icon slot. Set to true to show the icon area at the start of the button.\n */\n @property({type: Boolean}) hasLeadingIcon = false;\n\n /**\n * Whether the button should hug its content. When true, the button width shrinks to fit its content instead of stretching to fill the container.\n */\n @property({type: Boolean}) hugContent = false;\n\n /**\n * Whether to automatically disable the button after a successful slide. When true, the button disables itself after the slide action completes.\n */\n @property({type: Boolean}) autoDisable = false;\n\n @state() private dragging = false;\n @state() private animatingBack = false;\n\n private dragStartX = 0;\n private dragCurrentX = 0;\n private dragOffset = 0;\n private trackWidth = 0;\n private buttonWidth = 0;\n private slideThreshold = 0.8;\n\n @query('.slide-button')\n private buttonRef?: HTMLElement;\n\n @query('.visual-container')\n private visualContainerRef?: HTMLElement;\n\n private onDragStart = (e: MouseEvent | TouchEvent) => {\n if (this.disabled) return;\n\n this.dragging = true;\n if (e instanceof MouseEvent) {\n this.dragStartX = e.clientX;\n } else {\n this.dragStartX = e.touches[0].clientX;\n }\n this.dragCurrentX = this.dragStartX;\n this.trackWidth = this.visualContainerRef?.offsetWidth || 0;\n this.buttonWidth = this.buttonRef?.offsetWidth || 0;\n\n window.addEventListener('mousemove', this.onDragMove);\n window.addEventListener('touchmove', this.onDragMove, {passive: false});\n window.addEventListener('mouseup', this.onDragEnd);\n window.addEventListener('touchend', this.onDragEnd);\n };\n\n private onDragMove = (e: MouseEvent | TouchEvent) => {\n if (!this.dragging) return;\n\n let clientX;\n if (e instanceof MouseEvent) {\n clientX = e.clientX;\n } else {\n clientX = e.touches[0].clientX;\n e.preventDefault();\n }\n\n this.dragCurrentX = clientX;\n this.dragOffset = this.dragCurrentX - this.dragStartX;\n this.requestUpdate();\n };\n\n private onDragEnd = () => {\n if (!this.dragging) return;\n\n this.dragging = false;\n this.animatingBack = true;\n\n const maxOffset = this.trackWidth - this.buttonWidth;\n const dragProgress = Math.max(0, this.dragOffset) / maxOffset;\n\n if (dragProgress >= this.slideThreshold) {\n this.completeSlide();\n }\n\n this.dragOffset = 0;\n this.requestUpdate();\n\n setTimeout(() => {\n this.animatingBack = false;\n this.requestUpdate();\n }, this.getResetDurationMs());\n\n window.removeEventListener('mousemove', this.onDragMove);\n window.removeEventListener('touchmove', this.onDragMove);\n window.removeEventListener('mouseup', this.onDragEnd);\n window.removeEventListener('touchend', this.onDragEnd);\n };\n\n private getResetDurationMs(): number {\n const resetDuration = getComputedStyle(this).getPropertyValue(\n '--slide-button-reset-duration'\n );\n return parseFloat(resetDuration) * 1000;\n }\n\n private completeSlide() {\n /**\n * Emitted when the slide action is completed (handle dragged past the\n * threshold or activated via keyboard).\n * @fires slide\n */\n this.dispatchEvent(new CustomEvent('slide', {detail: {completed: true}}));\n\n if (this.autoDisable) {\n setTimeout(() => {\n this.disabled = true;\n this.requestUpdate();\n }, this.getResetDurationMs());\n }\n }\n\n private handleKeydown = (e: KeyboardEvent) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n e.preventDefault();\n if (this.disabled) return;\n this.completeSlide();\n this.playKeyboardFeedback();\n };\n\n private keyboardFeedbackTimeouts: ReturnType<typeof setTimeout>[] = [];\n\n private playKeyboardFeedback() {\n this.keyboardFeedbackTimeouts.forEach(clearTimeout);\n this.keyboardFeedbackTimeouts = [];\n this.trackWidth = this.visualContainerRef?.offsetWidth || 0;\n this.buttonWidth = this.buttonRef?.offsetWidth || 0;\n this.dragOffset = this.trackWidth - this.buttonWidth;\n this.animatingBack = true;\n this.requestUpdate();\n const durationMs = this.getResetDurationMs();\n this.keyboardFeedbackTimeouts.push(\n setTimeout(() => {\n this.dragOffset = 0;\n this.requestUpdate();\n this.keyboardFeedbackTimeouts.push(\n setTimeout(() => {\n this.animatingBack = false;\n this.requestUpdate();\n }, durationMs)\n );\n }, durationMs)\n );\n }\n\n private getButtonStyle() {\n if (!this.dragging && !this.animatingBack) return '';\n\n const maxOffset = this.trackWidth - this.buttonWidth + 1;\n let left = Math.max(-1, this.dragOffset - 1);\n left = Math.min(left, maxOffset - 1);\n\n return `left: ${left}px;`;\n }\n\n override firstUpdated() {\n const resizeObserver = new ResizeObserver(() => {\n this.trackWidth = this.visualContainerRef?.offsetWidth || 0;\n this.buttonWidth = this.buttonRef?.offsetWidth || 0;\n });\n if (this.visualContainerRef)\n resizeObserver.observe(this.visualContainerRef);\n if (this.buttonRef) resizeObserver.observe(this.buttonRef);\n }\n\n override render() {\n const containerClasses = {\n 'slide-button-container': true,\n dragging: this.dragging,\n 'animating-back': this.animatingBack,\n disabled: this.disabled,\n 'hug-content': this.hugContent,\n };\n\n const visualClasses = {\n 'visual-container': true,\n };\n\n const buttonClasses = {\n 'slide-button': true,\n 'has-leading-icon': this.hasLeadingIcon,\n };\n\n const forwardedAriaLabel = this.getAttribute('aria-label') ?? undefined;\n\n return html`\n <div class=${classMap(containerClasses)}>\n <div class=${classMap(visualClasses)}>\n <div\n class=\"button-touch-target\"\n style=${this.getButtonStyle()}\n role=\"button\"\n tabindex=${this.disabled ? '-1' : '0'}\n aria-disabled=${this.disabled ? 'true' : 'false'}\n aria-label=${ifDefined(forwardedAriaLabel)}\n @mousedown=${this.onDragStart}\n @touchstart=${this.onDragStart}\n @keydown=${this.handleKeydown}\n >\n <div class=${classMap(buttonClasses)}>\n <div class=\"button-content\">\n ${this.hasLeadingIcon\n ? html`\n <div class=\"leading-icon\">\n <slot name=\"leading-icon\"></slot>\n </div>\n `\n : nothing}\n <div class=\"button-label\">\n <slot name=\"label\"></slot>\n </div>\n </div>\n </div>\n </div>\n <div class=\"trailing-icon-area\">\n <obi-chevron-double-right-google\n class=\"trailing-icon\"\n aria-hidden=\"true\"\n ></obi-chevron-double-right-google>\n </div>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-slide-button': ObcSlideButton;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -205,13 +205,13 @@ export declare class ObcSlider extends LitElement {
205
205
  * Fires the `value` event with the new value.
206
206
  *
207
207
  * @param value - The new value to set.
208
- * @fires value - Fired when the value is changed
208
+ * @fires value
209
209
  */
210
210
  onInput(value: number): void;
211
211
  /**
212
212
  * Fires the `change` event with the current value.
213
213
  *
214
- * @fires change - Fired when user interaction completes; dispatched on release even if the value did not change
214
+ * @fires change
215
215
  */
216
216
  private fireChangeEvent;
217
217
  /**
@@ -67,7 +67,7 @@ let ObcSlider = class extends LitElement {
67
67
  * Fires the `value` event with the new value.
68
68
  *
69
69
  * @param value - The new value to set.
70
- * @fires value - Fired when the value is changed
70
+ * @fires value
71
71
  */
72
72
  onInput(value) {
73
73
  this.value = value;
@@ -76,7 +76,7 @@ let ObcSlider = class extends LitElement {
76
76
  /**
77
77
  * Fires the `change` event with the current value.
78
78
  *
79
- * @fires change - Fired when user interaction completes; dispatched on release even if the value did not change
79
+ * @fires change
80
80
  */
81
81
  fireChangeEvent() {
82
82
  this.dispatchEvent(
@@ -1 +1 @@
1
- {"version":3,"file":"slider.js","sources":["../../../src/components/slider/slider.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport {styleMap} from 'lit/directives/style-map.js';\nimport componentStyle from './slider.css?inline';\nimport '../icon-button/icon-button.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {customElement} from '../../decorator.js';\n\n/**\n * Enum of slider visual and interaction variants.\n *\n * - `normal`: Standard slider appearance and interaction.\n * - `enhanced`: Visually prominent slider with increased track and thumb size for easier manipulation.\n * - `no-input`: Read-only display; disables user input and interaction.\n */\nexport enum ObcSliderVariant {\n Normal = 'normal',\n Enhanced = 'enhanced',\n NoInput = 'no-input',\n}\n\n/**\n * Custom event type for slider value changes.\n * The event detail contains the new numeric value.\n */\nexport type ObcSliderValueEvent = CustomEvent<number>;\n\n/**\n * Custom event type for slider change event (fired after user interaction completes).\n * The event detail contains the new numeric value.\n */\nexport type ObcSliderChangeEvent = CustomEvent<number>;\n\n/**\n * `<obc-slider>` – A horizontal slider component for selecting a numeric value within a defined range.\n *\n * Provides a visual and interactive way for users to adjust values such as volume, brightness, or other continuous settings. The slider supports optional step increments, left/right icon buttons for quick adjustments, and can be configured for read-only display or enhanced visual prominence.\n *\n * Appears as a horizontal track with a draggable thumb, and may include optional icon buttons on either side for increment/decrement actions. The component can be used for both direct manipulation (dragging the thumb) and discrete changes (via buttons).\n *\n * ---\n *\n * ### Features\n * - **Variants:**\n * - **Normal:** Standard slider with a slim track and thumb.\n * - **Enhanced:** Larger track and thumb for improved accessibility and visual emphasis.\n * - **No Input:** Read-only mode; disables all user interaction and presents the current value visually.\n * - **Value Range:** Supports configurable `min`, `max`, and `step` properties for precise control over allowed values.\n * - **Step Buttons:** Optional left and right icon buttons allow users to increment or decrement the value by a defined step (`stepClick`).\n * - **Icons:** Custom icons can be slotted into the left and right button positions for contextual meaning (e.g., `<obi-arrow></obi-arrow>, <obi-placeholder></obi-placeholder>`).\n * - **Seeking:** When `allowSeeking` is enabled, users can click or drag along the track to set the value, with smooth animated transitions based on `seekingSpeed`.\n * - **Hug Container:** The `hugcontainer` attribute removes spacing between the slider and its icon buttons, allowing for a compact layout.\n * - **Accessibility:** Underlying input is a native `<input type=\"range\">` for keyboard and screen reader support.\n *\n * ---\n *\n * ### Usage Guidelines\n * Use `obc-slider` when you need users to select or adjust a value within a continuous or stepped range, such as for volume, brightness, or similar controls. The enhanced variant is suitable for scenarios where the slider is a primary control or needs to be more visually prominent. The no-input variant is ideal for displaying a value without allowing user changes.\n *\n * - For discrete, step-based changes, provide `step` and/or `stepClick` values.\n * - Use left/right icons to clarify the meaning of the adjustment (e.g., low/high, decrease/increase).\n * - Enable `allowSeeking` for scenarios where users should be able to jump to a specific value by clicking the track.\n * - Use `hugcontainer` when the slider should visually connect tightly with its icon buttons.\n *\n * **TODO(designer):** Clarify recommended use cases for each variant and when to use `allowSeeking` vs. standard interaction.\n *\n * ---\n *\n * ### Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-------------|---------------------------|--------------------------------------------|\n * | icon-left | `hasLeftIcon` is true | Icon/button for decrement action |\n * | icon-right | `hasRightIcon` is true | Icon/button for increment action |\n *\n * ---\n *\n * ### Properties and Attributes\n * - `value` (number): Current slider value. Updates as the user interacts.\n * - `min` (number): Minimum allowed value (default: 0).\n * - `max` (number): Maximum allowed value (default: 100).\n * - `step` (number): Step granularity for value changes (optional).\n * - `stepClick` (number): Amount to increment/decrement when clicking icon buttons (default: 10).\n * - `variant` (ObcSliderVariant): Visual/interaction style (`normal`, `enhanced`, `no-input`). Default: `normal`.\n * - `hasLeftIcon`/`hasRightIcon` (boolean): Show icon button on left/right.\n * - `allowSeeking` (boolean): Enables animated seeking to clicked value on the track.\n * - `seekingSpeed` (number): Animation speed for seeking (default: 1/3; higher is faster).\n * - `hugcontainer` (attribute): Removes spacing between slider and icon buttons for a compact layout.\n *\n * ---\n *\n * ### Events\n * - `value` – Fired continuously when the slider value changes during user interaction or programmatically. The event detail contains the new value as a number.\n * - `change` – Fired only after user interaction completes (mouse/touch release or button click). The event detail contains the new value as a number.\n *\n * ---\n *\n * ### Best Practices & Constraints\n * - Only use `no-input` variant for read-only display; interactive controls should use `normal` or `enhanced`.\n * - For accessibility, ensure the slider has a visible label or context.\n * - Use step values that make sense for the range (e.g., avoid step=0.01 for a 0–10 range unless fine granularity is needed).\n * - When using icon buttons, provide icons that clearly indicate their function.\n * - The slider is horizontal only; for vertical sliders, use a different component.\n *\n * ---\n *\n * ### Example\n *\n * ```html\n * <obc-slider\n * value=\"40\"\n * min=\"0\"\n * max=\"100\"\n * step=\"10\"\n * haslefticon\n * hasrighticon\n * variant=\"enhanced\"\n * >\n * <obi-arrow slot=\"icon-left\"></obi-arrow>\n * <obi-arrow slot=\"icon-right\"></obi-arrow>\n * </obc-slider>\n * ```\n *\n * In this example, the slider allows selection from 0 to 100 in steps of 10, with left/right arrow icons for quick adjustments.\n *\n * @slot icon-left - Slot for the left icon button (shown when `hasLeftIcon` is true)\n * @slot icon-right - Slot for the right icon button (shown when `hasRightIcon` is true)\n * @attr hugcontainer - If set, the slider will not have any spacing between the slider icons and the container\n * @fires {ObcSliderValueEvent} value - Fired when the value is changed\n * @fires {ObcSliderChangeEvent} change - Fired when user interaction completes; dispatched on release even if the value did not change\n * @stable\n */\n@customElement('obc-slider')\nexport class ObcSlider extends LitElement {\n /**\n * The current value of the slider.\n *\n * Updates as the user drags the thumb, clicks the track (if `allowSeeking`), or uses the increment/decrement buttons.\n */\n @property({type: Number}) value = 50;\n\n /**\n * The minimum allowed value for the slider.\n *\n * Default is 0.\n */\n @property({type: Number}) min = 0;\n\n /**\n * The maximum allowed value for the slider.\n *\n * Default is 100.\n */\n @property({type: Number}) max = 100;\n\n /**\n * The step granularity for slider value changes.\n *\n * If set, the slider will snap to multiples of this value between min and max.\n * Optional; if not set, the slider is continuous.\n */\n @property({type: Number}) step: number | undefined;\n\n /**\n * The amount to increment or decrement the value when clicking the left/right icon buttons.\n *\n * Default is 10.\n * @availableWhen hasLeftIcon==true || hasRightIcon==true\n */\n @property({type: Number}) stepClick = 10;\n\n /**\n * The visual and interaction style of the slider.\n *\n * - `normal`: Standard appearance.\n * - `enhanced`: Larger track and thumb for emphasis.\n * - `no-input`: Read-only; disables all user input.\n *\n * Default is `normal`.\n */\n @property({type: String}) variant: ObcSliderVariant = ObcSliderVariant.Normal;\n\n /**\n * Whether to display a left icon button for decrementing the value.\n *\n * When true, the `icon-left` slot is rendered as a button.\n */\n @property({type: Boolean}) hasLeftIcon = false;\n\n /**\n * Whether to display a right icon button for incrementing the value.\n *\n * When true, the `icon-right` slot is rendered as a button.\n */\n @property({type: Boolean}) hasRightIcon = false;\n\n /**\n * Enables animated seeking: clicking or dragging along the track will set the value to the clicked position, animating smoothly.\n *\n * Default is false.\n * @availableWhen variant!=no-input && disabled==false\n */\n @property({type: Boolean}) allowSeeking = false;\n\n /**\n * The speed of the smooth animation that moves the value to the clicked position (used when `allowSeeking` is false).\n *\n * Expressed as the inverse of seconds to go from min to max (e.g., 1/3 means 3 seconds for full range).\n * Default is 1/3.\n * @availableWhen allowSeeking==false && variant!=no-input && disabled==false\n */\n @property({type: Number}) seekingSpeed = 1 / 3;\n\n @property({type: Boolean}) disabled = false;\n\n private get ratio(): number {\n const range = this.max - this.min;\n if (!Number.isFinite(range) || range <= 0) return 0;\n const ratio = (this.value - this.min) / range;\n if (!Number.isFinite(ratio)) return 0;\n return Math.max(0, Math.min(1, ratio));\n }\n\n private animationFrame: number | null = null;\n private isMouseDown = false;\n private isTouchActive = false;\n private targetValue = 0;\n private isDragging = false;\n private animationStartTime: number | null = null;\n private animationStartValue: number = 0;\n\n /**\n * Handles input changes from the slider or buttons.\n * Fires the `value` event with the new value.\n *\n * @param value - The new value to set.\n * @fires value - Fired when the value is changed\n */\n onInput(value: number) {\n this.value = value;\n this.dispatchEvent(new CustomEvent('value', {detail: this.value}));\n }\n\n /**\n * Fires the `change` event with the current value.\n *\n * @fires change - Fired when user interaction completes; dispatched on release even if the value did not change\n */\n private fireChangeEvent() {\n this.dispatchEvent(\n new CustomEvent('change', {detail: this.value}) as ObcSliderChangeEvent\n );\n }\n\n /**\n * Decrements the value by `stepClick` when the left icon button is clicked.\n */\n onReduceClick() {\n if (this.disabled) return;\n this.onInput(Math.max(this.value - this.stepClick, this.min));\n this.fireChangeEvent();\n }\n\n /**\n * Increments the value by `stepClick` when the right icon button is clicked.\n */\n onIncreaseClick() {\n if (this.disabled) return;\n this.onInput(Math.min(this.value + this.stepClick, this.max));\n this.fireChangeEvent();\n }\n\n private get slider(): HTMLInputElement {\n return this.renderRoot.querySelector('input[type=\"range\"]')!;\n }\n\n private isClickingThumb(e: MouseEvent | TouchEvent) {\n const rect = this.slider.getBoundingClientRect();\n const left = rect.left + 24;\n const width = rect.width - 48;\n const thumbWidth = 48;\n const ratioValue = this.ratio;\n const thumbCenter = left + width * ratioValue;\n\n let clientX: number;\n if ('touches' in e) {\n clientX = e.touches[0].clientX;\n } else {\n clientX = e.clientX;\n }\n\n const isNearThumb = Math.abs(clientX - thumbCenter) <= thumbWidth / 2;\n return isNearThumb;\n }\n\n private onMouseDown(e: MouseEvent) {\n if (this.variant === ObcSliderVariant.NoInput || this.disabled) return;\n if (this.isClickingThumb(e)) return;\n this.isMouseDown = true;\n this.updateTargetValue(e);\n e.preventDefault();\n window.addEventListener('mousemove', this.onWindowMouseMove);\n window.addEventListener('mouseup', this.onWindowMouseUp);\n this.startAnimation();\n }\n\n private onTouchStart(e: TouchEvent) {\n if (this.variant === ObcSliderVariant.NoInput || this.disabled) return;\n if (this.isClickingThumb(e)) return;\n this.isTouchActive = true;\n this.updateTargetValue(e);\n e.preventDefault();\n window.addEventListener('touchmove', this.onWindowTouchMove, {\n passive: false,\n });\n window.addEventListener('touchend', this.onWindowTouchEnd);\n this.startAnimation();\n }\n\n private onWindowMouseMove = (e: MouseEvent) => {\n this.onMouseMove(e);\n };\n\n private onWindowMouseUp = () => {\n this.onMouseUp();\n };\n\n private onWindowTouchMove = (e: TouchEvent) => {\n this.onTouchMove(e);\n };\n\n private onWindowTouchEnd = () => {\n this.onTouchEnd();\n };\n\n private onMouseMove(e: MouseEvent) {\n if (this.isMouseDown) {\n this.updateTargetValue(e);\n }\n }\n\n private onTouchMove(e: TouchEvent) {\n if (this.isTouchActive) {\n this.updateTargetValue(e);\n }\n }\n\n private onMouseUp() {\n this.isMouseDown = false;\n window.removeEventListener('mousemove', this.onWindowMouseMove);\n window.removeEventListener('mouseup', this.onWindowMouseUp);\n this.stopAnimation();\n this.fireChangeEvent();\n }\n\n private onTouchEnd() {\n this.isTouchActive = false;\n window.removeEventListener('touchmove', this.onWindowTouchMove);\n window.removeEventListener('touchend', this.onWindowTouchEnd);\n this.stopAnimation();\n this.fireChangeEvent();\n }\n\n private updateTargetValue(e: MouseEvent | TouchEvent) {\n const rect = this.slider.getBoundingClientRect();\n const left = rect.left + 24;\n const width = rect.width - 48;\n const x = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX;\n const percent = (x - left) / width;\n const min = parseFloat(this.slider.min);\n const max = parseFloat(this.slider.max);\n const unroundedValue = min + (max - min) * percent;\n if (this.step) {\n this.targetValue = Math.round(unroundedValue / this.step) * this.step;\n } else {\n this.targetValue = unroundedValue;\n }\n }\n\n private startAnimation() {\n this.isDragging = this.allowSeeking;\n this.animationStartTime = performance.now();\n this.animationStartValue = parseFloat(this.slider.value);\n const min = parseFloat(this.slider.min);\n const max = parseFloat(this.slider.max);\n const step = this.step;\n const duration = (1 / this.seekingSpeed) * 1000; // ms\n const direction = this.targetValue > this.animationStartValue ? 1 : -1;\n\n const animate = () => {\n let nextValue = this.targetValue;\n if (!this.isDragging) {\n const now = performance.now();\n const elapsed = now - (this.animationStartTime ?? now);\n const range = Math.abs(max - min);\n // How much of the range should be covered by now\n const expectedProgress = Math.min(elapsed / duration, 1);\n const expectedValue =\n this.animationStartValue + direction * range * expectedProgress;\n // Snap to step\n if (direction > 0) {\n nextValue =\n step === undefined\n ? expectedValue\n : Math.ceil((expectedValue - min) / step) * step + min;\n nextValue = Math.min(this.targetValue, nextValue);\n } else {\n nextValue =\n step === undefined\n ? expectedValue\n : Math.floor((expectedValue - min) / step) * step + min;\n nextValue = Math.max(this.targetValue, nextValue);\n }\n }\n // Only update if value actually changes\n if (parseFloat(this.slider.value) !== nextValue) {\n this.slider.value = String(nextValue);\n this.slider.dispatchEvent(new Event('input'));\n }\n // Continue animating if not at target\n if (\n (direction > 0 && nextValue < this.targetValue) ||\n (direction < 0 && nextValue > this.targetValue)\n ) {\n this.animationFrame = requestAnimationFrame(animate);\n } else if (this.isMouseDown || this.isTouchActive) {\n // If mouse or touch is still active, wait for new target\n this.animationStartTime = performance.now();\n this.animationStartValue = parseFloat(this.slider.value);\n this.animationFrame = requestAnimationFrame(animate);\n this.isDragging = true;\n }\n };\n\n this.animationFrame = requestAnimationFrame(animate);\n }\n\n private stopAnimation() {\n if (this.animationFrame !== null) {\n cancelAnimationFrame(this.animationFrame);\n this.animationFrame = null;\n }\n }\n\n override render() {\n return html`\n ${this.hasLeftIcon\n ? html` <obc-icon-button\n ?disabled=${this.disabled}\n @click=${this.onReduceClick}\n variant=\"normal\"\n >\n <slot name=\"icon-left\"></slot>\n </obc-icon-button>`\n : null}\n <div\n class=${classMap({\n wrapper: true,\n [this.variant]: true,\n disabled: this.disabled,\n })}\n style=${styleMap({\n '--_ratio': String(this.ratio),\n })}\n >\n <div class=\"track\"></div>\n <input\n type=\"range\"\n min=${this.min}\n max=${this.max}\n step=${ifDefined(this.step)}\n .value=${this.value.toString()}\n ?disabled=${this.variant === ObcSliderVariant.NoInput ||\n this.disabled}\n class=\"slider\"\n @input=${(event: Event) => {\n this.value = Number((event.target as HTMLInputElement).value);\n this.dispatchEvent(new CustomEvent('value', {detail: this.value}));\n }}\n @change=${() => {\n this.fireChangeEvent();\n }}\n @mousedown=${this.onMouseDown}\n @touchstart=${this.onTouchStart}\n @mousemove=${this.onMouseMove}\n @touchmove=${this.onTouchMove}\n @mouseup=${this.onMouseUp}\n @touchend=${this.onTouchEnd}\n />\n <div\n class=\"interactive-track-hover\"\n @mousedown=${this.onMouseDown}\n @touchstart=${this.onTouchStart}\n @mousemove=${this.onMouseMove}\n @touchmove=${this.onTouchMove}\n @mouseup=${this.onMouseUp}\n @touchend=${this.onTouchEnd}\n ></div>\n <div\n class=\"container-hover\"\n @mousedown=${this.onMouseDown}\n @touchstart=${this.onTouchStart}\n @mousemove=${this.onMouseMove}\n @touchmove=${this.onTouchMove}\n @mouseup=${this.onMouseUp}\n @touchend=${this.onTouchEnd}\n ></div>\n <div class=\"interactive-track\"></div>\n <div class=\"thumb\"></div>\n </div>\n ${this.hasRightIcon\n ? html`<obc-icon-button\n ?disabled=${this.disabled}\n @click=${this.onIncreaseClick}\n variant=\"normal\"\n >\n <slot name=\"icon-right\"></slot>\n </obc-icon-button>`\n : null}\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-slider': ObcSlider;\n }\n}\n"],"names":["ObcSliderVariant"],"mappings":"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"}
1
+ {"version":3,"file":"slider.js","sources":["../../../src/components/slider/slider.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport {styleMap} from 'lit/directives/style-map.js';\nimport componentStyle from './slider.css?inline';\nimport '../icon-button/icon-button.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {customElement} from '../../decorator.js';\n\n/**\n * Enum of slider visual and interaction variants.\n *\n * - `normal`: Standard slider appearance and interaction.\n * - `enhanced`: Visually prominent slider with increased track and thumb size for easier manipulation.\n * - `no-input`: Read-only display; disables user input and interaction.\n */\nexport enum ObcSliderVariant {\n Normal = 'normal',\n Enhanced = 'enhanced',\n NoInput = 'no-input',\n}\n\n/**\n * Custom event type for slider value changes.\n * The event detail contains the new numeric value.\n */\nexport type ObcSliderValueEvent = CustomEvent<number>;\n\n/**\n * Custom event type for slider change event (fired after user interaction completes).\n * The event detail contains the new numeric value.\n */\nexport type ObcSliderChangeEvent = CustomEvent<number>;\n\n/**\n * `<obc-slider>` – A horizontal slider component for selecting a numeric value within a defined range.\n *\n * Provides a visual and interactive way for users to adjust values such as volume, brightness, or other continuous settings. The slider supports optional step increments, left/right icon buttons for quick adjustments, and can be configured for read-only display or enhanced visual prominence.\n *\n * Appears as a horizontal track with a draggable thumb, and may include optional icon buttons on either side for increment/decrement actions. The component can be used for both direct manipulation (dragging the thumb) and discrete changes (via buttons).\n *\n * ---\n *\n * ### Features\n * - **Variants:**\n * - **Normal:** Standard slider with a slim track and thumb.\n * - **Enhanced:** Larger track and thumb for improved accessibility and visual emphasis.\n * - **No Input:** Read-only mode; disables all user interaction and presents the current value visually.\n * - **Value Range:** Supports configurable `min`, `max`, and `step` properties for precise control over allowed values.\n * - **Step Buttons:** Optional left and right icon buttons allow users to increment or decrement the value by a defined step (`stepClick`).\n * - **Icons:** Custom icons can be slotted into the left and right button positions for contextual meaning (e.g., `<obi-arrow></obi-arrow>, <obi-placeholder></obi-placeholder>`).\n * - **Seeking:** When `allowSeeking` is enabled, users can click or drag along the track to set the value, with smooth animated transitions based on `seekingSpeed`.\n * - **Hug Container:** The `hugcontainer` attribute removes spacing between the slider and its icon buttons, allowing for a compact layout.\n * - **Accessibility:** Underlying input is a native `<input type=\"range\">` for keyboard and screen reader support.\n *\n * ---\n *\n * ### Usage Guidelines\n * Use `obc-slider` when you need users to select or adjust a value within a continuous or stepped range, such as for volume, brightness, or similar controls. The enhanced variant is suitable for scenarios where the slider is a primary control or needs to be more visually prominent. The no-input variant is ideal for displaying a value without allowing user changes.\n *\n * - For discrete, step-based changes, provide `step` and/or `stepClick` values.\n * - Use left/right icons to clarify the meaning of the adjustment (e.g., low/high, decrease/increase).\n * - Enable `allowSeeking` for scenarios where users should be able to jump to a specific value by clicking the track.\n * - Use `hugcontainer` when the slider should visually connect tightly with its icon buttons.\n *\n * **TODO(designer):** Clarify recommended use cases for each variant and when to use `allowSeeking` vs. standard interaction.\n *\n * ---\n *\n * ### Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-------------|---------------------------|--------------------------------------------|\n * | icon-left | `hasLeftIcon` is true | Icon/button for decrement action |\n * | icon-right | `hasRightIcon` is true | Icon/button for increment action |\n *\n * ---\n *\n * ### Properties and Attributes\n * - `value` (number): Current slider value. Updates as the user interacts.\n * - `min` (number): Minimum allowed value (default: 0).\n * - `max` (number): Maximum allowed value (default: 100).\n * - `step` (number): Step granularity for value changes (optional).\n * - `stepClick` (number): Amount to increment/decrement when clicking icon buttons (default: 10).\n * - `variant` (ObcSliderVariant): Visual/interaction style (`normal`, `enhanced`, `no-input`). Default: `normal`.\n * - `hasLeftIcon`/`hasRightIcon` (boolean): Show icon button on left/right.\n * - `allowSeeking` (boolean): Enables animated seeking to clicked value on the track.\n * - `seekingSpeed` (number): Animation speed for seeking (default: 1/3; higher is faster).\n * - `hugcontainer` (attribute): Removes spacing between slider and icon buttons for a compact layout.\n *\n * ---\n *\n * ### Events\n * - `value` – Fired continuously when the slider value changes during user interaction or programmatically. The event detail contains the new value as a number.\n * - `change` – Fired only after user interaction completes (mouse/touch release or button click). The event detail contains the new value as a number.\n *\n * ---\n *\n * ### Best Practices & Constraints\n * - Only use `no-input` variant for read-only display; interactive controls should use `normal` or `enhanced`.\n * - For accessibility, ensure the slider has a visible label or context.\n * - Use step values that make sense for the range (e.g., avoid step=0.01 for a 0–10 range unless fine granularity is needed).\n * - When using icon buttons, provide icons that clearly indicate their function.\n * - The slider is horizontal only; for vertical sliders, use a different component.\n *\n * ---\n *\n * ### Example\n *\n * ```html\n * <obc-slider\n * value=\"40\"\n * min=\"0\"\n * max=\"100\"\n * step=\"10\"\n * haslefticon\n * hasrighticon\n * variant=\"enhanced\"\n * >\n * <obi-arrow slot=\"icon-left\"></obi-arrow>\n * <obi-arrow slot=\"icon-right\"></obi-arrow>\n * </obc-slider>\n * ```\n *\n * In this example, the slider allows selection from 0 to 100 in steps of 10, with left/right arrow icons for quick adjustments.\n *\n * @slot icon-left - Slot for the left icon button (shown when `hasLeftIcon` is true)\n * @slot icon-right - Slot for the right icon button (shown when `hasRightIcon` is true)\n * @attr hugcontainer - If set, the slider will not have any spacing between the slider icons and the container\n * @fires {ObcSliderValueEvent} value - Fired when the value is changed\n * @fires {ObcSliderChangeEvent} change - Fired when user interaction completes; dispatched on release even if the value did not change\n * @stable\n */\n@customElement('obc-slider')\nexport class ObcSlider extends LitElement {\n /**\n * The current value of the slider.\n *\n * Updates as the user drags the thumb, clicks the track (if `allowSeeking`), or uses the increment/decrement buttons.\n */\n @property({type: Number}) value = 50;\n\n /**\n * The minimum allowed value for the slider.\n *\n * Default is 0.\n */\n @property({type: Number}) min = 0;\n\n /**\n * The maximum allowed value for the slider.\n *\n * Default is 100.\n */\n @property({type: Number}) max = 100;\n\n /**\n * The step granularity for slider value changes.\n *\n * If set, the slider will snap to multiples of this value between min and max.\n * Optional; if not set, the slider is continuous.\n */\n @property({type: Number}) step: number | undefined;\n\n /**\n * The amount to increment or decrement the value when clicking the left/right icon buttons.\n *\n * Default is 10.\n * @availableWhen hasLeftIcon==true || hasRightIcon==true\n */\n @property({type: Number}) stepClick = 10;\n\n /**\n * The visual and interaction style of the slider.\n *\n * - `normal`: Standard appearance.\n * - `enhanced`: Larger track and thumb for emphasis.\n * - `no-input`: Read-only; disables all user input.\n *\n * Default is `normal`.\n */\n @property({type: String}) variant: ObcSliderVariant = ObcSliderVariant.Normal;\n\n /**\n * Whether to display a left icon button for decrementing the value.\n *\n * When true, the `icon-left` slot is rendered as a button.\n */\n @property({type: Boolean}) hasLeftIcon = false;\n\n /**\n * Whether to display a right icon button for incrementing the value.\n *\n * When true, the `icon-right` slot is rendered as a button.\n */\n @property({type: Boolean}) hasRightIcon = false;\n\n /**\n * Enables animated seeking: clicking or dragging along the track will set the value to the clicked position, animating smoothly.\n *\n * Default is false.\n * @availableWhen variant!=no-input && disabled==false\n */\n @property({type: Boolean}) allowSeeking = false;\n\n /**\n * The speed of the smooth animation that moves the value to the clicked position (used when `allowSeeking` is false).\n *\n * Expressed as the inverse of seconds to go from min to max (e.g., 1/3 means 3 seconds for full range).\n * Default is 1/3.\n * @availableWhen allowSeeking==false && variant!=no-input && disabled==false\n */\n @property({type: Number}) seekingSpeed = 1 / 3;\n\n @property({type: Boolean}) disabled = false;\n\n private get ratio(): number {\n const range = this.max - this.min;\n if (!Number.isFinite(range) || range <= 0) return 0;\n const ratio = (this.value - this.min) / range;\n if (!Number.isFinite(ratio)) return 0;\n return Math.max(0, Math.min(1, ratio));\n }\n\n private animationFrame: number | null = null;\n private isMouseDown = false;\n private isTouchActive = false;\n private targetValue = 0;\n private isDragging = false;\n private animationStartTime: number | null = null;\n private animationStartValue: number = 0;\n\n /**\n * Handles input changes from the slider or buttons.\n * Fires the `value` event with the new value.\n *\n * @param value - The new value to set.\n * @fires value\n */\n onInput(value: number) {\n this.value = value;\n this.dispatchEvent(new CustomEvent('value', {detail: this.value}));\n }\n\n /**\n * Fires the `change` event with the current value.\n *\n * @fires change\n */\n private fireChangeEvent() {\n this.dispatchEvent(\n new CustomEvent('change', {detail: this.value}) as ObcSliderChangeEvent\n );\n }\n\n /**\n * Decrements the value by `stepClick` when the left icon button is clicked.\n */\n onReduceClick() {\n if (this.disabled) return;\n this.onInput(Math.max(this.value - this.stepClick, this.min));\n this.fireChangeEvent();\n }\n\n /**\n * Increments the value by `stepClick` when the right icon button is clicked.\n */\n onIncreaseClick() {\n if (this.disabled) return;\n this.onInput(Math.min(this.value + this.stepClick, this.max));\n this.fireChangeEvent();\n }\n\n private get slider(): HTMLInputElement {\n return this.renderRoot.querySelector('input[type=\"range\"]')!;\n }\n\n private isClickingThumb(e: MouseEvent | TouchEvent) {\n const rect = this.slider.getBoundingClientRect();\n const left = rect.left + 24;\n const width = rect.width - 48;\n const thumbWidth = 48;\n const ratioValue = this.ratio;\n const thumbCenter = left + width * ratioValue;\n\n let clientX: number;\n if ('touches' in e) {\n clientX = e.touches[0].clientX;\n } else {\n clientX = e.clientX;\n }\n\n const isNearThumb = Math.abs(clientX - thumbCenter) <= thumbWidth / 2;\n return isNearThumb;\n }\n\n private onMouseDown(e: MouseEvent) {\n if (this.variant === ObcSliderVariant.NoInput || this.disabled) return;\n if (this.isClickingThumb(e)) return;\n this.isMouseDown = true;\n this.updateTargetValue(e);\n e.preventDefault();\n window.addEventListener('mousemove', this.onWindowMouseMove);\n window.addEventListener('mouseup', this.onWindowMouseUp);\n this.startAnimation();\n }\n\n private onTouchStart(e: TouchEvent) {\n if (this.variant === ObcSliderVariant.NoInput || this.disabled) return;\n if (this.isClickingThumb(e)) return;\n this.isTouchActive = true;\n this.updateTargetValue(e);\n e.preventDefault();\n window.addEventListener('touchmove', this.onWindowTouchMove, {\n passive: false,\n });\n window.addEventListener('touchend', this.onWindowTouchEnd);\n this.startAnimation();\n }\n\n private onWindowMouseMove = (e: MouseEvent) => {\n this.onMouseMove(e);\n };\n\n private onWindowMouseUp = () => {\n this.onMouseUp();\n };\n\n private onWindowTouchMove = (e: TouchEvent) => {\n this.onTouchMove(e);\n };\n\n private onWindowTouchEnd = () => {\n this.onTouchEnd();\n };\n\n private onMouseMove(e: MouseEvent) {\n if (this.isMouseDown) {\n this.updateTargetValue(e);\n }\n }\n\n private onTouchMove(e: TouchEvent) {\n if (this.isTouchActive) {\n this.updateTargetValue(e);\n }\n }\n\n private onMouseUp() {\n this.isMouseDown = false;\n window.removeEventListener('mousemove', this.onWindowMouseMove);\n window.removeEventListener('mouseup', this.onWindowMouseUp);\n this.stopAnimation();\n this.fireChangeEvent();\n }\n\n private onTouchEnd() {\n this.isTouchActive = false;\n window.removeEventListener('touchmove', this.onWindowTouchMove);\n window.removeEventListener('touchend', this.onWindowTouchEnd);\n this.stopAnimation();\n this.fireChangeEvent();\n }\n\n private updateTargetValue(e: MouseEvent | TouchEvent) {\n const rect = this.slider.getBoundingClientRect();\n const left = rect.left + 24;\n const width = rect.width - 48;\n const x = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX;\n const percent = (x - left) / width;\n const min = parseFloat(this.slider.min);\n const max = parseFloat(this.slider.max);\n const unroundedValue = min + (max - min) * percent;\n if (this.step) {\n this.targetValue = Math.round(unroundedValue / this.step) * this.step;\n } else {\n this.targetValue = unroundedValue;\n }\n }\n\n private startAnimation() {\n this.isDragging = this.allowSeeking;\n this.animationStartTime = performance.now();\n this.animationStartValue = parseFloat(this.slider.value);\n const min = parseFloat(this.slider.min);\n const max = parseFloat(this.slider.max);\n const step = this.step;\n const duration = (1 / this.seekingSpeed) * 1000; // ms\n const direction = this.targetValue > this.animationStartValue ? 1 : -1;\n\n const animate = () => {\n let nextValue = this.targetValue;\n if (!this.isDragging) {\n const now = performance.now();\n const elapsed = now - (this.animationStartTime ?? now);\n const range = Math.abs(max - min);\n // How much of the range should be covered by now\n const expectedProgress = Math.min(elapsed / duration, 1);\n const expectedValue =\n this.animationStartValue + direction * range * expectedProgress;\n // Snap to step\n if (direction > 0) {\n nextValue =\n step === undefined\n ? expectedValue\n : Math.ceil((expectedValue - min) / step) * step + min;\n nextValue = Math.min(this.targetValue, nextValue);\n } else {\n nextValue =\n step === undefined\n ? expectedValue\n : Math.floor((expectedValue - min) / step) * step + min;\n nextValue = Math.max(this.targetValue, nextValue);\n }\n }\n // Only update if value actually changes\n if (parseFloat(this.slider.value) !== nextValue) {\n this.slider.value = String(nextValue);\n this.slider.dispatchEvent(new Event('input'));\n }\n // Continue animating if not at target\n if (\n (direction > 0 && nextValue < this.targetValue) ||\n (direction < 0 && nextValue > this.targetValue)\n ) {\n this.animationFrame = requestAnimationFrame(animate);\n } else if (this.isMouseDown || this.isTouchActive) {\n // If mouse or touch is still active, wait for new target\n this.animationStartTime = performance.now();\n this.animationStartValue = parseFloat(this.slider.value);\n this.animationFrame = requestAnimationFrame(animate);\n this.isDragging = true;\n }\n };\n\n this.animationFrame = requestAnimationFrame(animate);\n }\n\n private stopAnimation() {\n if (this.animationFrame !== null) {\n cancelAnimationFrame(this.animationFrame);\n this.animationFrame = null;\n }\n }\n\n override render() {\n return html`\n ${this.hasLeftIcon\n ? html` <obc-icon-button\n ?disabled=${this.disabled}\n @click=${this.onReduceClick}\n variant=\"normal\"\n >\n <slot name=\"icon-left\"></slot>\n </obc-icon-button>`\n : null}\n <div\n class=${classMap({\n wrapper: true,\n [this.variant]: true,\n disabled: this.disabled,\n })}\n style=${styleMap({\n '--_ratio': String(this.ratio),\n })}\n >\n <div class=\"track\"></div>\n <input\n type=\"range\"\n min=${this.min}\n max=${this.max}\n step=${ifDefined(this.step)}\n .value=${this.value.toString()}\n ?disabled=${this.variant === ObcSliderVariant.NoInput ||\n this.disabled}\n class=\"slider\"\n @input=${(event: Event) => {\n this.value = Number((event.target as HTMLInputElement).value);\n this.dispatchEvent(new CustomEvent('value', {detail: this.value}));\n }}\n @change=${() => {\n this.fireChangeEvent();\n }}\n @mousedown=${this.onMouseDown}\n @touchstart=${this.onTouchStart}\n @mousemove=${this.onMouseMove}\n @touchmove=${this.onTouchMove}\n @mouseup=${this.onMouseUp}\n @touchend=${this.onTouchEnd}\n />\n <div\n class=\"interactive-track-hover\"\n @mousedown=${this.onMouseDown}\n @touchstart=${this.onTouchStart}\n @mousemove=${this.onMouseMove}\n @touchmove=${this.onTouchMove}\n @mouseup=${this.onMouseUp}\n @touchend=${this.onTouchEnd}\n ></div>\n <div\n class=\"container-hover\"\n @mousedown=${this.onMouseDown}\n @touchstart=${this.onTouchStart}\n @mousemove=${this.onMouseMove}\n @touchmove=${this.onTouchMove}\n @mouseup=${this.onMouseUp}\n @touchend=${this.onTouchEnd}\n ></div>\n <div class=\"interactive-track\"></div>\n <div class=\"thumb\"></div>\n </div>\n ${this.hasRightIcon\n ? html`<obc-icon-button\n ?disabled=${this.disabled}\n @click=${this.onIncreaseClick}\n variant=\"normal\"\n >\n <slot name=\"icon-right\"></slot>\n </obc-icon-button>`\n : null}\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-slider': ObcSlider;\n }\n}\n"],"names":["ObcSliderVariant"],"mappings":"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"}
@@ -222,13 +222,13 @@ export declare class ObcSliderDouble extends LitElement {
222
222
  * Handles input changes from the slider thumbs.
223
223
  * Updates the low and high values and emits the `value` event.
224
224
  *
225
- * @fires {ObcSliderDoubleValueEvent} value - Fires when the value is changed
225
+ * @fires value
226
226
  */
227
227
  onInput(): void;
228
228
  /**
229
229
  * Fires the `change` event with the current low and high values.
230
230
  *
231
- * @fires change - Fires when user interaction completes
231
+ * @fires change
232
232
  */
233
233
  private fireChangeEvent;
234
234
  private THUMB_WIDTH;
@@ -73,7 +73,7 @@ let ObcSliderDouble = class extends LitElement {
73
73
  * Handles input changes from the slider thumbs.
74
74
  * Updates the low and high values and emits the `value` event.
75
75
  *
76
- * @fires {ObcSliderDoubleValueEvent} value - Fires when the value is changed
76
+ * @fires value
77
77
  */
78
78
  onInput() {
79
79
  let newLow = parseFloat(this.minInput.value);
@@ -95,7 +95,7 @@ let ObcSliderDouble = class extends LitElement {
95
95
  /**
96
96
  * Fires the `change` event with the current low and high values.
97
97
  *
98
- * @fires change - Fires when user interaction completes
98
+ * @fires change
99
99
  */
100
100
  fireChangeEvent() {
101
101
  this.dispatchEvent(