@oicl/openbridge-webcomponents 2.1.0-next.1 → 2.1.0-next.2

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 (55) hide show
  1. package/README.md +1 -0
  2. package/bundle/openbridge-webcomponents.bundle.js +352 -244
  3. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  4. package/custom-elements.json +944 -90
  5. package/dist/building-blocks/alert-list/alert-list-base.d.ts +60 -0
  6. package/dist/building-blocks/alert-list/alert-list-base.d.ts.map +1 -0
  7. package/dist/building-blocks/alert-list/alert-list-base.js +191 -0
  8. package/dist/building-blocks/alert-list/alert-list-base.js.map +1 -0
  9. package/dist/building-blocks/alert-list/alert-list.css.js.map +1 -1
  10. package/dist/building-blocks/alert-list/alert-list.d.ts +13 -26
  11. package/dist/building-blocks/alert-list/alert-list.d.ts.map +1 -1
  12. package/dist/building-blocks/alert-list/alert-list.js +7 -142
  13. package/dist/building-blocks/alert-list/alert-list.js.map +1 -1
  14. package/dist/components/alert-icon/alert-icon.d.ts.map +1 -1
  15. package/dist/components/alert-icon/alert-icon.js +6 -5
  16. package/dist/components/alert-icon/alert-icon.js.map +1 -1
  17. package/dist/components/alert-list-details/alert-list-details.css.js +4 -1
  18. package/dist/components/alert-list-details/alert-list-details.css.js.map +1 -1
  19. package/dist/components/alert-menu/alert-menu.css.js +3 -42
  20. package/dist/components/alert-menu/alert-menu.css.js.map +1 -1
  21. package/dist/components/alert-menu/alert-menu.d.ts +28 -6
  22. package/dist/components/alert-menu/alert-menu.d.ts.map +1 -1
  23. package/dist/components/alert-menu/alert-menu.js +81 -60
  24. package/dist/components/alert-menu/alert-menu.js.map +1 -1
  25. package/dist/components/alert-menu-item/alert-menu-item.d.ts +16 -6
  26. package/dist/components/alert-menu-item/alert-menu-item.d.ts.map +1 -1
  27. package/dist/components/alert-menu-item/alert-menu-item.js +11 -2
  28. package/dist/components/alert-menu-item/alert-menu-item.js.map +1 -1
  29. package/dist/components/number-input-field/number-input-field.css.js +8 -2
  30. package/dist/components/number-input-field/number-input-field.css.js.map +1 -1
  31. package/dist/components/number-input-field/number-input-field.d.ts +15 -1
  32. package/dist/components/number-input-field/number-input-field.d.ts.map +1 -1
  33. package/dist/components/number-input-field/number-input-field.js +38 -44
  34. package/dist/components/number-input-field/number-input-field.js.map +1 -1
  35. package/dist/components/textbox/textbox.css.js +3 -9
  36. package/dist/components/textbox/textbox.css.js.map +1 -1
  37. package/dist/components/textbox/textbox.d.ts +3 -0
  38. package/dist/components/textbox/textbox.d.ts.map +1 -1
  39. package/dist/components/textbox/textbox.js.map +1 -1
  40. package/dist/generated/locales/es-419.d.ts +1 -1
  41. package/dist/generated/locales/es-419.js +1 -1
  42. package/dist/generated/locales/es-419.js.map +1 -1
  43. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +2 -1
  44. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
  45. package/dist/pages/alert-detail-page/alert-detail-page.js +1 -1
  46. package/dist/pages/alert-detail-page/alert-detail-page.js.map +1 -1
  47. package/dist/pages/alert-list-page-small/alert-list-page-small-base.d.ts +63 -0
  48. package/dist/pages/alert-list-page-small/alert-list-page-small-base.d.ts.map +1 -0
  49. package/dist/pages/alert-list-page-small/alert-list-page-small-base.js +126 -0
  50. package/dist/pages/alert-list-page-small/alert-list-page-small-base.js.map +1 -0
  51. package/dist/pages/alert-list-page-small/alert-list-page-small.d.ts +12 -15
  52. package/dist/pages/alert-list-page-small/alert-list-page-small.d.ts.map +1 -1
  53. package/dist/pages/alert-list-page-small/alert-list-page-small.js +41 -92
  54. package/dist/pages/alert-list-page-small/alert-list-page-small.js.map +1 -1
  55. package/package.json +1 -1
@@ -11,7 +11,8 @@ export declare enum ObcAlertMenuItemStatus {
11
11
  Acknowledged = "acknowledged",
12
12
  NoAckAlarm = "no-ack-alarm",
13
13
  NoAckWarning = "no-ack-warning",
14
- Rectified = "rectified"
14
+ Rectified = "rectified",
15
+ RectifiedUnacknowledged = "rectified-unacknowledged"
15
16
  }
16
17
  /**
17
18
  * Appearance of an alert menu item action.
@@ -32,12 +33,13 @@ export declare enum ObcAlertMenuItemActionState {
32
33
  * ### Features
33
34
  * - **Status Variants:** Supports multiple alert states via the `status` property:
34
35
  * - **Unacknowledged:** Shows an action button (ACK) for user acknowledgment.
36
+ * - **RectifiedUnacknowledged:** The situation that raised the alert has cleared, but the alert still waits for acknowledgment, so the ACK action stays.
35
37
  * - **Caution, Acknowledged, Rectified:** Display different visual cues for alert progression.
36
38
  * - **NoAckAlarm / NoAckWarning:** Show special icons indicating unacknowledged alarms or warnings.
37
39
  * - **Icon Support:** Optional secondary icon (e.g., system or source) and a primary alert icon. Tertiary "shelved" icon appears if the alert is shelved.
38
40
  * - **Time and Day Display:** Optionally shows day and/or time for the alert occurrence.
39
41
  * - **Expandable:** Can be toggled open/closed for additional details (via click).
40
- * - **Action Buttons:** Displays an "ACK" button for unacknowledged alerts and an optional secondary action (label set via `secondaryActionLabel`); each triggers an event when clicked.
42
+ * - **Action Buttons:** Displays an "ACK" button for the statuses that still wait for acknowledgment (`unacknowledged` and `rectified-unacknowledged`) and an optional secondary action (label set via `secondaryActionLabel`); each triggers an event when clicked.
41
43
  * - Each action's appearance is controlled independently via `primaryActionState` / `secondaryActionState` (`enabled`, `disabled`, or `none`).
42
44
  * - **Animated Intro:** Optional animation when the item appears.
43
45
  * - **Size Options:** Supports single-line or multi-line layouts (see `size` property).
@@ -51,7 +53,9 @@ export declare enum ObcAlertMenuItemActionState {
51
53
  * - Only show the "ACK" action for alerts that require acknowledgment.
52
54
  * - Provide `secondaryActionLabel` to add a second action alongside ACK.
53
55
  * - Use `primaryActionState` / `secondaryActionState` to temporarily disable an action (`disabled`) or remove it without leaving a gap (`none`).
54
- * - Use the `shelved` property to indicate alerts that are temporarily deferred.
56
+ * - Use the `shelved` property to indicate alerts that are temporarily deferred, and `blocked` for alerts another system has set aside. The alert menus sort items into their tabs by `status` and `shelved`; `blocked` is there for menus that list blocked alerts apart.
57
+ *
58
+ * **TODO(designer):** Should a blocked alert show a marker, as a shelved one shows the shelf icon?
55
59
  *
56
60
  * ### Slots
57
61
  * | Slot Name | Renders When... | Purpose |
@@ -91,13 +95,16 @@ export declare enum ObcAlertMenuItemActionState {
91
95
  * When true, the `icon` slot is rendered.
92
96
  * @property shelved - Indicates if the alert is shelved (temporarily deferred).
93
97
  * When true, a tertiary icon is shown to represent the shelved state.
98
+ * @property blocked - Indicates that another system has blocked the alert as not relevant here.
99
+ * For menus that list blocked alerts apart; the item itself shows no marker for it yet.
94
100
  * @property title - The title of the alert.
95
101
  * @property description - The description of the alert.
96
102
  * @property day - The day label for the alert (e.g., "Yesterday").
97
103
  * @property time - The time label for the alert (e.g., "14:30").
98
104
  * @property status - The current status of the alert item.
99
105
  * Determines visual style, icon, and action button visibility.
100
- * Possible values: 'unacknowledged', 'caution', 'acknowledged', 'no-ack-alarm', 'no-ack-warning', 'rectified'.
106
+ * Possible values: 'unacknowledged', 'caution', 'acknowledged', 'no-ack-alarm', 'no-ack-warning', 'rectified', 'rectified-unacknowledged'.
107
+ * 'unacknowledged' and 'rectified-unacknowledged' show the ACK action; the other values show a trailing icon instead.
101
108
  * Default is 'unacknowledged'.
102
109
  * @property open - Whether the item is expanded/open to show additional details.
103
110
  * Toggled by clicking the item.
@@ -130,6 +137,8 @@ export declare class ObcAlertMenuItem extends LitElement {
130
137
  hasIcon: boolean;
131
138
  /** Indicates if the alert is shelved (temporarily deferred). When true, a tertiary icon is shown to represent the shelved state. */
132
139
  shelved: boolean;
140
+ /** Indicates that another system has blocked the alert as not relevant here. For menus that list blocked alerts apart; the item itself shows no marker for it yet. */
141
+ blocked: boolean;
133
142
  /** The title of the alert. */
134
143
  title: string;
135
144
  /** The description of the alert. */
@@ -138,7 +147,7 @@ export declare class ObcAlertMenuItem extends LitElement {
138
147
  day: string;
139
148
  /** The time label for the alert (e.g., "14:30"). */
140
149
  time: string;
141
- /** The current status of the alert item. Determines visual style, icon, and action button visibility. Possible values: 'unacknowledged', 'caution', 'acknowledged', 'no-ack-alarm', 'no-ack-warning', 'rectified'. Default is 'unacknowledged'. */
150
+ /** The current status of the alert item. Determines visual style, icon, and action button visibility. Possible values: 'unacknowledged', 'caution', 'acknowledged', 'no-ack-alarm', 'no-ack-warning', 'rectified', 'rectified-unacknowledged'. 'unacknowledged' and 'rectified-unacknowledged' show the ACK action; the other values show a trailing icon instead. Default is 'unacknowledged'. */
142
151
  status: ObcAlertMenuItemStatus;
143
152
  /** Whether the item is expanded/open to show additional details. Toggled by clicking the item. */
144
153
  open: boolean;
@@ -152,6 +161,7 @@ export declare class ObcAlertMenuItem extends LitElement {
152
161
  primaryActionState: ObcAlertMenuItemActionState;
153
162
  /** Appearance of the secondary action: `enabled`, `disabled` or `none`, which hides it. */
154
163
  secondaryActionState: ObcAlertMenuItemActionState;
164
+ private get canAck();
155
165
  private get primaryActionLabel();
156
166
  private get secondaryActionLabelToShow();
157
167
  private get primaryActionDisabled();
@@ -165,7 +175,7 @@ export declare class ObcAlertMenuItem extends LitElement {
165
175
  }
166
176
  declare global {
167
177
  interface HTMLElementTagNameMap {
168
- 'ob-alert-menu-item': ObcAlertMenuItem;
178
+ 'obc-alert-menu-item': ObcAlertMenuItem;
169
179
  }
170
180
  }
171
181
  //# sourceMappingURL=alert-menu-item.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"alert-menu-item.d.ts","sourceRoot":"","sources":["../../../src/components/alert-menu-item/alert-menu-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,2CAA2C,CAAC;AACnD,OAAO,6BAA6B,CAAC;AACrC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,uCAAuC,CAAC;AAC/C,OAAO,EAAC,sBAAsB,EAAC,MAAM,2CAA2C,CAAC;AAGjF,oBAAY,sBAAsB;IAChC,cAAc,mBAAmB;IACjC,OAAO,YAAY;IACnB,YAAY,iBAAiB;IAC7B,UAAU,iBAAiB;IAC3B,YAAY,mBAAmB;IAC/B,SAAS,cAAc;CACxB;AAED;;;;;GAKG;AACH,oBAAY,2BAA2B;IACrC,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,IAAI,SAAS;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoGG;AACH,qBACa,gBAAiB,SAAQ,UAAU;IACnB,OAAO,UAAS;IAED,OAAO,UAAS;IAEvB,KAAK,SAAM;IAEpB,WAAW,SAAM;IAEjB,GAAG,SAAM;IAET,IAAI,SAAM;IAEK,MAAM,yBACP;IAEb,IAAI,UAAS;IAEd,IAAI,EAAE,sBAAsB,CAClB;IAET,YAAY,UAAS;IAEtB,oBAAoB,SAAM;IAE1B,kBAAkB,EAAE,2BAA2B,CACnC;IAEZ,oBAAoB,EAAE,2BAA2B,CACxC;IAEnC,OAAO,KAAK,kBAAkB,GAK7B;IAED,OAAO,KAAK,0BAA0B,GAKrC;IAED,OAAO,KAAK,qBAAqB,GAEhC;IAED,OAAO,KAAK,uBAAuB,GAElC;IAED,OAAO,KAAK,eAAe,GAG1B;IAED,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,0BAA0B;IAKzB,MAAM;IAoDf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,oBAAoB,EAAE,gBAAgB,CAAC;KACxC;CACF"}
1
+ {"version":3,"file":"alert-menu-item.d.ts","sourceRoot":"","sources":["../../../src/components/alert-menu-item/alert-menu-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,2CAA2C,CAAC;AACnD,OAAO,6BAA6B,CAAC;AACrC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,uCAAuC,CAAC;AAC/C,OAAO,EAAC,sBAAsB,EAAC,MAAM,2CAA2C,CAAC;AAGjF,oBAAY,sBAAsB;IAChC,cAAc,mBAAmB;IACjC,OAAO,YAAY;IACnB,YAAY,iBAAiB;IAC7B,UAAU,iBAAiB;IAC3B,YAAY,mBAAmB;IAC/B,SAAS,cAAc;IACvB,uBAAuB,6BAA6B;CACrD;AAED;;;;;GAKG;AACH,oBAAY,2BAA2B;IACrC,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,IAAI,SAAS;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AACH,qBACa,gBAAiB,SAAQ,UAAU;IACnB,OAAO,UAAS;IAED,OAAO,UAAS;IAEhB,OAAO,UAAS;IAEvB,KAAK,SAAM;IAEpB,WAAW,SAAM;IAEjB,GAAG,SAAM;IAET,IAAI,SAAM;IAEK,MAAM,yBACP;IAEb,IAAI,UAAS;IAEd,IAAI,EAAE,sBAAsB,CAClB;IAET,YAAY,UAAS;IAEtB,oBAAoB,SAAM;IAE1B,kBAAkB,EAAE,2BAA2B,CACnC;IAEZ,oBAAoB,EAAE,2BAA2B,CACxC;IAEnC,OAAO,KAAK,MAAM,GAKjB;IAED,OAAO,KAAK,kBAAkB,GAK7B;IAED,OAAO,KAAK,0BAA0B,GAKrC;IAED,OAAO,KAAK,qBAAqB,GAEhC;IAED,OAAO,KAAK,uBAAuB,GAElC;IAED,OAAO,KAAK,eAAe,GAG1B;IAED,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,0BAA0B;IAKzB,MAAM;IAoDf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,qBAAqB,EAAE,gBAAgB,CAAC;KACzC;CACF"}
@@ -17,6 +17,7 @@ var ObcAlertMenuItemStatus = /* @__PURE__ */ function(ObcAlertMenuItemStatus) {
17
17
  ObcAlertMenuItemStatus["NoAckAlarm"] = "no-ack-alarm";
18
18
  ObcAlertMenuItemStatus["NoAckWarning"] = "no-ack-warning";
19
19
  ObcAlertMenuItemStatus["Rectified"] = "rectified";
20
+ ObcAlertMenuItemStatus["RectifiedUnacknowledged"] = "rectified-unacknowledged";
20
21
  return ObcAlertMenuItemStatus;
21
22
  }({});
22
23
  /**
@@ -36,6 +37,7 @@ var ObcAlertMenuItem = class ObcAlertMenuItem extends LitElement {
36
37
  super(..._args);
37
38
  this.hasIcon = false;
38
39
  this.shelved = false;
40
+ this.blocked = false;
39
41
  this.title = "";
40
42
  this.description = "";
41
43
  this.day = "";
@@ -48,9 +50,12 @@ var ObcAlertMenuItem = class ObcAlertMenuItem extends LitElement {
48
50
  this.primaryActionState = "enabled";
49
51
  this.secondaryActionState = "none";
50
52
  }
53
+ get canAck() {
54
+ return this.status === "unacknowledged" || this.status === "rectified-unacknowledged";
55
+ }
51
56
  get primaryActionLabel() {
52
57
  if (this.primaryActionState === "none") return "";
53
- return this.status === "unacknowledged" ? "ACK" : "";
58
+ return this.canAck ? "ACK" : "";
54
59
  }
55
60
  get secondaryActionLabelToShow() {
56
61
  if (this.secondaryActionState === "none") return "";
@@ -63,7 +68,7 @@ var ObcAlertMenuItem = class ObcAlertMenuItem extends LitElement {
63
68
  return this.secondaryActionState === "disabled";
64
69
  }
65
70
  get hasTrailingIcon() {
66
- return this.status !== "unacknowledged";
71
+ return !this.canAck;
67
72
  }
68
73
  handleMessageClick(event) {
69
74
  event.stopPropagation();
@@ -123,6 +128,10 @@ __decorate([property({
123
128
  type: Boolean,
124
129
  reflect: true
125
130
  })], ObcAlertMenuItem.prototype, "shelved", void 0);
131
+ __decorate([property({
132
+ type: Boolean,
133
+ reflect: true
134
+ })], ObcAlertMenuItem.prototype, "blocked", void 0);
126
135
  __decorate([property({ type: String })], ObcAlertMenuItem.prototype, "title", void 0);
127
136
  __decorate([property({ type: String })], ObcAlertMenuItem.prototype, "description", void 0);
128
137
  __decorate([property({ type: String })], ObcAlertMenuItem.prototype, "day", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"alert-menu-item.js","names":[],"sources":["../../../src/components/alert-menu-item/alert-menu-item.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {choose} from 'lit/directives/choose.js';\n\nimport compentStyle from './alert-menu-item.css?inline';\nimport '../message-menu-item/message-menu-item.js';\nimport '../alert-icon/alert-icon.js';\nimport '../../icons/icon-alerts-shelf.js';\nimport '../../icons/icon-alarm-noack-iec.js';\nimport '../../icons/icon-warning-noack-iec.js';\nimport {ObcMessageMenuItemSize} from '../message-menu-item/message-menu-item.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum ObcAlertMenuItemStatus {\n Unacknowledged = 'unacknowledged',\n Caution = 'caution',\n Acknowledged = 'acknowledged',\n NoAckAlarm = 'no-ack-alarm',\n NoAckWarning = 'no-ack-warning',\n Rectified = 'rectified',\n}\n\n/**\n * Appearance of an alert menu item action.\n * - `enabled`: Action is shown and interactive (default).\n * - `disabled`: Action is shown but cannot be triggered.\n * - `none`: Action is removed and takes no space.\n */\nexport enum ObcAlertMenuItemActionState {\n Enabled = 'enabled',\n Disabled = 'disabled',\n None = 'none',\n}\n\n/**\n * `<obc-alert-menu-item>` – A list item component for displaying alert or notification entries with status, icons, and action controls.\n *\n * Presents a concise summary of an alert or message, including status, title, description, and optional icons. Designed for use in alert menus, notification drawers, or similar lists where users need to review and acknowledge alerts efficiently.\n *\n * ### Features\n * - **Status Variants:** Supports multiple alert states via the `status` property:\n * - **Unacknowledged:** Shows an action button (ACK) for user acknowledgment.\n * - **Caution, Acknowledged, Rectified:** Display different visual cues for alert progression.\n * - **NoAckAlarm / NoAckWarning:** Show special icons indicating unacknowledged alarms or warnings.\n * - **Icon Support:** Optional secondary icon (e.g., system or source) and a primary alert icon. Tertiary \"shelved\" icon appears if the alert is shelved.\n * - **Time and Day Display:** Optionally shows day and/or time for the alert occurrence.\n * - **Expandable:** Can be toggled open/closed for additional details (via click).\n * - **Action Buttons:** Displays an \"ACK\" button for unacknowledged alerts and an optional secondary action (label set via `secondaryActionLabel`); each triggers an event when clicked.\n * - Each action's appearance is controlled independently via `primaryActionState` / `secondaryActionState` (`enabled`, `disabled`, or `none`).\n * - **Animated Intro:** Optional animation when the item appears.\n * - **Size Options:** Supports single-line or multi-line layouts (see `size` property).\n *\n * ### Usage Guidelines\n * Use `obc-alert-menu-item` to represent individual alerts or notifications in a menu, list, or notification center. Ideal for scenarios where users need to quickly scan, identify, and acknowledge alerts. The component is best suited for transient or actionable notifications rather than persistent banners.\n *\n * - Use the `status` property to reflect the current state of the alert.\n * - Provide a relevant icon in the `alert-icon` slot to visually indicate the alert type.\n * - Use the `icon` slot for a source/system icon if needed.\n * - Only show the \"ACK\" action for alerts that require acknowledgment.\n * - Provide `secondaryActionLabel` to add a second action alongside ACK.\n * - Use `primaryActionState` / `secondaryActionState` to temporarily disable an action (`disabled`) or remove it without leaving a gap (`none`).\n * - Use the `shelved` property to indicate alerts that are temporarily deferred.\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |---------------|-------------------------------|------------------------------------------------------|\n * | alert-icon | Always | Main alert icon representing the alert type. |\n * | title | Always | Title content; falls back to the `title` property. |\n * | description | Always | Description content; falls back to the `description` property. |\n * | icon | If `hasIcon` is true | Secondary icon (e.g., system/source of alert). |\n *\n * ### Events\n * - **ack-click** – Fired when the ACK action button is clicked.\n * - **ack-secondary-click** – Fired when the secondary action button is clicked.\n * - **item-click** – Fired when the alert menu item is clicked (toggles open/closed).\n *\n * ### Best Practices\n * - Only display the ACK action for alerts that require acknowledgment.\n * - Use concise titles and descriptions for quick scanning.\n * - For grouped alerts, ensure each item has a unique status and icon as appropriate.\n * - Avoid overloading with too many icons; use secondary and tertiary icons only when necessary.\n * - Follow standard notification design guidelines: keep actionable items prominent, and use color/iconography to indicate severity or status.\n *\n * **Example:**\n * ```\n * <obc-alert-menu-item\n * status=\"unacknowledged\"\n * title=\"Engine Temperature High\"\n * description=\"Port main engine temperature exceeds normal operating range\"\n * time=\"14:30\"\n * hasIcon\n * >\n * <obc-alert-icon slot=\"alert-icon\" type=\"alarm\" active></obc-alert-icon>\n * <obi-engine slot=\"icon\"></obi-engine>\n * </obc-alert-menu-item>\n * ```\n *\n * @property hasIcon - Whether to display a secondary icon (e.g., system/source) in the item.\n * When true, the `icon` slot is rendered.\n * @property shelved - Indicates if the alert is shelved (temporarily deferred).\n * When true, a tertiary icon is shown to represent the shelved state.\n * @property title - The title of the alert.\n * @property description - The description of the alert.\n * @property day - The day label for the alert (e.g., \"Yesterday\").\n * @property time - The time label for the alert (e.g., \"14:30\").\n * @property status - The current status of the alert item.\n * Determines visual style, icon, and action button visibility.\n * Possible values: 'unacknowledged', 'caution', 'acknowledged', 'no-ack-alarm', 'no-ack-warning', 'rectified'.\n * Default is 'unacknowledged'.\n * @property open - Whether the item is expanded/open to show additional details.\n * Toggled by clicking the item.\n * @property size - Layout size of the menu item.\n * Controls whether content is single-line or multi-line.\n * Possible values: 'single-line', 'multi-line'.\n * Default is 'single-line'.\n * @property animateIntro - Whether to animate the item's appearance (intro animation).\n * @property secondaryActionLabel - The label for the secondary action button.\n * Unlike the primary (ACK) action, the secondary label is not derived from\n * `status`; it must be provided explicitly. The secondary action is only\n * shown when a non-empty label is set and `secondaryActionState` is not\n * `none`.\n * @property primaryActionState - Appearance of the primary (ACK) action: `enabled`, `disabled` or `none`,\n * which hides it.\n * @property secondaryActionState - Appearance of the secondary action: `enabled`, `disabled` or `none`, which\n * hides it.\n * @slot alert-icon - The main alert icon representing the alert type.\n * @slot title - Title content; falls back to the `title` property when empty.\n * @slot description - Description content; falls back to the `description` property when empty.\n * @slot icon - Optional secondary icon (e.g., source/system).\n *\n * @fires {CustomEvent<void>} ack-click - Fired when the ACK action button is clicked.\n * @fires {CustomEvent<void>} ack-secondary-click - Fired when the secondary action button is clicked.\n * @fires {CustomEvent<void>} item-click - Fired when the alert menu item is clicked.\n * @stable\n */\n@customElement('obc-alert-menu-item')\nexport class ObcAlertMenuItem extends LitElement {\n @property({type: Boolean}) hasIcon = false;\n\n @property({type: Boolean, reflect: true}) shelved = false;\n\n @property({type: String}) override title = '';\n\n @property({type: String}) description = '';\n\n @property({type: String}) day = '';\n\n @property({type: String}) time = '';\n\n @property({type: String, reflect: true}) status =\n ObcAlertMenuItemStatus.Unacknowledged;\n\n @property({type: Boolean}) open = false;\n\n @property({type: String}) size: ObcMessageMenuItemSize =\n ObcMessageMenuItemSize.SingleLine;\n\n @property({type: Boolean}) animateIntro = false;\n\n @property({type: String}) secondaryActionLabel = '';\n\n @property({type: String}) primaryActionState: ObcAlertMenuItemActionState =\n ObcAlertMenuItemActionState.Enabled;\n\n @property({type: String}) secondaryActionState: ObcAlertMenuItemActionState =\n ObcAlertMenuItemActionState.None;\n\n private get primaryActionLabel() {\n if (this.primaryActionState === ObcAlertMenuItemActionState.None) {\n return '';\n }\n return this.status === ObcAlertMenuItemStatus.Unacknowledged ? 'ACK' : '';\n }\n\n private get secondaryActionLabelToShow() {\n if (this.secondaryActionState === ObcAlertMenuItemActionState.None) {\n return '';\n }\n return this.secondaryActionLabel;\n }\n\n private get primaryActionDisabled() {\n return this.primaryActionState === ObcAlertMenuItemActionState.Disabled;\n }\n\n private get secondaryActionDisabled() {\n return this.secondaryActionState === ObcAlertMenuItemActionState.Disabled;\n }\n\n private get hasTrailingIcon() {\n // True when we need the action container but don't have an ACK button\n return this.status !== ObcAlertMenuItemStatus.Unacknowledged;\n }\n\n private handleMessageClick(event: Event) {\n event.stopPropagation();\n this.dispatchEvent(new CustomEvent('item-click'));\n this.open = !this.open;\n }\n\n private handleActionClick(event: Event) {\n event.stopPropagation();\n this.dispatchEvent(new CustomEvent('ack-click'));\n }\n\n private handleSecondaryActionClick(event: Event) {\n event.stopPropagation();\n this.dispatchEvent(new CustomEvent('ack-secondary-click'));\n }\n\n override render() {\n return html`\n <obc-message-menu-item\n .title=${this.title}\n .description=${this.description}\n .day=${this.day}\n .time=${this.time}\n .primaryActionLabel=${this.primaryActionLabel}\n .secondaryActionLabel=${this.secondaryActionLabelToShow}\n .enablePrimaryAction=${!this.primaryActionDisabled}\n .enableSecondaryAction=${!this.secondaryActionDisabled}\n .size=${this.size}\n .open=${this.open}\n .hasSecondaryIcon=${this.hasIcon}\n .isShelved=${this.shelved}\n .hasTrailingIcon=${this.hasTrailingIcon}\n enhancedIcon\n hasPrimaryIcon\n @message-click=${this.handleMessageClick}\n @primary-action-click=${this.handleActionClick}\n @secondary-action-click=${this.handleSecondaryActionClick}\n >\n <slot name=\"alert-icon\" slot=\"primary-icon\"></slot>\n <slot name=\"title\" slot=\"title\">${this.title}</slot>\n <slot name=\"description\" slot=\"description\">${this.description}</slot>\n ${\n this.hasIcon\n ? html`<slot name=\"icon\" slot=\"secondary-icon\"></slot>`\n : nothing\n }\n ${choose(this.status, [\n [\n ObcAlertMenuItemStatus.NoAckAlarm,\n () =>\n html`<obi-alarm-noack-iec\n slot=\"trailing-icon\"\n useCssColor\n ></obi-alarm-noack-iec>`,\n ],\n [\n ObcAlertMenuItemStatus.NoAckWarning,\n () =>\n html`<obi-warning-noack-iec\n slot=\"trailing-icon\"\n useCssColor\n ></obi-warning-noack-iec>`,\n ],\n ])}\n </obc-message-menu-item>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ob-alert-menu-item': ObcAlertMenuItem;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"alert-menu-item.js","names":[],"sources":["../../../src/components/alert-menu-item/alert-menu-item.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {choose} from 'lit/directives/choose.js';\n\nimport compentStyle from './alert-menu-item.css?inline';\nimport '../message-menu-item/message-menu-item.js';\nimport '../alert-icon/alert-icon.js';\nimport '../../icons/icon-alerts-shelf.js';\nimport '../../icons/icon-alarm-noack-iec.js';\nimport '../../icons/icon-warning-noack-iec.js';\nimport {ObcMessageMenuItemSize} from '../message-menu-item/message-menu-item.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum ObcAlertMenuItemStatus {\n Unacknowledged = 'unacknowledged',\n Caution = 'caution',\n Acknowledged = 'acknowledged',\n NoAckAlarm = 'no-ack-alarm',\n NoAckWarning = 'no-ack-warning',\n Rectified = 'rectified',\n RectifiedUnacknowledged = 'rectified-unacknowledged',\n}\n\n/**\n * Appearance of an alert menu item action.\n * - `enabled`: Action is shown and interactive (default).\n * - `disabled`: Action is shown but cannot be triggered.\n * - `none`: Action is removed and takes no space.\n */\nexport enum ObcAlertMenuItemActionState {\n Enabled = 'enabled',\n Disabled = 'disabled',\n None = 'none',\n}\n\n/**\n * `<obc-alert-menu-item>` – A list item component for displaying alert or notification entries with status, icons, and action controls.\n *\n * Presents a concise summary of an alert or message, including status, title, description, and optional icons. Designed for use in alert menus, notification drawers, or similar lists where users need to review and acknowledge alerts efficiently.\n *\n * ### Features\n * - **Status Variants:** Supports multiple alert states via the `status` property:\n * - **Unacknowledged:** Shows an action button (ACK) for user acknowledgment.\n * - **RectifiedUnacknowledged:** The situation that raised the alert has cleared, but the alert still waits for acknowledgment, so the ACK action stays.\n * - **Caution, Acknowledged, Rectified:** Display different visual cues for alert progression.\n * - **NoAckAlarm / NoAckWarning:** Show special icons indicating unacknowledged alarms or warnings.\n * - **Icon Support:** Optional secondary icon (e.g., system or source) and a primary alert icon. Tertiary \"shelved\" icon appears if the alert is shelved.\n * - **Time and Day Display:** Optionally shows day and/or time for the alert occurrence.\n * - **Expandable:** Can be toggled open/closed for additional details (via click).\n * - **Action Buttons:** Displays an \"ACK\" button for the statuses that still wait for acknowledgment (`unacknowledged` and `rectified-unacknowledged`) and an optional secondary action (label set via `secondaryActionLabel`); each triggers an event when clicked.\n * - Each action's appearance is controlled independently via `primaryActionState` / `secondaryActionState` (`enabled`, `disabled`, or `none`).\n * - **Animated Intro:** Optional animation when the item appears.\n * - **Size Options:** Supports single-line or multi-line layouts (see `size` property).\n *\n * ### Usage Guidelines\n * Use `obc-alert-menu-item` to represent individual alerts or notifications in a menu, list, or notification center. Ideal for scenarios where users need to quickly scan, identify, and acknowledge alerts. The component is best suited for transient or actionable notifications rather than persistent banners.\n *\n * - Use the `status` property to reflect the current state of the alert.\n * - Provide a relevant icon in the `alert-icon` slot to visually indicate the alert type.\n * - Use the `icon` slot for a source/system icon if needed.\n * - Only show the \"ACK\" action for alerts that require acknowledgment.\n * - Provide `secondaryActionLabel` to add a second action alongside ACK.\n * - Use `primaryActionState` / `secondaryActionState` to temporarily disable an action (`disabled`) or remove it without leaving a gap (`none`).\n * - Use the `shelved` property to indicate alerts that are temporarily deferred, and `blocked` for alerts another system has set aside. The alert menus sort items into their tabs by `status` and `shelved`; `blocked` is there for menus that list blocked alerts apart.\n *\n * **TODO(designer):** Should a blocked alert show a marker, as a shelved one shows the shelf icon?\n *\n * ### Slots\n * | Slot Name | Renders When... | Purpose |\n * |---------------|-------------------------------|------------------------------------------------------|\n * | alert-icon | Always | Main alert icon representing the alert type. |\n * | title | Always | Title content; falls back to the `title` property. |\n * | description | Always | Description content; falls back to the `description` property. |\n * | icon | If `hasIcon` is true | Secondary icon (e.g., system/source of alert). |\n *\n * ### Events\n * - **ack-click** – Fired when the ACK action button is clicked.\n * - **ack-secondary-click** – Fired when the secondary action button is clicked.\n * - **item-click** – Fired when the alert menu item is clicked (toggles open/closed).\n *\n * ### Best Practices\n * - Only display the ACK action for alerts that require acknowledgment.\n * - Use concise titles and descriptions for quick scanning.\n * - For grouped alerts, ensure each item has a unique status and icon as appropriate.\n * - Avoid overloading with too many icons; use secondary and tertiary icons only when necessary.\n * - Follow standard notification design guidelines: keep actionable items prominent, and use color/iconography to indicate severity or status.\n *\n * **Example:**\n * ```\n * <obc-alert-menu-item\n * status=\"unacknowledged\"\n * title=\"Engine Temperature High\"\n * description=\"Port main engine temperature exceeds normal operating range\"\n * time=\"14:30\"\n * hasIcon\n * >\n * <obc-alert-icon slot=\"alert-icon\" type=\"alarm\" active></obc-alert-icon>\n * <obi-engine slot=\"icon\"></obi-engine>\n * </obc-alert-menu-item>\n * ```\n *\n * @property hasIcon - Whether to display a secondary icon (e.g., system/source) in the item.\n * When true, the `icon` slot is rendered.\n * @property shelved - Indicates if the alert is shelved (temporarily deferred).\n * When true, a tertiary icon is shown to represent the shelved state.\n * @property blocked - Indicates that another system has blocked the alert as not relevant here.\n * For menus that list blocked alerts apart; the item itself shows no marker for it yet.\n * @property title - The title of the alert.\n * @property description - The description of the alert.\n * @property day - The day label for the alert (e.g., \"Yesterday\").\n * @property time - The time label for the alert (e.g., \"14:30\").\n * @property status - The current status of the alert item.\n * Determines visual style, icon, and action button visibility.\n * Possible values: 'unacknowledged', 'caution', 'acknowledged', 'no-ack-alarm', 'no-ack-warning', 'rectified', 'rectified-unacknowledged'.\n * 'unacknowledged' and 'rectified-unacknowledged' show the ACK action; the other values show a trailing icon instead.\n * Default is 'unacknowledged'.\n * @property open - Whether the item is expanded/open to show additional details.\n * Toggled by clicking the item.\n * @property size - Layout size of the menu item.\n * Controls whether content is single-line or multi-line.\n * Possible values: 'single-line', 'multi-line'.\n * Default is 'single-line'.\n * @property animateIntro - Whether to animate the item's appearance (intro animation).\n * @property secondaryActionLabel - The label for the secondary action button.\n * Unlike the primary (ACK) action, the secondary label is not derived from\n * `status`; it must be provided explicitly. The secondary action is only\n * shown when a non-empty label is set and `secondaryActionState` is not\n * `none`.\n * @property primaryActionState - Appearance of the primary (ACK) action: `enabled`, `disabled` or `none`,\n * which hides it.\n * @property secondaryActionState - Appearance of the secondary action: `enabled`, `disabled` or `none`, which\n * hides it.\n * @slot alert-icon - The main alert icon representing the alert type.\n * @slot title - Title content; falls back to the `title` property when empty.\n * @slot description - Description content; falls back to the `description` property when empty.\n * @slot icon - Optional secondary icon (e.g., source/system).\n *\n * @fires {CustomEvent<void>} ack-click - Fired when the ACK action button is clicked.\n * @fires {CustomEvent<void>} ack-secondary-click - Fired when the secondary action button is clicked.\n * @fires {CustomEvent<void>} item-click - Fired when the alert menu item is clicked.\n * @stable\n */\n@customElement('obc-alert-menu-item')\nexport class ObcAlertMenuItem extends LitElement {\n @property({type: Boolean}) hasIcon = false;\n\n @property({type: Boolean, reflect: true}) shelved = false;\n\n @property({type: Boolean, reflect: true}) blocked = false;\n\n @property({type: String}) override title = '';\n\n @property({type: String}) description = '';\n\n @property({type: String}) day = '';\n\n @property({type: String}) time = '';\n\n @property({type: String, reflect: true}) status =\n ObcAlertMenuItemStatus.Unacknowledged;\n\n @property({type: Boolean}) open = false;\n\n @property({type: String}) size: ObcMessageMenuItemSize =\n ObcMessageMenuItemSize.SingleLine;\n\n @property({type: Boolean}) animateIntro = false;\n\n @property({type: String}) secondaryActionLabel = '';\n\n @property({type: String}) primaryActionState: ObcAlertMenuItemActionState =\n ObcAlertMenuItemActionState.Enabled;\n\n @property({type: String}) secondaryActionState: ObcAlertMenuItemActionState =\n ObcAlertMenuItemActionState.None;\n\n private get canAck() {\n return (\n this.status === ObcAlertMenuItemStatus.Unacknowledged ||\n this.status === ObcAlertMenuItemStatus.RectifiedUnacknowledged\n );\n }\n\n private get primaryActionLabel() {\n if (this.primaryActionState === ObcAlertMenuItemActionState.None) {\n return '';\n }\n return this.canAck ? 'ACK' : '';\n }\n\n private get secondaryActionLabelToShow() {\n if (this.secondaryActionState === ObcAlertMenuItemActionState.None) {\n return '';\n }\n return this.secondaryActionLabel;\n }\n\n private get primaryActionDisabled() {\n return this.primaryActionState === ObcAlertMenuItemActionState.Disabled;\n }\n\n private get secondaryActionDisabled() {\n return this.secondaryActionState === ObcAlertMenuItemActionState.Disabled;\n }\n\n private get hasTrailingIcon() {\n // True when we need the action container but don't have an ACK button\n return !this.canAck;\n }\n\n private handleMessageClick(event: Event) {\n event.stopPropagation();\n this.dispatchEvent(new CustomEvent('item-click'));\n this.open = !this.open;\n }\n\n private handleActionClick(event: Event) {\n event.stopPropagation();\n this.dispatchEvent(new CustomEvent('ack-click'));\n }\n\n private handleSecondaryActionClick(event: Event) {\n event.stopPropagation();\n this.dispatchEvent(new CustomEvent('ack-secondary-click'));\n }\n\n override render() {\n return html`\n <obc-message-menu-item\n .title=${this.title}\n .description=${this.description}\n .day=${this.day}\n .time=${this.time}\n .primaryActionLabel=${this.primaryActionLabel}\n .secondaryActionLabel=${this.secondaryActionLabelToShow}\n .enablePrimaryAction=${!this.primaryActionDisabled}\n .enableSecondaryAction=${!this.secondaryActionDisabled}\n .size=${this.size}\n .open=${this.open}\n .hasSecondaryIcon=${this.hasIcon}\n .isShelved=${this.shelved}\n .hasTrailingIcon=${this.hasTrailingIcon}\n enhancedIcon\n hasPrimaryIcon\n @message-click=${this.handleMessageClick}\n @primary-action-click=${this.handleActionClick}\n @secondary-action-click=${this.handleSecondaryActionClick}\n >\n <slot name=\"alert-icon\" slot=\"primary-icon\"></slot>\n <slot name=\"title\" slot=\"title\">${this.title}</slot>\n <slot name=\"description\" slot=\"description\">${this.description}</slot>\n ${\n this.hasIcon\n ? html`<slot name=\"icon\" slot=\"secondary-icon\"></slot>`\n : nothing\n }\n ${choose(this.status, [\n [\n ObcAlertMenuItemStatus.NoAckAlarm,\n () =>\n html`<obi-alarm-noack-iec\n slot=\"trailing-icon\"\n useCssColor\n ></obi-alarm-noack-iec>`,\n ],\n [\n ObcAlertMenuItemStatus.NoAckWarning,\n () =>\n html`<obi-warning-noack-iec\n slot=\"trailing-icon\"\n useCssColor\n ></obi-warning-noack-iec>`,\n ],\n ])}\n </obc-message-menu-item>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-alert-menu-item': ObcAlertMenuItem;\n }\n}\n"],"mappings":"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"}
@@ -419,12 +419,18 @@ var number_input_field_default = css`* {
419
419
  }
420
420
 
421
421
  .wrapper.align-center .value-input {
422
- width: var(--obc-number-input-center-width, auto);
423
- min-width: var(--obc-number-input-center-width, 40px);
422
+ field-sizing: content; /* the unit hugs the value */
423
+ width: auto;
424
424
  text-align: right;
425
425
  flex: 0 0 auto;
426
426
  }
427
427
 
428
+ @supports not (field-sizing: content) {
429
+ .wrapper.align-center .value-input {
430
+ flex: 1 1 auto; /* the 20-character default width would push the value out of a narrow field */
431
+ }
432
+ }
433
+
428
434
  .wrapper.align-right .label-container,
429
435
  .wrapper.align-right-unit-outside .label-container {
430
436
  justify-content: flex-end;
@@ -1 +1 @@
1
- {"version":3,"file":"number-input-field.css.js","names":[],"sources":["../../../src/components/number-input-field/number-input-field.css?inline"],"sourcesContent":["* {\n box-sizing: border-box;\n user-select: text;\n}\n\n.wrapper {\n @mixin base-input-field-wrapper;\n @mixin base-input-field-sizes;\n\n &.error .unit-text {\n color: var(--element-neutral-color);\n }\n}\n\n/* Shared base styles */\n@mixin base-input-field-all;\n\n.wrapper.align-center .label-container,\n.wrapper.wrapper.align-right .label-container {\n align-items: baseline;\n}\n\n/* Number input specific: text alignment */\n.value-input {\n text-align: right;\n}\n\n.squared .input-field-container {\n border-radius: 0;\n}\n\n/* Unit */\n.unit-text {\n @mixin font-instrument-unit;\n color: var(--element-inactive-color);\n white-space: nowrap;\n height: var(--global-typography-instrument-unit-line-height);\n user-select: none;\n\n &.external {\n padding-left: var(\n --ui-components-input-fields-number-input-field-unit-container-padding-left\n );\n }\n}\n\n.wrapper.align-center .label-container:focus-within .unit-text {\n color: var(--element-neutral-color);\n}\n\n/* Alignment variants */\n.wrapper.align-center .label-container {\n justify-content: center;\n}\n\n.wrapper .value-input {\n text-align: right;\n padding: 0;\n}\n\n.wrapper.align-center .value-input {\n width: var(--obc-number-input-center-width, auto);\n min-width: var(--obc-number-input-center-width, 40px);\n text-align: right;\n flex: 0 0 auto;\n}\n\n.wrapper.align-right .label-container,\n.wrapper.align-right-unit-outside .label-container {\n justify-content: flex-end;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"number-input-field.css.js","names":[],"sources":["../../../src/components/number-input-field/number-input-field.css?inline"],"sourcesContent":["* {\n box-sizing: border-box;\n user-select: text;\n}\n\n.wrapper {\n @mixin base-input-field-wrapper;\n @mixin base-input-field-sizes;\n\n &.error .unit-text {\n color: var(--element-neutral-color);\n }\n}\n\n/* Shared base styles */\n@mixin base-input-field-all;\n\n.wrapper.align-center .label-container,\n.wrapper.wrapper.align-right .label-container {\n align-items: baseline;\n}\n\n/* Number input specific: text alignment */\n.value-input {\n text-align: right;\n}\n\n.squared .input-field-container {\n border-radius: 0;\n}\n\n/* Unit */\n.unit-text {\n @mixin font-instrument-unit;\n color: var(--element-inactive-color);\n white-space: nowrap;\n height: var(--global-typography-instrument-unit-line-height);\n user-select: none;\n\n &.external {\n padding-left: var(\n --ui-components-input-fields-number-input-field-unit-container-padding-left\n );\n }\n}\n\n.wrapper.align-center .label-container:focus-within .unit-text {\n color: var(--element-neutral-color);\n}\n\n/* Alignment variants */\n.wrapper.align-center .label-container {\n justify-content: center;\n}\n\n.wrapper .value-input {\n text-align: right;\n padding: 0;\n}\n\n.wrapper.align-center .value-input {\n field-sizing: content; /* the unit hugs the value */\n width: auto;\n text-align: right;\n flex: 0 0 auto;\n}\n\n@supports not (field-sizing: content) {\n .wrapper.align-center .value-input {\n flex: 1 1 auto; /* the 20-character default width would push the value out of a narrow field */\n }\n}\n\n.wrapper.align-right .label-container,\n.wrapper.align-right-unit-outside .label-container {\n justify-content: flex-end;\n}\n"],"mappings":""}
@@ -98,6 +98,7 @@ export declare class ObcNumberInputField extends LitElement {
98
98
  private previousValue;
99
99
  private previousDisplayText;
100
100
  private lastCommittedValue;
101
+ private focusFromValueClick;
101
102
  private inputElement?;
102
103
  get displayValue(): string;
103
104
  private getFormatOptions;
@@ -106,18 +107,31 @@ export declare class ObcNumberInputField extends LitElement {
106
107
  private isProjectedValueAllowed;
107
108
  private onBeforeInput;
108
109
  private onFocus;
110
+ /**
111
+ * Ungroups a value the user clicked into, once the browser has placed the
112
+ * caret, and moves the caret with its digits. Ungrouping before that shifts
113
+ * the text under the pointer and the caret lands beside the clicked digit.
114
+ */
115
+ private ungroupKeepingSelection;
116
+ private ungroupDisplay;
109
117
  private onBlur;
110
118
  private commitDisplay;
111
119
  private dispatchInput;
112
120
  private dispatchChange;
113
121
  private get shouldUpdateValue();
114
122
  private getEffectiveDisplay;
115
- private updateCenterAlignedInputWidth;
116
123
  firstUpdated(): void;
117
124
  private get isEmpty();
118
125
  willUpdate(changedProperties: PropertyValues): void;
119
126
  updated(): void;
120
127
  private renderFooterText;
128
+ /**
129
+ * Keeps focus where it is while the chrome around the value is clicked.
130
+ * The wrapper is a `<label>`, so the click itself focuses the input; without
131
+ * this the pointerdown would blur it first and commit an unfinished edit.
132
+ * A click on the value itself is the browser's; it is only noted, so the
133
+ * focus it causes ungroups the value without moving the caret.
134
+ */
121
135
  private onPointerDown;
122
136
  render(): TemplateResult<1>;
123
137
  static styles: import('lit').CSSResult;
@@ -1 +1 @@
1
- {"version":3,"file":"number-input-field.d.ts","sourceRoot":"","sources":["../../../src/components/number-input-field/number-input-field.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAIV,cAAc,EACd,cAAc,EACf,MAAM,KAAK,CAAC;AAgBb,MAAM,MAAM,6BAA6B,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AACzE,MAAM,MAAM,8BAA8B,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AAE1E,oBAAY,4BAA4B;IACtC,MAAM,WAAW;IACjB,KAAK,UAAU;IACf,gBAAgB,uBAAuB;CACxC;AAED,oBAAY,uBAAuB;IACjC,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED,oBAAY,4BAA4B;IACtC,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,KAAK,UAAU;CAChB;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBACa,mBAAoB,SAAQ,UAAU;IACvB,KAAK,SAAO;IACZ,IAAI,SAAM;IACV,WAAW,SAAM;IACjB,SAAS,EAAE,4BAA4B,CAC5B;IAEK,QAAQ,UAAS;IACjB,QAAQ,UAAS;IACjB,KAAK,UAAS;IAC9B,SAAS,SAAM;IACd,oBAAoB,UAAS;IAC7B,aAAa,UAAS;IAEtB,sBAAsB,UAAS;IAEhC,IAAI,SAAM;IAEV,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,uBAAuB,CACrB;IAEP,cAAc,UAAS;IACxB,UAAU,SAAM;IAEhB,KAAK,SAAM;IACV,QAAQ,UAAS;IACjB,YAAY,UAAS;IACtB,cAAc,EAAE,4BAA4B,CAClC;IAET,aAAa,UAAS;IACvB,eAAe,EAAE,4BAA4B,CACnC;IAET,OAAO,UAAS;IAEC,eAAe,SAAM;IAEvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,SAAK;IACtB,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC,iBAAiB,SAAM;IAExC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,aAAa,CAAO;IAC5B,OAAO,CAAC,mBAAmB,CAAM;IACjC,OAAO,CAAC,kBAAkB,CAAO;IAEnB,OAAO,CAAC,YAAY,CAAC,CAAmB;IAE/D,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,cAAc;IAQtB,OAAO,KAAK,iBAAiB,GAU5B;IAED,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,6BAA6B;IA6B5B,YAAY;IAQrB,OAAO,KAAK,OAAO,GAKlB;IAEQ,UAAU,CAAC,iBAAiB,EAAE,cAAc;IA2B5C,OAAO;IAYhB,OAAO,CAAC,gBAAgB;IAuBxB,OAAO,CAAC,aAAa;IAyCZ,MAAM;IA4Gf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,wBAAwB,EAAE,mBAAmB,CAAC;KAC/C;CACF"}
1
+ {"version":3,"file":"number-input-field.d.ts","sourceRoot":"","sources":["../../../src/components/number-input-field/number-input-field.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAIV,cAAc,EACd,cAAc,EACf,MAAM,KAAK,CAAC;AAeb,MAAM,MAAM,6BAA6B,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AACzE,MAAM,MAAM,8BAA8B,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AAE1E,oBAAY,4BAA4B;IACtC,MAAM,WAAW;IACjB,KAAK,UAAU;IACf,gBAAgB,uBAAuB;CACxC;AAED,oBAAY,uBAAuB;IACjC,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED,oBAAY,4BAA4B;IACtC,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,KAAK,UAAU;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBACa,mBAAoB,SAAQ,UAAU;IACvB,KAAK,SAAO;IACZ,IAAI,SAAM;IACV,WAAW,SAAM;IACjB,SAAS,EAAE,4BAA4B,CAC5B;IAEK,QAAQ,UAAS;IACjB,QAAQ,UAAS;IACjB,KAAK,UAAS;IAC9B,SAAS,SAAM;IACd,oBAAoB,UAAS;IAC7B,aAAa,UAAS;IAEtB,sBAAsB,UAAS;IAEhC,IAAI,SAAM;IAEV,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,uBAAuB,CACrB;IAEP,cAAc,UAAS;IACxB,UAAU,SAAM;IAEhB,KAAK,SAAM;IACV,QAAQ,UAAS;IACjB,YAAY,UAAS;IACtB,cAAc,EAAE,4BAA4B,CAClC;IAET,aAAa,UAAS;IACvB,eAAe,EAAE,4BAA4B,CACnC;IAET,OAAO,UAAS;IAEC,eAAe,SAAM;IAEvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,SAAK;IACtB,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC,iBAAiB,SAAM;IAExC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,aAAa,CAAO;IAC5B,OAAO,CAAC,mBAAmB,CAAM;IACjC,OAAO,CAAC,kBAAkB,CAAO;IAE1C,OAAO,CAAC,mBAAmB,CAAS;IAEb,OAAO,CAAC,YAAY,CAAC,CAAmB;IAE/D,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,OAAO;IAaf;;;;OAIG;YACW,uBAAuB;IAiBrC,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,cAAc;IAQtB,OAAO,KAAK,iBAAiB,GAU5B;IAED,OAAO,CAAC,mBAAmB;IAUlB,YAAY;IAOrB,OAAO,KAAK,OAAO,GAKlB;IAEQ,UAAU,CAAC,iBAAiB,EAAE,cAAc;IA2B5C,OAAO;IAUhB,OAAO,CAAC,gBAAgB;IAuBxB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IASZ,MAAM;IA4Gf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,wBAAwB,EAAE,mBAAmB,CAAC;KAC/C;CACF"}
@@ -1,5 +1,4 @@
1
1
  import { customElement } from "../../decorator.js";
2
- import { getCssVariableValue } from "../../charthelpers/colors.js";
3
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
4
3
  import number_input_field_default from "./number-input-field.css.js";
5
4
  import { formatNumberForDisplay, isAllowedIntermediateInput, parseNumberInput, removeGroupingFromDisplay, valuesEqual } from "./number-input-format.js";
@@ -25,9 +24,6 @@ var ObcNumberInputFieldPlacement = /* @__PURE__ */ function(ObcNumberInputFieldP
25
24
  ObcNumberInputFieldPlacement["Right"] = "right";
26
25
  return ObcNumberInputFieldPlacement;
27
26
  }({});
28
- var characterWidth = 9.15199279785156;
29
- var symbolWidth = 4.287994384765653;
30
- var baseFontSize = 16;
31
27
  var ObcNumberInputField = class ObcNumberInputField extends LitElement {
32
28
  constructor(..._args) {
33
29
  super(..._args);
@@ -61,6 +57,7 @@ var ObcNumberInputField = class ObcNumberInputField extends LitElement {
61
57
  this.previousValue = NaN;
62
58
  this.previousDisplayText = "";
63
59
  this.lastCommittedValue = NaN;
60
+ this.focusFromValueClick = false;
64
61
  }
65
62
  get displayValue() {
66
63
  return this.displayText;
@@ -84,7 +81,6 @@ var ObcNumberInputField = class ObcNumberInputField extends LitElement {
84
81
  const parsed = parseNumberInput(raw);
85
82
  this.value = parsed;
86
83
  this.previousDisplayText = raw;
87
- this.updateCenterAlignedInputWidth(raw);
88
84
  this.dispatchInput();
89
85
  }
90
86
  isProjectedValueAllowed(projected) {
@@ -112,6 +108,31 @@ var ObcNumberInputField = class ObcNumberInputField extends LitElement {
112
108
  onFocus() {
113
109
  this.hasFocus = true;
114
110
  if (this.readonly) return;
111
+ if (this.focusFromValueClick) {
112
+ this.focusFromValueClick = false;
113
+ requestAnimationFrame(() => void this.ungroupKeepingSelection());
114
+ return;
115
+ }
116
+ this.ungroupDisplay();
117
+ }
118
+ /**
119
+ * Ungroups a value the user clicked into, once the browser has placed the
120
+ * caret, and moves the caret with its digits. Ungrouping before that shifts
121
+ * the text under the pointer and the caret lands beside the clicked digit.
122
+ */
123
+ async ungroupKeepingSelection() {
124
+ const input = this.inputElement;
125
+ if (!input || !this.hasFocus) return;
126
+ const grouped = input.value;
127
+ const offsetWithoutGrouping = (offset) => removeGroupingFromDisplay(grouped.slice(0, offset ?? grouped.length), this.getFormatOptions()).length;
128
+ const start = offsetWithoutGrouping(input.selectionStart);
129
+ const end = offsetWithoutGrouping(input.selectionEnd);
130
+ const direction = input.selectionDirection ?? void 0;
131
+ this.ungroupDisplay();
132
+ await this.updateComplete;
133
+ input.setSelectionRange(start, end, direction);
134
+ }
135
+ ungroupDisplay() {
115
136
  const source = this.displayOverride || this.displayText;
116
137
  this.displayText = removeGroupingFromDisplay(source, this.getFormatOptions());
117
138
  this.displayOverride = "";
@@ -158,22 +179,9 @@ var ObcNumberInputField = class ObcNumberInputField extends LitElement {
158
179
  if (!this.shouldUpdateValue && this.inputElement) return this.inputElement.value;
159
180
  return this.displayText;
160
181
  }
161
- updateCenterAlignedInputWidth(value) {
162
- if (this.textAlign !== "center") {
163
- this.style.removeProperty("--obc-number-input-center-width");
164
- return;
165
- }
166
- const fontSize = Number.parseFloat(getCssVariableValue(this, "--global-typography-instrument-value-regular-font-size"));
167
- const characters = value.replaceAll(/[.,]/g, "");
168
- const symbols = value.length - characters.length;
169
- const calculatedWidth = characters.length * characterWidth + symbols * symbolWidth;
170
- const measuredWidth = Math.ceil(calculatedWidth * fontSize / baseFontSize);
171
- this.style.setProperty("--obc-number-input-center-width", `${measuredWidth}px`);
172
- }
173
182
  firstUpdated() {
174
183
  if (!this.displayText && !this.displayOverride) this.displayText = this.formatValueForDisplay(this.value);
175
184
  this.lastCommittedValue = this.value;
176
- this.updateCenterAlignedInputWidth(this.getEffectiveDisplay());
177
185
  }
178
186
  get isEmpty() {
179
187
  if (this.inputElement) return this.inputElement.value.trim().length === 0;
@@ -195,7 +203,6 @@ var ObcNumberInputField = class ObcNumberInputField extends LitElement {
195
203
  }
196
204
  updated() {
197
205
  if (this.rejectDuplicateUpdates && !valuesEqual(this.value, this.previousValue) && (this.previousDisplayText !== this.displayText || !this.hasFocus)) this.previousValue = this.value;
198
- this.updateCenterAlignedInputWidth(this.getEffectiveDisplay());
199
206
  }
200
207
  renderFooterText(text, isError) {
201
208
  if (!text) return nothing;
@@ -212,33 +219,20 @@ var ObcNumberInputField = class ObcNumberInputField extends LitElement {
212
219
  ${text}
213
220
  </div>`;
214
221
  }
222
+ /**
223
+ * Keeps focus where it is while the chrome around the value is clicked.
224
+ * The wrapper is a `<label>`, so the click itself focuses the input; without
225
+ * this the pointerdown would blur it first and commit an unfinished edit.
226
+ * A click on the value itself is the browser's; it is only noted, so the
227
+ * focus it causes ungroups the value without moving the caret.
228
+ */
215
229
  onPointerDown(e) {
216
- if (this.disabled) return;
217
- if (this.readonly) return;
218
- if (this.inputElement) {
219
- e.stopPropagation();
220
- e.preventDefault();
221
- this.inputElement.focus();
222
- const inputBox = this.inputElement.getBoundingClientRect();
223
- let selectionStart;
224
- if (e.clientX < inputBox.left) selectionStart = 0;
225
- else if (e.clientX > inputBox.right) selectionStart = this.inputElement.value.length;
226
- else {
227
- const mouseX = e.clientX;
228
- let inputX = inputBox.right;
229
- const text = this.inputElement.value;
230
- for (let i = text.length - 1; i >= 0; i--) {
231
- const width = text[i].match(/[.,]/) ? symbolWidth : characterWidth;
232
- if (mouseX > inputX - width / 2) {
233
- selectionStart = i + 1;
234
- break;
235
- }
236
- inputX -= width;
237
- }
238
- if (selectionStart === void 0) selectionStart = 0;
239
- }
240
- this.inputElement.setSelectionRange(selectionStart, selectionStart);
230
+ if (this.disabled || this.readonly) return;
231
+ if (e.target === this.inputElement) {
232
+ this.focusFromValueClick = !this.hasFocus;
233
+ return;
241
234
  }
235
+ e.preventDefault();
242
236
  }
243
237
  render() {
244
238
  const hasHelperOrError = Boolean(this.helperText) || Boolean(this.error && this.errorText);
@@ -1 +1 @@
1
- {"version":3,"file":"number-input-field.js","names":[],"sources":["../../../src/components/number-input-field/number-input-field.ts"],"sourcesContent":["import {\n LitElement,\n html,\n nothing,\n unsafeCSS,\n TemplateResult,\n PropertyValues,\n} from 'lit';\nimport {property, state, query} from 'lit/decorators.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport componentStyle from './number-input-field.css?inline';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {customElement} from '../../decorator.js';\nimport {\n formatNumberForDisplay,\n isAllowedIntermediateInput,\n NumberInputFormatOptions,\n parseNumberInput,\n removeGroupingFromDisplay,\n valuesEqual,\n} from './number-input-format.js';\nimport {getCssVariableValue} from '../../charthelpers/colors.js';\n\nexport type ObcNumberInputFieldInputEvent = CustomEvent<{value: number}>;\nexport type ObcNumberInputFieldChangeEvent = CustomEvent<{value: number}>;\n\nexport enum ObcNumberInputFieldTextAlign {\n Center = 'center',\n Right = 'right',\n RightUnitOutside = 'right-unit-outside',\n}\n\nexport enum ObcNumberInputFieldSize {\n Regular = 'regular',\n Large = 'large',\n}\n\nexport enum ObcNumberInputFieldPlacement {\n Left = 'left',\n Center = 'center',\n Right = 'right',\n}\n\nconst characterWidth = 9.15199279785156;\nconst symbolWidth = 4.287994384765653;\nconst baseFontSize = 16;\n/**\n * `<obc-number-input-field>` – A specialized input field for numerical values with optional unit display.\n *\n * @availableWhen errorText error==true\n * @property rejectUpdatesOnFocus - If true, the input field will not update its value on focus\n * @property rejectUpdates - If true, the value will only be initially set, and not updated on change\n * @property rejectDuplicateUpdates - If true, the input field will not update its value if the value is the same as the previous value\n * This is useful to avoid React re-rendering to reset the value.\n * @property name - Name attribute for form integration\n * @property maxlength - Maximum number of characters allowed\n * @property minlength - Minimum number of characters required\n * @availableWhen hasLabelIcon label!=''\n * @availableWhen labelPlacement label!=''\n * @availableWhen hasHelperIcon helperText!='' || (error==true && errorText!='')\n * @availableWhen helperPlacement helperText!='' || (error==true && errorText!='')\n * @property squared - Internal property for squared corners, used when input is used in stepper-box\n * @property displayOverride - Optional display text override for controlled consumers (e.g. keyboard-numeric)\n * that manage formatted strings while the committed value may be NaN.\n * @property validationPattern - Optional regex pattern. When set, any keystroke or paste whose resulting\n * value does not match this pattern is blocked at the `beforeinput` stage.\n * When unset, a permissive numeric filter (digits, sign, active separators,\n * whitespace) is applied instead.\n * @slot leading-icon - Icon displayed before the input value (when `hasLeadingIcon` is true)\n * @slot label-icon - Icon displayed before the label text (when `hasLabelIcon` is true)\n * @slot helper-icon - Icon displayed before helper or error text (when `hasHelperIcon` is true)\n * @fires {CustomEvent<{value: number}>} input - When the numeric value changes during editing\n * @fires {CustomEvent<{value: number}>} change - When the value is committed on blur\n * @stable\n */\n@customElement('obc-number-input-field')\nexport class ObcNumberInputField extends LitElement {\n @property({type: Number}) value = NaN;\n @property({type: String}) unit = '';\n @property({type: String}) placeholder = '';\n @property({type: String}) textAlign: ObcNumberInputFieldTextAlign =\n ObcNumberInputFieldTextAlign.Right;\n\n @property({type: Boolean, reflect: true}) disabled = false;\n @property({type: Boolean, reflect: true}) readonly = false;\n @property({type: Boolean, reflect: true}) error = false;\n @property({type: String}) errorText = '';\n @property({type: Boolean}) rejectUpdatesOnFocus = false;\n @property({type: Boolean}) rejectUpdates = false;\n\n @property({type: Boolean}) rejectDuplicateUpdates = false;\n\n @property({type: String}) name = '';\n\n @property({type: Number}) maxlength?: number;\n\n @property({type: Number}) minlength?: number;\n\n @property({type: String}) size: ObcNumberInputFieldSize =\n ObcNumberInputFieldSize.Regular;\n\n @property({type: Boolean}) hasLeadingIcon = false;\n @property({type: String}) helperText = '';\n\n @property({type: String}) label = '';\n @property({type: Boolean}) required = false;\n @property({type: Boolean}) hasLabelIcon = false;\n @property({type: String}) labelPlacement: ObcNumberInputFieldPlacement =\n ObcNumberInputFieldPlacement.Left;\n\n @property({type: Boolean}) hasHelperIcon = false;\n @property({type: String}) helperPlacement: ObcNumberInputFieldPlacement =\n ObcNumberInputFieldPlacement.Left;\n\n @property({type: Boolean}) squared = false;\n\n @property({type: String, attribute: false}) displayOverride = '';\n\n @property({type: String}) decimalSeparator?: string;\n @property({type: String}) groupSeparator?: string;\n @property({type: Number}) minFractionDigits = 0;\n @property({type: Number}) maxFractionDigits?: number | undefined;\n\n @property({type: String}) validationPattern = '';\n\n @state() private hasFocus = false;\n @state() private displayText = '';\n @state() private previousValue = NaN;\n @state() private previousDisplayText = '';\n @state() private lastCommittedValue = NaN;\n\n @query('.value-input') private inputElement?: HTMLInputElement;\n\n get displayValue(): string {\n return this.displayText;\n }\n\n private getFormatOptions(): NumberInputFormatOptions {\n return {\n decimalSeparator: this.decimalSeparator,\n groupSeparator: this.groupSeparator,\n minFractionDigits: this.minFractionDigits,\n maxFractionDigits: this.maxFractionDigits,\n };\n }\n\n private formatValueForDisplay(value: number): string {\n return formatNumberForDisplay(value, this.getFormatOptions());\n }\n\n private onInput(e: Event) {\n e.stopPropagation();\n const raw = (e.target as HTMLInputElement).value;\n this.displayText = raw;\n this.displayOverride = '';\n const parsed = parseNumberInput(raw);\n this.value = parsed;\n this.previousDisplayText = raw;\n this.updateCenterAlignedInputWidth(raw);\n this.dispatchInput();\n }\n\n private isProjectedValueAllowed(projected: string): boolean {\n if (this.validationPattern) {\n let regex: RegExp;\n try {\n // Anchor the consumer pattern so it must match the whole projected\n // value rather than any substring (e.g. `[0-9]` must not pass `a1`).\n regex = new RegExp(`^(?:${this.validationPattern})$`);\n } catch {\n // Invalid pattern: fall back to the numeric filter instead of\n // allowing arbitrary input.\n return isAllowedIntermediateInput(projected, this.getFormatOptions());\n }\n return regex.test(projected);\n }\n return isAllowedIntermediateInput(projected, this.getFormatOptions());\n }\n\n private onBeforeInput(e: InputEvent) {\n if (this.disabled || this.readonly) return;\n const input = e.target as HTMLInputElement;\n\n const incoming = e.data ?? e.dataTransfer?.getData('text/plain') ?? null;\n // Deletions, history, and formatting (`insertLineBreak`, `historyUndo`,\n // `deleteContentBackward`, etc.) have `data === null` and no transferable\n // text — always allow them.\n if (incoming === null) return;\n\n const start = input.selectionStart ?? input.value.length;\n const end = input.selectionEnd ?? input.value.length;\n const projected =\n input.value.slice(0, start) + incoming + input.value.slice(end);\n\n if (!this.isProjectedValueAllowed(projected)) {\n e.preventDefault();\n }\n }\n\n private onFocus() {\n this.hasFocus = true;\n // A read-only field has nothing to edit, so it keeps its formatted display\n // instead of switching to the ungrouped editing representation.\n if (this.readonly) return;\n const source = this.displayOverride || this.displayText;\n this.displayText = removeGroupingFromDisplay(\n source,\n this.getFormatOptions()\n );\n this.displayOverride = '';\n }\n\n private onBlur() {\n this.hasFocus = false;\n if (this.readonly) return;\n this.commitDisplay();\n if (!valuesEqual(this.value, this.lastCommittedValue)) {\n this.lastCommittedValue = this.value;\n this.dispatchChange();\n }\n }\n\n private commitDisplay() {\n const trimmed = this.displayText.trim();\n if (trimmed === '') {\n this.value = NaN;\n this.displayText = '';\n this.displayOverride = '';\n return;\n }\n\n const forCommit = trimmed.replace(/[.,]$/, '');\n const parsed = parseNumberInput(forCommit);\n\n if (Number.isFinite(parsed)) {\n this.value = parsed;\n this.displayText = this.formatValueForDisplay(parsed);\n } else {\n this.value = NaN;\n }\n this.displayOverride = '';\n }\n\n private dispatchInput() {\n this.dispatchEvent(\n new CustomEvent('input', {\n detail: {value: this.value},\n })\n );\n }\n\n private dispatchChange() {\n this.dispatchEvent(\n new CustomEvent('change', {\n detail: {value: this.value},\n })\n );\n }\n\n private get shouldUpdateValue(): boolean {\n if (this.rejectUpdates) return false;\n if (this.rejectUpdatesOnFocus && this.hasFocus) return false;\n if (\n this.rejectDuplicateUpdates &&\n valuesEqual(this.value, this.previousValue)\n ) {\n return false;\n }\n return true;\n }\n\n private getEffectiveDisplay(): string {\n if (this.displayOverride) {\n return this.displayOverride;\n }\n if (!this.shouldUpdateValue && this.inputElement) {\n return this.inputElement.value;\n }\n return this.displayText;\n }\n\n private updateCenterAlignedInputWidth(value: string) {\n if (this.textAlign !== ObcNumberInputFieldTextAlign.Center) {\n this.style.removeProperty('--obc-number-input-center-width');\n return;\n }\n\n const fontSize = Number.parseFloat(\n getCssVariableValue(\n this,\n '--global-typography-instrument-value-regular-font-size'\n )\n );\n\n const characters = value.replaceAll(/[.,]/g, '');\n const symbols = value.length - characters.length;\n // These values are based on the font size of 16px\n\n const calculatedWidth =\n characters.length * characterWidth + symbols * symbolWidth;\n\n const measuredWidth = Math.ceil(\n (calculatedWidth * fontSize) / baseFontSize\n );\n this.style.setProperty(\n '--obc-number-input-center-width',\n `${measuredWidth}px`\n );\n }\n\n override firstUpdated() {\n if (!this.displayText && !this.displayOverride) {\n this.displayText = this.formatValueForDisplay(this.value);\n }\n this.lastCommittedValue = this.value;\n this.updateCenterAlignedInputWidth(this.getEffectiveDisplay());\n }\n\n private get isEmpty(): boolean {\n if (this.inputElement) {\n return this.inputElement.value.trim().length === 0;\n }\n return isNaN(this.value);\n }\n\n override willUpdate(changedProperties: PropertyValues) {\n const formatPropsChanged =\n changedProperties.has('decimalSeparator') ||\n changedProperties.has('groupSeparator') ||\n changedProperties.has('minFractionDigits') ||\n changedProperties.has('maxFractionDigits');\n\n if (changedProperties.has('value') && this.shouldUpdateValue) {\n if (!this.hasFocus) {\n this.displayText = this.formatValueForDisplay(this.value);\n this.displayOverride = '';\n this.lastCommittedValue = this.value;\n }\n } else if (formatPropsChanged && !this.hasFocus && this.shouldUpdateValue) {\n this.displayText = this.formatValueForDisplay(this.value);\n this.displayOverride = '';\n }\n\n if (\n changedProperties.has('value') &&\n !this.shouldUpdateValue &&\n this.inputElement\n ) {\n this.value = parseNumberInput(this.inputElement.value);\n }\n }\n\n override updated() {\n if (\n this.rejectDuplicateUpdates &&\n !valuesEqual(this.value, this.previousValue) &&\n (this.previousDisplayText !== this.displayText || !this.hasFocus)\n ) {\n this.previousValue = this.value;\n }\n\n this.updateCenterAlignedInputWidth(this.getEffectiveDisplay());\n }\n\n private renderFooterText(\n text: string,\n isError: boolean\n ): TemplateResult | typeof nothing {\n if (!text) return nothing;\n return html`<div\n id=\"helper-text\"\n class=${classMap({\n [isError ? 'error-text' : 'helper-text']: true,\n [`helper-placement-${this.helperPlacement}`]: true,\n })}\n >\n ${\n this.hasHelperIcon\n ? html`<div class=\"helper-icon\">\n <slot name=\"helper-icon\"></slot>\n </div>`\n : nothing\n }\n ${text}\n </div>`;\n }\n\n private onPointerDown(e: PointerEvent) {\n if (this.disabled) return;\n if (this.readonly) return;\n if (this.inputElement) {\n e.stopPropagation();\n e.preventDefault();\n this.inputElement.focus();\n const inputBox = this.inputElement.getBoundingClientRect();\n let selectionStart: number | undefined;\n if (e.clientX < inputBox.left) {\n // set marker at the left edge of the input\n selectionStart = 0;\n } else if (e.clientX > inputBox.right) {\n // set marker at the right edge of the input\n selectionStart = this.inputElement.value.length;\n } else {\n // set marker at the mouse position\n // Start from the right side of the input and move left until the mouse position is found\n // This is done to set the marker also at label touch.\n // Starts from the right since the label is right aligned.\n const mouseX = e.clientX;\n let inputX = inputBox.right;\n const text = this.inputElement.value;\n for (let i = text.length - 1; i >= 0; i--) {\n const char = text[i];\n const isSymbol = char.match(/[.,]/);\n const width = isSymbol ? symbolWidth : characterWidth;\n if (mouseX > inputX - width / 2) {\n selectionStart = i + 1;\n break;\n }\n inputX -= width;\n }\n if (selectionStart === undefined) {\n selectionStart = 0;\n }\n }\n this.inputElement.setSelectionRange(selectionStart, selectionStart);\n }\n }\n\n override render() {\n const hasHelperOrError =\n Boolean(this.helperText) || Boolean(this.error && this.errorText);\n const unitInside =\n this.unit &&\n this.textAlign !== ObcNumberInputFieldTextAlign.RightUnitOutside;\n const unitOutside =\n this.unit &&\n this.textAlign === ObcNumberInputFieldTextAlign.RightUnitOutside;\n\n const display = this.getEffectiveDisplay();\n\n return html`\n <label\n class=${classMap({\n wrapper: true,\n [`align-${this.textAlign}`]: true,\n [`size-${this.size}`]: true,\n error: this.error,\n disabled: this.disabled,\n readonly: this.readonly,\n empty: this.isEmpty,\n helpertext: hasHelperOrError,\n haslabel: Boolean(this.label),\n squared: this.squared,\n })}\n @pointerdown=${this.onPointerDown}\n >\n ${\n this.label\n ? html`<div\n class=${classMap({\n 'label-text-container': true,\n [`label-placement-${this.labelPlacement}`]: true,\n })}\n >\n ${\n this.hasLabelIcon\n ? html`<div class=\"label-icon\">\n <slot name=\"label-icon\"></slot>\n </div>`\n : nothing\n }\n <span class=\"label-text\">${this.label}</span>\n ${\n this.required\n ? html`<div class=\"required-indicator\"></div>`\n : nothing\n }\n </div>`\n : nothing\n }\n\n <div class=\"horizontal-container\">\n <div class=\"input-field-container\" part=\"input-field-container\">\n ${\n this.hasLeadingIcon\n ? html`<div class=\"leading-icon\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing\n }\n <div class=\"label-container\">\n <input\n type=\"text\"\n inputmode=\"decimal\"\n class=\"value-input\"\n .value=${display}\n @focus=${this.onFocus}\n @blur=${this.onBlur}\n .placeholder=${this.placeholder}\n name=${ifDefined(this.name || undefined)}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n maxlength=${ifDefined(this.maxlength)}\n minlength=${ifDefined(this.minlength)}\n aria-invalid=${this.error ? 'true' : 'false'}\n aria-describedby=${ifDefined(\n hasHelperOrError ? 'helper-text' : undefined\n )}\n autocomplete=\"off\"\n @beforeinput=${this.onBeforeInput}\n @input=${this.onInput}\n />\n ${\n unitInside\n ? html`<span class=\"unit-text\">${this.unit}</span>`\n : nothing\n }\n </div>\n </div>\n ${\n unitOutside\n ? html`<span class=\"unit-text external\">${this.unit}</span>`\n : nothing\n }\n </div>\n\n ${\n this.error && this.errorText\n ? this.renderFooterText(this.errorText, true)\n : this.renderFooterText(this.helperText, false)\n }\n </label>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-number-input-field': ObcNumberInputField;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"number-input-field.js","names":[],"sources":["../../../src/components/number-input-field/number-input-field.ts"],"sourcesContent":["import {\n LitElement,\n html,\n nothing,\n unsafeCSS,\n TemplateResult,\n PropertyValues,\n} from 'lit';\nimport {property, state, query} from 'lit/decorators.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport componentStyle from './number-input-field.css?inline';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {customElement} from '../../decorator.js';\nimport {\n formatNumberForDisplay,\n isAllowedIntermediateInput,\n NumberInputFormatOptions,\n parseNumberInput,\n removeGroupingFromDisplay,\n valuesEqual,\n} from './number-input-format.js';\n\nexport type ObcNumberInputFieldInputEvent = CustomEvent<{value: number}>;\nexport type ObcNumberInputFieldChangeEvent = CustomEvent<{value: number}>;\n\nexport enum ObcNumberInputFieldTextAlign {\n Center = 'center',\n Right = 'right',\n RightUnitOutside = 'right-unit-outside',\n}\n\nexport enum ObcNumberInputFieldSize {\n Regular = 'regular',\n Large = 'large',\n}\n\nexport enum ObcNumberInputFieldPlacement {\n Left = 'left',\n Center = 'center',\n Right = 'right',\n}\n\n/**\n * `<obc-number-input-field>` – A specialized input field for numerical values with optional unit display.\n *\n * @availableWhen errorText error==true\n * @property rejectUpdatesOnFocus - If true, the input field will not update its value on focus\n * @property rejectUpdates - If true, the value will only be initially set, and not updated on change\n * @property rejectDuplicateUpdates - If true, the input field will not update its value if the value is the same as the previous value\n * This is useful to avoid React re-rendering to reset the value.\n * @property name - Name attribute for form integration\n * @property maxlength - Maximum number of characters allowed\n * @property minlength - Minimum number of characters required\n * @availableWhen hasLabelIcon label!=''\n * @availableWhen labelPlacement label!=''\n * @availableWhen hasHelperIcon helperText!='' || (error==true && errorText!='')\n * @availableWhen helperPlacement helperText!='' || (error==true && errorText!='')\n * @property squared - Internal property for squared corners, used when input is used in stepper-box\n * @property displayOverride - Optional display text override for controlled consumers (e.g. keyboard-numeric)\n * that manage formatted strings while the committed value may be NaN.\n * @property validationPattern - Optional regex pattern. When set, any keystroke or paste whose resulting\n * value does not match this pattern is blocked at the `beforeinput` stage.\n * When unset, a permissive numeric filter (digits, sign, active separators,\n * whitespace) is applied instead.\n * @slot leading-icon - Icon displayed before the input value (when `hasLeadingIcon` is true)\n * @slot label-icon - Icon displayed before the label text (when `hasLabelIcon` is true)\n * @slot helper-icon - Icon displayed before helper or error text (when `hasHelperIcon` is true)\n * @fires {CustomEvent<{value: number}>} input - When the numeric value changes during editing\n * @fires {CustomEvent<{value: number}>} change - When the value is committed on blur\n * @stable\n */\n@customElement('obc-number-input-field')\nexport class ObcNumberInputField extends LitElement {\n @property({type: Number}) value = NaN;\n @property({type: String}) unit = '';\n @property({type: String}) placeholder = '';\n @property({type: String}) textAlign: ObcNumberInputFieldTextAlign =\n ObcNumberInputFieldTextAlign.Right;\n\n @property({type: Boolean, reflect: true}) disabled = false;\n @property({type: Boolean, reflect: true}) readonly = false;\n @property({type: Boolean, reflect: true}) error = false;\n @property({type: String}) errorText = '';\n @property({type: Boolean}) rejectUpdatesOnFocus = false;\n @property({type: Boolean}) rejectUpdates = false;\n\n @property({type: Boolean}) rejectDuplicateUpdates = false;\n\n @property({type: String}) name = '';\n\n @property({type: Number}) maxlength?: number;\n\n @property({type: Number}) minlength?: number;\n\n @property({type: String}) size: ObcNumberInputFieldSize =\n ObcNumberInputFieldSize.Regular;\n\n @property({type: Boolean}) hasLeadingIcon = false;\n @property({type: String}) helperText = '';\n\n @property({type: String}) label = '';\n @property({type: Boolean}) required = false;\n @property({type: Boolean}) hasLabelIcon = false;\n @property({type: String}) labelPlacement: ObcNumberInputFieldPlacement =\n ObcNumberInputFieldPlacement.Left;\n\n @property({type: Boolean}) hasHelperIcon = false;\n @property({type: String}) helperPlacement: ObcNumberInputFieldPlacement =\n ObcNumberInputFieldPlacement.Left;\n\n @property({type: Boolean}) squared = false;\n\n @property({type: String, attribute: false}) displayOverride = '';\n\n @property({type: String}) decimalSeparator?: string;\n @property({type: String}) groupSeparator?: string;\n @property({type: Number}) minFractionDigits = 0;\n @property({type: Number}) maxFractionDigits?: number | undefined;\n\n @property({type: String}) validationPattern = '';\n\n @state() private hasFocus = false;\n @state() private displayText = '';\n @state() private previousValue = NaN;\n @state() private previousDisplayText = '';\n @state() private lastCommittedValue = NaN;\n\n private focusFromValueClick = false;\n\n @query('.value-input') private inputElement?: HTMLInputElement;\n\n get displayValue(): string {\n return this.displayText;\n }\n\n private getFormatOptions(): NumberInputFormatOptions {\n return {\n decimalSeparator: this.decimalSeparator,\n groupSeparator: this.groupSeparator,\n minFractionDigits: this.minFractionDigits,\n maxFractionDigits: this.maxFractionDigits,\n };\n }\n\n private formatValueForDisplay(value: number): string {\n return formatNumberForDisplay(value, this.getFormatOptions());\n }\n\n private onInput(e: Event) {\n e.stopPropagation();\n const raw = (e.target as HTMLInputElement).value;\n this.displayText = raw;\n this.displayOverride = '';\n const parsed = parseNumberInput(raw);\n this.value = parsed;\n this.previousDisplayText = raw;\n this.dispatchInput();\n }\n\n private isProjectedValueAllowed(projected: string): boolean {\n if (this.validationPattern) {\n let regex: RegExp;\n try {\n // Anchor the consumer pattern so it must match the whole projected\n // value rather than any substring (e.g. `[0-9]` must not pass `a1`).\n regex = new RegExp(`^(?:${this.validationPattern})$`);\n } catch {\n // Invalid pattern: fall back to the numeric filter instead of\n // allowing arbitrary input.\n return isAllowedIntermediateInput(projected, this.getFormatOptions());\n }\n return regex.test(projected);\n }\n return isAllowedIntermediateInput(projected, this.getFormatOptions());\n }\n\n private onBeforeInput(e: InputEvent) {\n if (this.disabled || this.readonly) return;\n const input = e.target as HTMLInputElement;\n\n const incoming = e.data ?? e.dataTransfer?.getData('text/plain') ?? null;\n // Deletions, history, and formatting (`insertLineBreak`, `historyUndo`,\n // `deleteContentBackward`, etc.) have `data === null` and no transferable\n // text — always allow them.\n if (incoming === null) return;\n\n const start = input.selectionStart ?? input.value.length;\n const end = input.selectionEnd ?? input.value.length;\n const projected =\n input.value.slice(0, start) + incoming + input.value.slice(end);\n\n if (!this.isProjectedValueAllowed(projected)) {\n e.preventDefault();\n }\n }\n\n private onFocus() {\n this.hasFocus = true;\n // A read-only field has nothing to edit, so it keeps its formatted display\n // instead of switching to the ungrouped editing representation.\n if (this.readonly) return;\n if (this.focusFromValueClick) {\n this.focusFromValueClick = false;\n requestAnimationFrame(() => void this.ungroupKeepingSelection());\n return;\n }\n this.ungroupDisplay();\n }\n\n /**\n * Ungroups a value the user clicked into, once the browser has placed the\n * caret, and moves the caret with its digits. Ungrouping before that shifts\n * the text under the pointer and the caret lands beside the clicked digit.\n */\n private async ungroupKeepingSelection() {\n const input = this.inputElement;\n if (!input || !this.hasFocus) return;\n const grouped = input.value;\n const offsetWithoutGrouping = (offset: number | null) =>\n removeGroupingFromDisplay(\n grouped.slice(0, offset ?? grouped.length),\n this.getFormatOptions()\n ).length;\n const start = offsetWithoutGrouping(input.selectionStart);\n const end = offsetWithoutGrouping(input.selectionEnd);\n const direction = input.selectionDirection ?? undefined;\n this.ungroupDisplay();\n await this.updateComplete;\n input.setSelectionRange(start, end, direction);\n }\n\n private ungroupDisplay() {\n const source = this.displayOverride || this.displayText;\n this.displayText = removeGroupingFromDisplay(\n source,\n this.getFormatOptions()\n );\n this.displayOverride = '';\n }\n\n private onBlur() {\n this.hasFocus = false;\n if (this.readonly) return;\n this.commitDisplay();\n if (!valuesEqual(this.value, this.lastCommittedValue)) {\n this.lastCommittedValue = this.value;\n this.dispatchChange();\n }\n }\n\n private commitDisplay() {\n const trimmed = this.displayText.trim();\n if (trimmed === '') {\n this.value = NaN;\n this.displayText = '';\n this.displayOverride = '';\n return;\n }\n\n const forCommit = trimmed.replace(/[.,]$/, '');\n const parsed = parseNumberInput(forCommit);\n\n if (Number.isFinite(parsed)) {\n this.value = parsed;\n this.displayText = this.formatValueForDisplay(parsed);\n } else {\n this.value = NaN;\n }\n this.displayOverride = '';\n }\n\n private dispatchInput() {\n this.dispatchEvent(\n new CustomEvent('input', {\n detail: {value: this.value},\n })\n );\n }\n\n private dispatchChange() {\n this.dispatchEvent(\n new CustomEvent('change', {\n detail: {value: this.value},\n })\n );\n }\n\n private get shouldUpdateValue(): boolean {\n if (this.rejectUpdates) return false;\n if (this.rejectUpdatesOnFocus && this.hasFocus) return false;\n if (\n this.rejectDuplicateUpdates &&\n valuesEqual(this.value, this.previousValue)\n ) {\n return false;\n }\n return true;\n }\n\n private getEffectiveDisplay(): string {\n if (this.displayOverride) {\n return this.displayOverride;\n }\n if (!this.shouldUpdateValue && this.inputElement) {\n return this.inputElement.value;\n }\n return this.displayText;\n }\n\n override firstUpdated() {\n if (!this.displayText && !this.displayOverride) {\n this.displayText = this.formatValueForDisplay(this.value);\n }\n this.lastCommittedValue = this.value;\n }\n\n private get isEmpty(): boolean {\n if (this.inputElement) {\n return this.inputElement.value.trim().length === 0;\n }\n return isNaN(this.value);\n }\n\n override willUpdate(changedProperties: PropertyValues) {\n const formatPropsChanged =\n changedProperties.has('decimalSeparator') ||\n changedProperties.has('groupSeparator') ||\n changedProperties.has('minFractionDigits') ||\n changedProperties.has('maxFractionDigits');\n\n if (changedProperties.has('value') && this.shouldUpdateValue) {\n if (!this.hasFocus) {\n this.displayText = this.formatValueForDisplay(this.value);\n this.displayOverride = '';\n this.lastCommittedValue = this.value;\n }\n } else if (formatPropsChanged && !this.hasFocus && this.shouldUpdateValue) {\n this.displayText = this.formatValueForDisplay(this.value);\n this.displayOverride = '';\n }\n\n if (\n changedProperties.has('value') &&\n !this.shouldUpdateValue &&\n this.inputElement\n ) {\n this.value = parseNumberInput(this.inputElement.value);\n }\n }\n\n override updated() {\n if (\n this.rejectDuplicateUpdates &&\n !valuesEqual(this.value, this.previousValue) &&\n (this.previousDisplayText !== this.displayText || !this.hasFocus)\n ) {\n this.previousValue = this.value;\n }\n }\n\n private renderFooterText(\n text: string,\n isError: boolean\n ): TemplateResult | typeof nothing {\n if (!text) return nothing;\n return html`<div\n id=\"helper-text\"\n class=${classMap({\n [isError ? 'error-text' : 'helper-text']: true,\n [`helper-placement-${this.helperPlacement}`]: true,\n })}\n >\n ${\n this.hasHelperIcon\n ? html`<div class=\"helper-icon\">\n <slot name=\"helper-icon\"></slot>\n </div>`\n : nothing\n }\n ${text}\n </div>`;\n }\n\n /**\n * Keeps focus where it is while the chrome around the value is clicked.\n * The wrapper is a `<label>`, so the click itself focuses the input; without\n * this the pointerdown would blur it first and commit an unfinished edit.\n * A click on the value itself is the browser's; it is only noted, so the\n * focus it causes ungroups the value without moving the caret.\n */\n private onPointerDown(e: PointerEvent) {\n if (this.disabled || this.readonly) return;\n if (e.target === this.inputElement) {\n this.focusFromValueClick = !this.hasFocus;\n return;\n }\n e.preventDefault();\n }\n\n override render() {\n const hasHelperOrError =\n Boolean(this.helperText) || Boolean(this.error && this.errorText);\n const unitInside =\n this.unit &&\n this.textAlign !== ObcNumberInputFieldTextAlign.RightUnitOutside;\n const unitOutside =\n this.unit &&\n this.textAlign === ObcNumberInputFieldTextAlign.RightUnitOutside;\n\n const display = this.getEffectiveDisplay();\n\n return html`\n <label\n class=${classMap({\n wrapper: true,\n [`align-${this.textAlign}`]: true,\n [`size-${this.size}`]: true,\n error: this.error,\n disabled: this.disabled,\n readonly: this.readonly,\n empty: this.isEmpty,\n helpertext: hasHelperOrError,\n haslabel: Boolean(this.label),\n squared: this.squared,\n })}\n @pointerdown=${this.onPointerDown}\n >\n ${\n this.label\n ? html`<div\n class=${classMap({\n 'label-text-container': true,\n [`label-placement-${this.labelPlacement}`]: true,\n })}\n >\n ${\n this.hasLabelIcon\n ? html`<div class=\"label-icon\">\n <slot name=\"label-icon\"></slot>\n </div>`\n : nothing\n }\n <span class=\"label-text\">${this.label}</span>\n ${\n this.required\n ? html`<div class=\"required-indicator\"></div>`\n : nothing\n }\n </div>`\n : nothing\n }\n\n <div class=\"horizontal-container\">\n <div class=\"input-field-container\" part=\"input-field-container\">\n ${\n this.hasLeadingIcon\n ? html`<div class=\"leading-icon\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing\n }\n <div class=\"label-container\">\n <input\n type=\"text\"\n inputmode=\"decimal\"\n class=\"value-input\"\n .value=${display}\n @focus=${this.onFocus}\n @blur=${this.onBlur}\n .placeholder=${this.placeholder}\n name=${ifDefined(this.name || undefined)}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n maxlength=${ifDefined(this.maxlength)}\n minlength=${ifDefined(this.minlength)}\n aria-invalid=${this.error ? 'true' : 'false'}\n aria-describedby=${ifDefined(\n hasHelperOrError ? 'helper-text' : undefined\n )}\n autocomplete=\"off\"\n @beforeinput=${this.onBeforeInput}\n @input=${this.onInput}\n />\n ${\n unitInside\n ? html`<span class=\"unit-text\">${this.unit}</span>`\n : nothing\n }\n </div>\n </div>\n ${\n unitOutside\n ? html`<span class=\"unit-text external\">${this.unit}</span>`\n : nothing\n }\n </div>\n\n ${\n this.error && this.errorText\n ? this.renderFooterText(this.errorText, true)\n : this.renderFooterText(this.helperText, false)\n }\n </label>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-number-input-field': ObcNumberInputField;\n }\n}\n"],"mappings":"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"}
@@ -19,21 +19,15 @@ var textbox_default = css`* {
19
19
  letter-spacing: var(--global-typography-generic-l-letter-spacing);
20
20
  }
21
21
 
22
- /* The inner-wrapper is the box: its height (--height) is the full textbox
23
- height, padding included. The content is sized to the cap height and
24
- vertically centered, which leaves the padding as equal space above and
25
- below. In engines that support text-box-trim the content box collapses to
26
- the cap height exactly; in Firefox (no text-box-trim) the content keeps its
27
- natural line box, so align-items:center + overflow:hidden crops it to the
28
- same height instead. No padding here – the centering provides it.
29
- (A small top padding could be added later to nudge the text up in Firefox.) */
22
+ /* The box, never clipped: descenders and diacritics paint past its edges. The
23
+ centred content leaves equal padding above and below; without text-box-trim
24
+ the host's zero line-height keeps it centred to within about a pixel. */
30
25
  .inner-wrapper {
31
26
  box-sizing: border-box;
32
27
  display: flex;
33
28
  align-items: center;
34
29
  justify-content: var(--alignment-justify, flex-end);
35
30
  height: var(--height);
36
- overflow: hidden;
37
31
  /* Opt-in: animate a \`size\` change (height + font-size below). Defaults to 0s
38
32
  (instant, current behavior) so existing usages and snapshots are unchanged;
39
33
  a consumer sets \`--obc-textbox-size-transition\` (e.g. 300ms) to animate the