@oicl/openbridge-webcomponents 2.0.0-next.124 → 2.0.0-next.125

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 (28) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +72 -15
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +19 -0
  4. package/dist/components/keyboard-full/keyboard-full.d.ts +5 -0
  5. package/dist/components/keyboard-full/keyboard-full.d.ts.map +1 -1
  6. package/dist/components/keyboard-full/keyboard-full.js +15 -8
  7. package/dist/components/keyboard-full/keyboard-full.js.map +1 -1
  8. package/dist/components/number-input-field/number-input-field.css.js +19 -0
  9. package/dist/components/number-input-field/number-input-field.css.js.map +1 -1
  10. package/dist/components/number-input-field/number-input-field.d.ts.map +1 -1
  11. package/dist/components/number-input-field/number-input-field.js +3 -0
  12. package/dist/components/number-input-field/number-input-field.js.map +1 -1
  13. package/dist/components/text-input-field/text-input-field.css.js +19 -0
  14. package/dist/components/text-input-field/text-input-field.css.js.map +1 -1
  15. package/dist/components/text-input-field/text-input-field.d.ts.map +1 -1
  16. package/dist/components/text-input-field/text-input-field.js +2 -1
  17. package/dist/components/text-input-field/text-input-field.js.map +1 -1
  18. package/dist/navigation-instruments/bearing-indicator/bearing-indicator.css.js +6 -2
  19. package/dist/navigation-instruments/bearing-indicator/bearing-indicator.css.js.map +1 -1
  20. package/dist/navigation-instruments/compass-indicator/compass-indicator.css.js +6 -2
  21. package/dist/navigation-instruments/compass-indicator/compass-indicator.css.js.map +1 -1
  22. package/dist/navigation-instruments/gauge-horizontal/gauge-horizontal.d.ts.map +1 -1
  23. package/dist/navigation-instruments/gauge-horizontal/gauge-horizontal.js +1 -1
  24. package/dist/navigation-instruments/gauge-horizontal/gauge-horizontal.js.map +1 -1
  25. package/dist/navigation-instruments/gauge-vertical/gauge-vertical.d.ts.map +1 -1
  26. package/dist/navigation-instruments/gauge-vertical/gauge-vertical.js +1 -1
  27. package/dist/navigation-instruments/gauge-vertical/gauge-vertical.js.map +1 -1
  28. package/package.json +1 -1
@@ -52327,6 +52327,25 @@
52327
52327
  "name": "onToggleCaps",
52328
52328
  "privacy": "private"
52329
52329
  },
52330
+ {
52331
+ "kind": "method",
52332
+ "name": "letterKeyLabel",
52333
+ "privacy": "private",
52334
+ "return": {
52335
+ "type": {
52336
+ "text": "string"
52337
+ }
52338
+ },
52339
+ "parameters": [
52340
+ {
52341
+ "name": "key",
52342
+ "type": {
52343
+ "text": "string"
52344
+ }
52345
+ }
52346
+ ],
52347
+ "description": "The character a letter key both shows and inserts. CAPS applies wherever\nthe alphabetic layout is rendered, including the number-row variant."
52348
+ },
52330
52349
  {
52331
52350
  "kind": "field",
52332
52351
  "name": "onToggleMode",
@@ -199,6 +199,11 @@ export declare class ObcKeyboardFull extends LitElement {
199
199
  private onBackspace;
200
200
  private onSpace;
201
201
  private onToggleCaps;
202
+ /**
203
+ * The character a letter key both shows and inserts. CAPS applies wherever
204
+ * the alphabetic layout is rendered, including the number-row variant.
205
+ */
206
+ private letterKeyLabel;
202
207
  private onToggleMode;
203
208
  private onCursorLeft;
204
209
  private onCursorRight;
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-full.d.ts","sourceRoot":"","sources":["../../../src/components/keyboard-full/keyboard-full.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,+BAA+B,CAAC;AACvC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,sCAAsC,CAAC;AAC9C,OAAO,wCAAwC,CAAC;AAChD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,gCAAgC,CAAC;AACxC,OAAO,yCAAyC,CAAC;AACjD,OAAO,EACL,sBAAsB,EAEtB,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,iCAAiC,CAAC;AAEzC,oBAAY,mBAAmB;IAC7B,QAAQ,aAAa;IACrB,IAAI,SAAS;CACd;AAED,oBAAY,mBAAmB;IAC7B,GAAG,QAAQ;IACX,OAAO,QAAQ;IACf,OAAO,YAAY;IACnB,oBAAoB,4BAA4B;CACjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuJG;AACH,qBACa,eAAgB,SAAQ,UAAU;IACnB,IAAI,EAAE,mBAAmB,CACpB;IAEJ,UAAU,UAAS;IAC9C,sCAAsC;IACZ,aAAa,SAAoB;IAEjC,KAAK,SAAM;IACX,WAAW,SAAiB;IAC3B,aAAa,UAAS;IACvB,SAAS,EAAE,qBAAqB,CAC5B;IAE9B;;;OAGG;IACuB,SAAS,EAAE,sBAAsB,CAC7B;IAErB,OAAO,CAAC,IAAI,CAAgD;IAC5D,OAAO,CAAC,QAAQ,CAAS;IAGlC,OAAO,CAAC,UAAU,CAAqB;IAGvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAWxB;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAI3B;IAEF,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAIzC;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;IAEF,OAAO,CAAC,YAAY,CAOlB;IAEF,OAAO,CAAC,gBAAgB,CAEtB;IAEF,OAAO,CAAC,UAAU,CAyBhB;IAEF,OAAO,CAAC,WAAW,CAuBjB;IAEF,OAAO,CAAC,OAAO,CAmBb;IAEF,OAAO,CAAC,YAAY,CAElB;IAEF,OAAO,CAAC,YAAY,CAElB;IAEF,OAAO,CAAC,YAAY,CAWlB;IAEF,OAAO,CAAC,aAAa,CAcnB;IAEF,OAAO,CAAC,MAAM,CAQZ;IAEF,OAAO,CAAC,mBAAmB,CAQzB;IAEF,OAAO,CAAC,wBAAwB,CAG9B;IAEF,OAAO,CAAC,sBAAsB;IAuB9B,OAAO,CAAC,gBAAgB;IAmExB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,iBAAiB;IA4DzB,OAAO,CAAC,kCAAkC;IAiD1C,OAAO,CAAC,qBAAqB;IAmC7B,OAAO,CAAC,qBAAqB;cAmCV,MAAM;IA0EzB,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
1
+ {"version":3,"file":"keyboard-full.d.ts","sourceRoot":"","sources":["../../../src/components/keyboard-full/keyboard-full.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAKzD,OAAO,+BAA+B,CAAC;AACvC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,sCAAsC,CAAC;AAC9C,OAAO,wCAAwC,CAAC;AAChD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,gCAAgC,CAAC;AACxC,OAAO,yCAAyC,CAAC;AACjD,OAAO,EACL,sBAAsB,EAEtB,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,iCAAiC,CAAC;AAEzC,oBAAY,mBAAmB;IAC7B,QAAQ,aAAa;IACrB,IAAI,SAAS;CACd;AAED,oBAAY,mBAAmB;IAC7B,GAAG,QAAQ;IACX,OAAO,QAAQ;IACf,OAAO,YAAY;IACnB,oBAAoB,4BAA4B;CACjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuJG;AACH,qBACa,eAAgB,SAAQ,UAAU;IACnB,IAAI,EAAE,mBAAmB,CACpB;IAEJ,UAAU,UAAS;IAC9C,sCAAsC;IACZ,aAAa,SAAoB;IAEjC,KAAK,SAAM;IACX,WAAW,SAAiB;IAC3B,aAAa,UAAS;IACvB,SAAS,EAAE,qBAAqB,CAC5B;IAE9B;;;OAGG;IACuB,SAAS,EAAE,sBAAsB,CAC7B;IAErB,OAAO,CAAC,IAAI,CAAgD;IAC5D,OAAO,CAAC,QAAQ,CAAS;IAGlC,OAAO,CAAC,UAAU,CAAqB;IAGvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAWxB;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAI3B;IAEF,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAIzC;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;IAEF,OAAO,CAAC,YAAY,CAOlB;IAEF,OAAO,CAAC,gBAAgB,CAEtB;IAEF,OAAO,CAAC,UAAU,CAkBhB;IAEF,OAAO,CAAC,WAAW,CAuBjB;IAEF,OAAO,CAAC,OAAO,CAmBb;IAEF,OAAO,CAAC,YAAY,CAElB;IAEF;;;OAGG;IACH,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,YAAY,CAElB;IAEF,OAAO,CAAC,YAAY,CAWlB;IAEF,OAAO,CAAC,aAAa,CAcnB;IAEF,OAAO,CAAC,MAAM,CAQZ;IAEF,OAAO,CAAC,mBAAmB,CAQzB;IAEF,OAAO,CAAC,wBAAwB,CAG9B;IAEF,OAAO,CAAC,sBAAsB;IAuB9B,OAAO,CAAC,gBAAgB;IAmExB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,iBAAiB;IA6DzB,OAAO,CAAC,kCAAkC;IAiD1C,OAAO,CAAC,qBAAqB;IAmC7B,OAAO,CAAC,qBAAqB;cAmCV,MAAM;IA0EzB,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
@@ -89,8 +89,7 @@ let ObcKeyboardFull = class extends LitElement {
89
89
  this.preventFocusLoss = (e) => {
90
90
  e.preventDefault();
91
91
  };
92
- this.onKeyPress = async (key) => {
93
- const char = this.capsLock && this.mode === "abc" && !this.showNumberRow ? key.toUpperCase() : key.toLowerCase();
92
+ this.onKeyPress = async (char) => {
94
93
  const inputElement = this.inputField?.shadowRoot?.querySelector(
95
94
  "input"
96
95
  );
@@ -194,6 +193,13 @@ let ObcKeyboardFull = class extends LitElement {
194
193
  this.dispatchValueChange();
195
194
  };
196
195
  }
196
+ /**
197
+ * The character a letter key both shows and inserts. CAPS applies wherever
198
+ * the alphabetic layout is rendered, including the number-row variant.
199
+ */
200
+ letterKeyLabel(key) {
201
+ return this.capsLock ? key.toUpperCase() : key.toLowerCase();
202
+ }
197
203
  renderCursorNavigation() {
198
204
  return html`
199
205
  <div class="navigation-buttons-container">
@@ -329,18 +335,19 @@ let ObcKeyboardFull = class extends LitElement {
329
335
  ${index === 2 && row.length < 10 ? Array(10 - row.length).fill(0).map(
330
336
  () => html`<div class="key-button-placeholder"></div>`
331
337
  ) : nothing}
332
- ${row.map(
333
- (key) => html`
338
+ ${row.map((key) => {
339
+ const label = this.letterKeyLabel(key);
340
+ return html`
334
341
  <obc-button
335
342
  class="key-button"
336
343
  variant="normal"
337
344
  @mousedown=${this.preventFocusLoss}
338
- @click=${() => this.onKeyPress(key)}
345
+ @click=${() => this.onKeyPress(label)}
339
346
  >
340
- ${this.capsLock ? key.toUpperCase() : key.toLowerCase()}
347
+ ${label}
341
348
  </obc-button>
342
- `
343
- )}
349
+ `;
350
+ })}
344
351
  </div>
345
352
  `
346
353
  )}
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-full.js","sources":["../../../src/components/keyboard-full/keyboard-full.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, state, query} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './keyboard-full.css?inline';\n\nimport '../icon-button/icon-button.js';\nimport '../../icons/icon-close-google.js';\nimport '../../icons/icon-backspace-google.js';\nimport '../../icons/icon-arrow-right-google.js';\nimport '../../icons/icon-arrow-left-google.js';\nimport '../../icons/icon-shift-lock.js';\nimport '../text-input-field/text-input-field.js';\nimport {\n HTMLInputTypeAttribute,\n ObcTextInputField,\n ObcTextInputFieldSize,\n} from '../text-input-field/text-input-field.js';\nimport '../button/button.js';\nimport '../check-button/check-button.js';\n\nexport enum ObcKeyboardFullType {\n Floating = 'floating',\n Flat = 'flat',\n}\n\nexport enum ObcKeyboardFullMode {\n ABC = 'abc',\n Numbers = '123',\n Symbols = 'symbols',\n SymbolsWithNumberRow = 'symbols-with-number-row',\n}\n\n/**\n * `<obc-keyboard-full>` – A comprehensive virtual keyboard component for alphanumeric text input.\n *\n * A full-featured on-screen keyboard that provides QWERTY layout with numeric and symbol modes,\n * designed for touch-screen interfaces where physical keyboards are unavailable or impractical.\n * Includes an integrated text input field with cursor positioning, action buttons for mode switching,\n * and customizable visual presentation.\n *\n * ## Features\n *\n * ### Keyboard Modes\n * The component supports multiple input modes that users can toggle between:\n *\n * - **ABC Mode (QWERTY)**: Standard alphabetic layout with CAPS lock functionality for uppercase/lowercase toggling.\n * When CAPS is enabled, letters appear in uppercase; when disabled, lowercase.\n * - **123 Mode (Numbers)**: Numeric layout (0-9) combined with commonly-used symbols like parentheses,\n * forward/backslash, quotation marks, and mathematical operators.\n * - **Symbols Mode**: Extended symbol set including currency symbols (§, €, £), brackets, mathematical\n * operators, and punctuation marks for specialized input.\n *\n * ### Visual Variants\n *\n * - **Floating (`type=\"floating\"`)**: Default presentation with shadow elevation and rounded corners,\n * appearing to float above the UI. Suitable for modal or overlay contexts.\n * - **Flat (`type=\"flat\"`)**: Minimalist presentation without shadows, designed to integrate seamlessly\n * at the bottom of the screen or within embedded layouts. Uses a top border for subtle separation.\n *\n * ### Layout Configurations\n *\n * - **Standard Layout** (`showNumberRow={false}`): Three-row QWERTY layout with mode toggle buttons\n * (ABC → 123 → Symbols → ABC) and cursor navigation arrows positioned beside the input field.\n * - **Compact Layout with Number Row** (`showNumberRow={true}`): Four-row layout featuring a dedicated\n * number row (1-0) above the QWERTY keys. In this mode, only ABC and Symbols modes are available\n * (no dedicated 123 mode), and cursor navigation arrows relocate to the action button panel on the right.\n *\n * ### Interactive Elements\n *\n * - **Integrated Input Field**: Displays current text value with placeholder support and direct editing capability.\n * - **Cursor Navigation**: Left/right arrow buttons for precise cursor positioning within the text.\n * - **SPACE Bar**: Full-width button for space character insertion at cursor position.\n * - **DEL (Backspace)**: Removes character before cursor position, with visual icon indicator.\n * - **CAPS Button**: Toggles uppercase/lowercase for alphabetic characters (ABC mode only).\n * - **Mode Toggle Button**: Cycles between keyboard modes, showing appropriate label (123, #+=, or ABC).\n * - **DONE Button**: Confirms input completion and dispatches the `done-click` event with final value.\n * - **Close Button** (optional): Appears in top bar when `showTopBar={true}`, dispatches `close-click` event.\n *\n * ### Optional Top Bar\n *\n * When `showTopBar` is enabled, displays a header containing:\n * - Parameter name label (customizable via `parameterName` property) in overline typography style\n * - Close button (icon-button with close icon) aligned to the right\n *\n * ## Usage Guidelines\n *\n * Use `<obc-keyboard-full>` when:\n * - Implementing touch-screen applications where users cannot access physical keyboards\n * - Building kiosk interfaces, embedded systems, or specialized control panels\n * - Creating password entry or secure input fields requiring custom keyboard layouts\n * - Designing applications for environments where on-screen keyboards improve workflow\n * (e.g., gloves-required environments, or where switching between physical keyboard and touchscreen is inefficient)\n *\n * **Layout Decision Guide:**\n * - Use **floating type** for modal dialogs, overlays, or temporary input contexts where the keyboard\n * should appear distinct from underlying content.\n * - Use **flat type** for persistent keyboards anchored to the bottom of the screen or embedded\n * within a fixed layout section.\n * - Enable **showNumberRow** when frequent numeric input is required (passwords, codes, mixed alphanumeric),\n * reducing mode switches. This is ideal for fields like serial numbers, product codes, or passwords\n * containing both letters and numbers.\n * - Disable **showNumberRow** for primarily alphabetic input or when screen space is limited,\n * as standard layout provides more compact dimensions.\n *\n * **Best Practices:**\n * - Always provide meaningful `parameterName` text when `showTopBar` is enabled to give users context\n * about what they're entering (e.g., \"Enter Password\", \"Station Name\", \"Notes\").\n * - Listen for `value-change` events to reactively update your application state as the user types.\n * - Handle `done-click` to process completed input (e.g., submit form, close keyboard, validate entry).\n * - Handle `close-click` to allow users to dismiss the keyboard without completing input\n * (equivalent to \"cancel\" action).\n * - For input fields requiring specific formats (URLs, emails), consider pre-populating `value`\n * with protocol prefixes or domain suffixes, or add validation after `done-click`.\n *\n * **TODO(designer)**: Confirm whether there are recommended timeout behaviors if the keyboard remains\n * idle, or if keyboard should always require explicit close/done action.\n *\n * **TODO(designer)**: Clarify whether `type=\"flat\"` has specific use cases tied to certain application\n * contexts, or if it's purely a visual preference decision.\n *\n * ## Keyboard Interaction Details\n *\n * The component maintains proper cursor position during editing:\n * - Clicking within the input field positions the cursor at that location\n * - Key presses insert characters at the current cursor position (not just at the end)\n * - Backspace removes the character immediately before the cursor\n * - Space bar inserts a space at the cursor position\n * - Arrow buttons move the cursor left/right one character at a time\n *\n * Focus is automatically maintained on the input field during keyboard interactions to prevent\n * focus loss when clicking keyboard buttons (via `@mousedown` prevention).\n *\n * ## Example Usage\n *\n * **Basic floating keyboard:**\n * ```html\n * <obc-keyboard-full\n * parameterName=\"Enter Station Name\"\n * placeholder=\"Type here...\"\n * @value-change=${(e) => console.log('Value:', e.detail.value)}\n * @done-click=${(e) => this.handleSubmit(e.detail.value)}\n * @close-click=${() => this.dismissKeyboard()}\n * >\n * </obc-keyboard-full>\n * ```\n *\n * **Masked password entry:**\n *\n * Set `inputType=\"password\"` to mask the entered value in the input field. A\n * show/hide toggle appears inside the field so users can reveal what they typed.\n * The `value-change` and `done-click` events still carry the real (unmasked)\n * string.\n * ```html\n * <obc-keyboard-full\n * type=\"flat\"\n * inputType=\"password\"\n * parameterName=\"Password\"\n * placeholder=\"Enter password\"\n * showNumberRow\n * showTopBar={false}\n * @done-click=${(e) => this.validatePassword(e.detail.value)}\n * >\n * </obc-keyboard-full>\n * ```\n *\n * **Pre-filled value for editing:**\n * ```html\n * <obc-keyboard-full\n * value=\"Initial text\"\n * parameterName=\"Edit Description\"\n * @value-change=${(e) => this.updateDraft(e.detail.value)}\n * >\n * </obc-keyboard-full>\n * ```\n *\n * @fires {CustomEvent<{value: string}>} value-change - Dispatched whenever the text value changes\n * (on key press, backspace, space, or direct input field editing). The `detail.value` contains\n * the complete current text string.\n * @fires {CustomEvent<{value: string}>} done-click - Dispatched when the DONE button is clicked,\n * indicating the user has completed text entry. The `detail.value` contains the final text string.\n * @fires {CustomEvent<void>} close-click - Dispatched when the close button (in top bar) is clicked,\n * allowing the application to dismiss the keyboard without submitting the value.\n * @beta\n */\n@customElement('obc-keyboard-full')\nexport class ObcKeyboardFull extends LitElement {\n @property({type: String}) type: ObcKeyboardFullType =\n ObcKeyboardFullType.Floating;\n\n @property({type: Boolean}) showTopBar = false;\n /** @availableWhen showTopBar==true */\n @property({type: String}) parameterName = 'Parameter name';\n\n @property({type: String}) value = '';\n @property({type: String}) placeholder = 'Placeholder';\n @property({type: Boolean}) showNumberRow = false;\n @property({type: String}) inputSize: ObcTextInputFieldSize =\n ObcTextInputFieldSize.Large;\n\n /**\n * Input type forwarded to the embedded input field. Set to `password` to mask\n * the entered value (a show/hide toggle is then shown inside the field).\n */\n @property({type: String}) inputType: HTMLInputTypeAttribute =\n HTMLInputTypeAttribute.Text;\n\n @state() private mode: ObcKeyboardFullMode = ObcKeyboardFullMode.ABC;\n @state() private capsLock = false;\n\n @query('obc-text-input-field')\n private inputField!: ObcTextInputField;\n\n // Keyboard layouts\n private readonly numberRow = [\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n '0',\n ];\n\n private readonly qwertyLayout = [\n ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],\n ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],\n ['Z', 'X', 'C', 'V', 'B', 'N', 'M', '.', '-'],\n ];\n\n private readonly symbolsWithNumberRowLayout = [\n ['$', '[', ']', '{', '}', '#', '^', '*', '='],\n ['\"', '+', '(', ')', '/', '\\\\', '&', '%', '@'],\n [\"'\", '?', '!', ';', ':', '\"', ',', '.', '-'],\n ];\n\n private readonly numbersLayout = [\n ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],\n ['\"', '+', '(', ')', '/', '\\\\', '&', '%', '@'],\n [\"'\", '?', '!', ';', ':', '\"', ',', '.', '-'],\n ];\n\n private readonly symbolsLayout = [\n ['§', '[', ']', '{', '}', '#', '^', '*', '='],\n ['~', '_', '|', '<', '>', '$', '€', '£'],\n ['\"', \"'\", '?', '!', ';', ':', ',', '.', '-'],\n ];\n\n private onCloseClick = () => {\n this.dispatchEvent(\n new CustomEvent('close-click', {\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private preventFocusLoss = (e: MouseEvent) => {\n e.preventDefault();\n };\n\n private onKeyPress = async (key: string) => {\n const char =\n this.capsLock &&\n this.mode === ObcKeyboardFullMode.ABC &&\n !this.showNumberRow\n ? key.toUpperCase()\n : key.toLowerCase();\n\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (inputElement && inputElement.selectionStart !== null) {\n const cursorPos = inputElement.selectionStart;\n this.value =\n this.value.slice(0, cursorPos) + char + this.value.slice(cursorPos);\n this.dispatchValueChange();\n\n // Move cursor forward after insertion\n await this.updateComplete;\n inputElement.focus();\n inputElement.setSelectionRange(cursorPos + 1, cursorPos + 1);\n } else {\n this.value += char;\n this.dispatchValueChange();\n }\n };\n\n private onBackspace = async () => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (\n inputElement &&\n inputElement.selectionStart !== null &&\n inputElement.selectionStart > 0\n ) {\n const cursorPos = inputElement.selectionStart;\n this.value =\n this.value.slice(0, cursorPos - 1) + this.value.slice(cursorPos);\n this.dispatchValueChange();\n\n // Move cursor back after deletion\n await this.updateComplete;\n inputElement.focus();\n inputElement.setSelectionRange(cursorPos - 1, cursorPos - 1);\n } else if (this.value.length > 0 && !inputElement) {\n // Fallback: remove from end\n this.value = this.value.slice(0, -1);\n this.dispatchValueChange();\n }\n };\n\n private onSpace = async () => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (inputElement && inputElement.selectionStart !== null) {\n const cursorPos = inputElement.selectionStart;\n this.value =\n this.value.slice(0, cursorPos) + ' ' + this.value.slice(cursorPos);\n this.dispatchValueChange();\n\n // Move cursor forward after insertion\n await this.updateComplete;\n inputElement.focus();\n inputElement.setSelectionRange(cursorPos + 1, cursorPos + 1);\n } else {\n // Fallback: append to end\n this.value += ' ';\n this.dispatchValueChange();\n }\n };\n\n private onToggleCaps = () => {\n this.capsLock = !this.capsLock;\n };\n\n private onToggleMode = (mode: ObcKeyboardFullMode) => {\n this.mode = mode;\n };\n\n private onCursorLeft = () => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (inputElement) {\n inputElement.focus();\n if (inputElement.selectionStart !== null) {\n const newPosition = Math.max(0, inputElement.selectionStart - 1);\n inputElement.setSelectionRange(newPosition, newPosition);\n }\n }\n };\n\n private onCursorRight = () => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (inputElement) {\n inputElement.focus();\n if (inputElement.selectionStart !== null) {\n const newPosition = Math.min(\n this.value.length,\n inputElement.selectionStart + 1\n );\n inputElement.setSelectionRange(newPosition, newPosition);\n }\n }\n };\n\n private onDone = () => {\n this.dispatchEvent(\n new CustomEvent('done-click', {\n detail: {value: this.value},\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private dispatchValueChange = () => {\n this.dispatchEvent(\n new CustomEvent('value-change', {\n detail: {value: this.value},\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private onInputFieldValueChanged = (e: Event) => {\n this.value = (e.target as ObcTextInputField).value;\n this.dispatchValueChange();\n };\n\n private renderCursorNavigation() {\n return html`\n <div class=\"navigation-buttons-container\">\n <obc-icon-button\n variant=\"normal\"\n cornerLeft\n @mousedown=${this.preventFocusLoss}\n @click=${this.onCursorLeft}\n >\n <obi-arrow-left-google></obi-arrow-left-google>\n </obc-icon-button>\n <obc-icon-button\n variant=\"normal\"\n cornerRight\n @mousedown=${this.preventFocusLoss}\n @click=${this.onCursorRight}\n >\n <obi-arrow-right-google></obi-arrow-right-google>\n </obc-icon-button>\n </div>\n `;\n }\n\n private renderModeButton() {\n if (this.showNumberRow) {\n // Toggle between QWERTY and Symbols when number row is visible\n return this.mode === ObcKeyboardFullMode.ABC\n ? html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() =>\n this.onToggleMode(ObcKeyboardFullMode.SymbolsWithNumberRow)}\n >\n #+=\n </obc-button>\n `\n : html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onToggleMode(ObcKeyboardFullMode.ABC)}\n >\n ABC\n </obc-button>\n `;\n }\n\n // Standard mode: cycle through ABC → Numbers → Symbols → ABC\n if (this.mode === ObcKeyboardFullMode.ABC) {\n return html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onToggleMode(ObcKeyboardFullMode.Numbers)}\n >\n 123\n </obc-button>\n `;\n }\n\n if (this.mode === ObcKeyboardFullMode.Numbers) {\n return html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onToggleMode(ObcKeyboardFullMode.Symbols)}\n >\n #+=\n </obc-button>\n `;\n }\n\n // Symbols mode\n return html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onToggleMode(ObcKeyboardFullMode.ABC)}\n >\n ABC\n </obc-button>\n `;\n }\n\n private renderKeyboard() {\n if (this.showNumberRow) {\n return this.mode === ObcKeyboardFullMode.SymbolsWithNumberRow\n ? this.renderSymbolsWithNumberRowKeyboard()\n : this.renderABCKeyboard();\n }\n\n switch (this.mode) {\n case ObcKeyboardFullMode.ABC:\n return this.renderABCKeyboard();\n case ObcKeyboardFullMode.Numbers:\n return this.renderNumbersKeyboard();\n case ObcKeyboardFullMode.Symbols:\n return this.renderSymbolsKeyboard();\n default:\n return this.renderABCKeyboard();\n }\n }\n\n private renderABCKeyboard() {\n return html`\n <div class=\"container-left\">\n <div class=\"keys-container\">\n ${this.showNumberRow\n ? html`\n <div class=\"row row-numbers\">\n ${this.numberRow.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"raised\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n `\n : nothing}\n ${this.qwertyLayout.map(\n (row, index) => html`\n <div class=\"row row-${index + 1}\">\n ${index === 2 && row.length < 10\n ? Array(10 - row.length)\n .fill(0)\n .map(\n () => html`<div class=\"key-button-placeholder\"></div>`\n )\n : nothing}\n ${row.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${this.capsLock ? key.toUpperCase() : key.toLowerCase()}\n </obc-button>\n `\n )}\n </div>\n `\n )}\n </div>\n <obc-button\n ?fullWidth=${true}\n class=\"space-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onSpace}\n >\n SPACE\n </obc-button>\n </div>\n `;\n }\n\n private renderSymbolsWithNumberRowKeyboard() {\n return html`\n <div class=\"container-left\">\n <div class=\"keys-container\">\n <div class=\"row row-numbers\">\n ${this.numberRow.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"raised\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n ${this.symbolsWithNumberRowLayout.map(\n (row, index) => html`\n <div class=\"row row-${index + 1}\">\n ${row.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n `\n )}\n </div>\n <obc-button\n ?fullWidth=${true}\n class=\"space-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onSpace}\n >\n SPACE\n </obc-button>\n </div>\n `;\n }\n\n private renderNumbersKeyboard() {\n return html`\n <div class=\"container-left\">\n <div class=\"keys-container\">\n ${this.numbersLayout.map(\n (row, index) => html`\n <div class=\"row row-${index + 1}\">\n ${row.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n `\n )}\n </div>\n <obc-button\n ?fullWidth=${true}\n class=\"space-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onSpace}\n >\n SPACE\n </obc-button>\n </div>\n `;\n }\n\n private renderSymbolsKeyboard() {\n return html`\n <div class=\"container-left\">\n <div class=\"keys-container\">\n ${this.symbolsLayout.map(\n (row, index) => html`\n <div class=\"row row-${index + 1}\">\n ${row.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n `\n )}\n </div>\n <obc-button\n ?fullWidth=${true}\n class=\"space-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onSpace}\n >\n SPACE\n </obc-button>\n </div>\n `;\n }\n\n protected override render() {\n return html`\n <div class=\"wrapper type-${this.type}\">\n ${this.showTopBar\n ? html`\n <div class=\"top-bar\">\n <div class=\"parameter-name\">${this.parameterName}</div>\n <obc-icon-button variant=\"flat\" @click=${this.onCloseClick}>\n <obi-close-google></obi-close-google>\n </obc-icon-button>\n </div>\n `\n : nothing}\n\n <div class=\"container-content\">\n <div class=\"input-container\">\n <obc-text-input-field\n class=\"input-field\"\n .value=${this.value}\n .placeholder=${this.placeholder}\n .size=${this.inputSize}\n .type=${this.inputType}\n @input=${this.onInputFieldValueChanged}\n >\n </obc-text-input-field>\n\n ${!this.showNumberRow ? this.renderCursorNavigation() : nothing}\n </div>\n\n <div class=\"container-keyboard\">\n ${this.renderKeyboard()}\n\n <div class=\"container-right\">\n ${this.showNumberRow ? this.renderCursorNavigation() : nothing}\n\n <obc-button\n class=\"action-button delete-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onBackspace}\n showLeadingIcon\n >\n <obi-backspace-google slot=\"leading-icon\"></obi-backspace-google\n >DEL\n </obc-button>\n\n <obc-check-button\n class=\"action-button caps-button\"\n type=\"regular\"\n ?checked=${this.capsLock}\n @mousedown=${this.preventFocusLoss}\n @click=${this.onToggleCaps}\n ?showIcon=${true}\n >\n <obi-shift-lock slot=\"icon\"></obi-shift-lock>\n CAPS\n </obc-check-button>\n\n ${this.renderModeButton()}\n\n <obc-button\n class=\"action-button done-button\"\n variant=\"raised\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onDone}\n >\n DONE\n </obc-button>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-keyboard-full': ObcKeyboardFull;\n }\n}\n"],"names":["ObcKeyboardFullType","ObcKeyboardFullMode"],"mappings":"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"}
1
+ {"version":3,"file":"keyboard-full.js","sources":["../../../src/components/keyboard-full/keyboard-full.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property, state, query} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './keyboard-full.css?inline';\n\nimport '../icon-button/icon-button.js';\nimport '../../icons/icon-close-google.js';\nimport '../../icons/icon-backspace-google.js';\nimport '../../icons/icon-arrow-right-google.js';\nimport '../../icons/icon-arrow-left-google.js';\nimport '../../icons/icon-shift-lock.js';\nimport '../text-input-field/text-input-field.js';\nimport {\n HTMLInputTypeAttribute,\n ObcTextInputField,\n ObcTextInputFieldSize,\n} from '../text-input-field/text-input-field.js';\nimport '../button/button.js';\nimport '../check-button/check-button.js';\n\nexport enum ObcKeyboardFullType {\n Floating = 'floating',\n Flat = 'flat',\n}\n\nexport enum ObcKeyboardFullMode {\n ABC = 'abc',\n Numbers = '123',\n Symbols = 'symbols',\n SymbolsWithNumberRow = 'symbols-with-number-row',\n}\n\n/**\n * `<obc-keyboard-full>` – A comprehensive virtual keyboard component for alphanumeric text input.\n *\n * A full-featured on-screen keyboard that provides QWERTY layout with numeric and symbol modes,\n * designed for touch-screen interfaces where physical keyboards are unavailable or impractical.\n * Includes an integrated text input field with cursor positioning, action buttons for mode switching,\n * and customizable visual presentation.\n *\n * ## Features\n *\n * ### Keyboard Modes\n * The component supports multiple input modes that users can toggle between:\n *\n * - **ABC Mode (QWERTY)**: Standard alphabetic layout with CAPS lock functionality for uppercase/lowercase toggling.\n * When CAPS is enabled, letters appear in uppercase; when disabled, lowercase.\n * - **123 Mode (Numbers)**: Numeric layout (0-9) combined with commonly-used symbols like parentheses,\n * forward/backslash, quotation marks, and mathematical operators.\n * - **Symbols Mode**: Extended symbol set including currency symbols (§, €, £), brackets, mathematical\n * operators, and punctuation marks for specialized input.\n *\n * ### Visual Variants\n *\n * - **Floating (`type=\"floating\"`)**: Default presentation with shadow elevation and rounded corners,\n * appearing to float above the UI. Suitable for modal or overlay contexts.\n * - **Flat (`type=\"flat\"`)**: Minimalist presentation without shadows, designed to integrate seamlessly\n * at the bottom of the screen or within embedded layouts. Uses a top border for subtle separation.\n *\n * ### Layout Configurations\n *\n * - **Standard Layout** (`showNumberRow={false}`): Three-row QWERTY layout with mode toggle buttons\n * (ABC → 123 → Symbols → ABC) and cursor navigation arrows positioned beside the input field.\n * - **Compact Layout with Number Row** (`showNumberRow={true}`): Four-row layout featuring a dedicated\n * number row (1-0) above the QWERTY keys. In this mode, only ABC and Symbols modes are available\n * (no dedicated 123 mode), and cursor navigation arrows relocate to the action button panel on the right.\n *\n * ### Interactive Elements\n *\n * - **Integrated Input Field**: Displays current text value with placeholder support and direct editing capability.\n * - **Cursor Navigation**: Left/right arrow buttons for precise cursor positioning within the text.\n * - **SPACE Bar**: Full-width button for space character insertion at cursor position.\n * - **DEL (Backspace)**: Removes character before cursor position, with visual icon indicator.\n * - **CAPS Button**: Toggles uppercase/lowercase for alphabetic characters (ABC mode only).\n * - **Mode Toggle Button**: Cycles between keyboard modes, showing appropriate label (123, #+=, or ABC).\n * - **DONE Button**: Confirms input completion and dispatches the `done-click` event with final value.\n * - **Close Button** (optional): Appears in top bar when `showTopBar={true}`, dispatches `close-click` event.\n *\n * ### Optional Top Bar\n *\n * When `showTopBar` is enabled, displays a header containing:\n * - Parameter name label (customizable via `parameterName` property) in overline typography style\n * - Close button (icon-button with close icon) aligned to the right\n *\n * ## Usage Guidelines\n *\n * Use `<obc-keyboard-full>` when:\n * - Implementing touch-screen applications where users cannot access physical keyboards\n * - Building kiosk interfaces, embedded systems, or specialized control panels\n * - Creating password entry or secure input fields requiring custom keyboard layouts\n * - Designing applications for environments where on-screen keyboards improve workflow\n * (e.g., gloves-required environments, or where switching between physical keyboard and touchscreen is inefficient)\n *\n * **Layout Decision Guide:**\n * - Use **floating type** for modal dialogs, overlays, or temporary input contexts where the keyboard\n * should appear distinct from underlying content.\n * - Use **flat type** for persistent keyboards anchored to the bottom of the screen or embedded\n * within a fixed layout section.\n * - Enable **showNumberRow** when frequent numeric input is required (passwords, codes, mixed alphanumeric),\n * reducing mode switches. This is ideal for fields like serial numbers, product codes, or passwords\n * containing both letters and numbers.\n * - Disable **showNumberRow** for primarily alphabetic input or when screen space is limited,\n * as standard layout provides more compact dimensions.\n *\n * **Best Practices:**\n * - Always provide meaningful `parameterName` text when `showTopBar` is enabled to give users context\n * about what they're entering (e.g., \"Enter Password\", \"Station Name\", \"Notes\").\n * - Listen for `value-change` events to reactively update your application state as the user types.\n * - Handle `done-click` to process completed input (e.g., submit form, close keyboard, validate entry).\n * - Handle `close-click` to allow users to dismiss the keyboard without completing input\n * (equivalent to \"cancel\" action).\n * - For input fields requiring specific formats (URLs, emails), consider pre-populating `value`\n * with protocol prefixes or domain suffixes, or add validation after `done-click`.\n *\n * **TODO(designer)**: Confirm whether there are recommended timeout behaviors if the keyboard remains\n * idle, or if keyboard should always require explicit close/done action.\n *\n * **TODO(designer)**: Clarify whether `type=\"flat\"` has specific use cases tied to certain application\n * contexts, or if it's purely a visual preference decision.\n *\n * ## Keyboard Interaction Details\n *\n * The component maintains proper cursor position during editing:\n * - Clicking within the input field positions the cursor at that location\n * - Key presses insert characters at the current cursor position (not just at the end)\n * - Backspace removes the character immediately before the cursor\n * - Space bar inserts a space at the cursor position\n * - Arrow buttons move the cursor left/right one character at a time\n *\n * Focus is automatically maintained on the input field during keyboard interactions to prevent\n * focus loss when clicking keyboard buttons (via `@mousedown` prevention).\n *\n * ## Example Usage\n *\n * **Basic floating keyboard:**\n * ```html\n * <obc-keyboard-full\n * parameterName=\"Enter Station Name\"\n * placeholder=\"Type here...\"\n * @value-change=${(e) => console.log('Value:', e.detail.value)}\n * @done-click=${(e) => this.handleSubmit(e.detail.value)}\n * @close-click=${() => this.dismissKeyboard()}\n * >\n * </obc-keyboard-full>\n * ```\n *\n * **Masked password entry:**\n *\n * Set `inputType=\"password\"` to mask the entered value in the input field. A\n * show/hide toggle appears inside the field so users can reveal what they typed.\n * The `value-change` and `done-click` events still carry the real (unmasked)\n * string.\n * ```html\n * <obc-keyboard-full\n * type=\"flat\"\n * inputType=\"password\"\n * parameterName=\"Password\"\n * placeholder=\"Enter password\"\n * showNumberRow\n * showTopBar={false}\n * @done-click=${(e) => this.validatePassword(e.detail.value)}\n * >\n * </obc-keyboard-full>\n * ```\n *\n * **Pre-filled value for editing:**\n * ```html\n * <obc-keyboard-full\n * value=\"Initial text\"\n * parameterName=\"Edit Description\"\n * @value-change=${(e) => this.updateDraft(e.detail.value)}\n * >\n * </obc-keyboard-full>\n * ```\n *\n * @fires {CustomEvent<{value: string}>} value-change - Dispatched whenever the text value changes\n * (on key press, backspace, space, or direct input field editing). The `detail.value` contains\n * the complete current text string.\n * @fires {CustomEvent<{value: string}>} done-click - Dispatched when the DONE button is clicked,\n * indicating the user has completed text entry. The `detail.value` contains the final text string.\n * @fires {CustomEvent<void>} close-click - Dispatched when the close button (in top bar) is clicked,\n * allowing the application to dismiss the keyboard without submitting the value.\n * @beta\n */\n@customElement('obc-keyboard-full')\nexport class ObcKeyboardFull extends LitElement {\n @property({type: String}) type: ObcKeyboardFullType =\n ObcKeyboardFullType.Floating;\n\n @property({type: Boolean}) showTopBar = false;\n /** @availableWhen showTopBar==true */\n @property({type: String}) parameterName = 'Parameter name';\n\n @property({type: String}) value = '';\n @property({type: String}) placeholder = 'Placeholder';\n @property({type: Boolean}) showNumberRow = false;\n @property({type: String}) inputSize: ObcTextInputFieldSize =\n ObcTextInputFieldSize.Large;\n\n /**\n * Input type forwarded to the embedded input field. Set to `password` to mask\n * the entered value (a show/hide toggle is then shown inside the field).\n */\n @property({type: String}) inputType: HTMLInputTypeAttribute =\n HTMLInputTypeAttribute.Text;\n\n @state() private mode: ObcKeyboardFullMode = ObcKeyboardFullMode.ABC;\n @state() private capsLock = false;\n\n @query('obc-text-input-field')\n private inputField!: ObcTextInputField;\n\n // Keyboard layouts\n private readonly numberRow = [\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n '0',\n ];\n\n private readonly qwertyLayout = [\n ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],\n ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],\n ['Z', 'X', 'C', 'V', 'B', 'N', 'M', '.', '-'],\n ];\n\n private readonly symbolsWithNumberRowLayout = [\n ['$', '[', ']', '{', '}', '#', '^', '*', '='],\n ['\"', '+', '(', ')', '/', '\\\\', '&', '%', '@'],\n [\"'\", '?', '!', ';', ':', '\"', ',', '.', '-'],\n ];\n\n private readonly numbersLayout = [\n ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],\n ['\"', '+', '(', ')', '/', '\\\\', '&', '%', '@'],\n [\"'\", '?', '!', ';', ':', '\"', ',', '.', '-'],\n ];\n\n private readonly symbolsLayout = [\n ['§', '[', ']', '{', '}', '#', '^', '*', '='],\n ['~', '_', '|', '<', '>', '$', '€', '£'],\n ['\"', \"'\", '?', '!', ';', ':', ',', '.', '-'],\n ];\n\n private onCloseClick = () => {\n this.dispatchEvent(\n new CustomEvent('close-click', {\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private preventFocusLoss = (e: MouseEvent) => {\n e.preventDefault();\n };\n\n private onKeyPress = async (char: string) => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (inputElement && inputElement.selectionStart !== null) {\n const cursorPos = inputElement.selectionStart;\n this.value =\n this.value.slice(0, cursorPos) + char + this.value.slice(cursorPos);\n this.dispatchValueChange();\n\n // Move cursor forward after insertion\n await this.updateComplete;\n inputElement.focus();\n inputElement.setSelectionRange(cursorPos + 1, cursorPos + 1);\n } else {\n this.value += char;\n this.dispatchValueChange();\n }\n };\n\n private onBackspace = async () => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (\n inputElement &&\n inputElement.selectionStart !== null &&\n inputElement.selectionStart > 0\n ) {\n const cursorPos = inputElement.selectionStart;\n this.value =\n this.value.slice(0, cursorPos - 1) + this.value.slice(cursorPos);\n this.dispatchValueChange();\n\n // Move cursor back after deletion\n await this.updateComplete;\n inputElement.focus();\n inputElement.setSelectionRange(cursorPos - 1, cursorPos - 1);\n } else if (this.value.length > 0 && !inputElement) {\n // Fallback: remove from end\n this.value = this.value.slice(0, -1);\n this.dispatchValueChange();\n }\n };\n\n private onSpace = async () => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (inputElement && inputElement.selectionStart !== null) {\n const cursorPos = inputElement.selectionStart;\n this.value =\n this.value.slice(0, cursorPos) + ' ' + this.value.slice(cursorPos);\n this.dispatchValueChange();\n\n // Move cursor forward after insertion\n await this.updateComplete;\n inputElement.focus();\n inputElement.setSelectionRange(cursorPos + 1, cursorPos + 1);\n } else {\n // Fallback: append to end\n this.value += ' ';\n this.dispatchValueChange();\n }\n };\n\n private onToggleCaps = () => {\n this.capsLock = !this.capsLock;\n };\n\n /**\n * The character a letter key both shows and inserts. CAPS applies wherever\n * the alphabetic layout is rendered, including the number-row variant.\n */\n private letterKeyLabel(key: string): string {\n return this.capsLock ? key.toUpperCase() : key.toLowerCase();\n }\n\n private onToggleMode = (mode: ObcKeyboardFullMode) => {\n this.mode = mode;\n };\n\n private onCursorLeft = () => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (inputElement) {\n inputElement.focus();\n if (inputElement.selectionStart !== null) {\n const newPosition = Math.max(0, inputElement.selectionStart - 1);\n inputElement.setSelectionRange(newPosition, newPosition);\n }\n }\n };\n\n private onCursorRight = () => {\n const inputElement = this.inputField?.shadowRoot?.querySelector(\n 'input'\n ) as HTMLInputElement | null;\n if (inputElement) {\n inputElement.focus();\n if (inputElement.selectionStart !== null) {\n const newPosition = Math.min(\n this.value.length,\n inputElement.selectionStart + 1\n );\n inputElement.setSelectionRange(newPosition, newPosition);\n }\n }\n };\n\n private onDone = () => {\n this.dispatchEvent(\n new CustomEvent('done-click', {\n detail: {value: this.value},\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private dispatchValueChange = () => {\n this.dispatchEvent(\n new CustomEvent('value-change', {\n detail: {value: this.value},\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private onInputFieldValueChanged = (e: Event) => {\n this.value = (e.target as ObcTextInputField).value;\n this.dispatchValueChange();\n };\n\n private renderCursorNavigation() {\n return html`\n <div class=\"navigation-buttons-container\">\n <obc-icon-button\n variant=\"normal\"\n cornerLeft\n @mousedown=${this.preventFocusLoss}\n @click=${this.onCursorLeft}\n >\n <obi-arrow-left-google></obi-arrow-left-google>\n </obc-icon-button>\n <obc-icon-button\n variant=\"normal\"\n cornerRight\n @mousedown=${this.preventFocusLoss}\n @click=${this.onCursorRight}\n >\n <obi-arrow-right-google></obi-arrow-right-google>\n </obc-icon-button>\n </div>\n `;\n }\n\n private renderModeButton() {\n if (this.showNumberRow) {\n // Toggle between QWERTY and Symbols when number row is visible\n return this.mode === ObcKeyboardFullMode.ABC\n ? html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() =>\n this.onToggleMode(ObcKeyboardFullMode.SymbolsWithNumberRow)}\n >\n #+=\n </obc-button>\n `\n : html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onToggleMode(ObcKeyboardFullMode.ABC)}\n >\n ABC\n </obc-button>\n `;\n }\n\n // Standard mode: cycle through ABC → Numbers → Symbols → ABC\n if (this.mode === ObcKeyboardFullMode.ABC) {\n return html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onToggleMode(ObcKeyboardFullMode.Numbers)}\n >\n 123\n </obc-button>\n `;\n }\n\n if (this.mode === ObcKeyboardFullMode.Numbers) {\n return html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onToggleMode(ObcKeyboardFullMode.Symbols)}\n >\n #+=\n </obc-button>\n `;\n }\n\n // Symbols mode\n return html`\n <obc-button\n class=\"action-button mode-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onToggleMode(ObcKeyboardFullMode.ABC)}\n >\n ABC\n </obc-button>\n `;\n }\n\n private renderKeyboard() {\n if (this.showNumberRow) {\n return this.mode === ObcKeyboardFullMode.SymbolsWithNumberRow\n ? this.renderSymbolsWithNumberRowKeyboard()\n : this.renderABCKeyboard();\n }\n\n switch (this.mode) {\n case ObcKeyboardFullMode.ABC:\n return this.renderABCKeyboard();\n case ObcKeyboardFullMode.Numbers:\n return this.renderNumbersKeyboard();\n case ObcKeyboardFullMode.Symbols:\n return this.renderSymbolsKeyboard();\n default:\n return this.renderABCKeyboard();\n }\n }\n\n private renderABCKeyboard() {\n return html`\n <div class=\"container-left\">\n <div class=\"keys-container\">\n ${this.showNumberRow\n ? html`\n <div class=\"row row-numbers\">\n ${this.numberRow.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"raised\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n `\n : nothing}\n ${this.qwertyLayout.map(\n (row, index) => html`\n <div class=\"row row-${index + 1}\">\n ${index === 2 && row.length < 10\n ? Array(10 - row.length)\n .fill(0)\n .map(\n () => html`<div class=\"key-button-placeholder\"></div>`\n )\n : nothing}\n ${row.map((key) => {\n const label = this.letterKeyLabel(key);\n return html`\n <obc-button\n class=\"key-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(label)}\n >\n ${label}\n </obc-button>\n `;\n })}\n </div>\n `\n )}\n </div>\n <obc-button\n ?fullWidth=${true}\n class=\"space-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onSpace}\n >\n SPACE\n </obc-button>\n </div>\n `;\n }\n\n private renderSymbolsWithNumberRowKeyboard() {\n return html`\n <div class=\"container-left\">\n <div class=\"keys-container\">\n <div class=\"row row-numbers\">\n ${this.numberRow.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"raised\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n ${this.symbolsWithNumberRowLayout.map(\n (row, index) => html`\n <div class=\"row row-${index + 1}\">\n ${row.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n `\n )}\n </div>\n <obc-button\n ?fullWidth=${true}\n class=\"space-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onSpace}\n >\n SPACE\n </obc-button>\n </div>\n `;\n }\n\n private renderNumbersKeyboard() {\n return html`\n <div class=\"container-left\">\n <div class=\"keys-container\">\n ${this.numbersLayout.map(\n (row, index) => html`\n <div class=\"row row-${index + 1}\">\n ${row.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n `\n )}\n </div>\n <obc-button\n ?fullWidth=${true}\n class=\"space-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onSpace}\n >\n SPACE\n </obc-button>\n </div>\n `;\n }\n\n private renderSymbolsKeyboard() {\n return html`\n <div class=\"container-left\">\n <div class=\"keys-container\">\n ${this.symbolsLayout.map(\n (row, index) => html`\n <div class=\"row row-${index + 1}\">\n ${row.map(\n (key) => html`\n <obc-button\n class=\"key-button\"\n variant=\"normal\"\n @mousedown=${this.preventFocusLoss}\n @click=${() => this.onKeyPress(key)}\n >\n ${key}\n </obc-button>\n `\n )}\n </div>\n `\n )}\n </div>\n <obc-button\n ?fullWidth=${true}\n class=\"space-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onSpace}\n >\n SPACE\n </obc-button>\n </div>\n `;\n }\n\n protected override render() {\n return html`\n <div class=\"wrapper type-${this.type}\">\n ${this.showTopBar\n ? html`\n <div class=\"top-bar\">\n <div class=\"parameter-name\">${this.parameterName}</div>\n <obc-icon-button variant=\"flat\" @click=${this.onCloseClick}>\n <obi-close-google></obi-close-google>\n </obc-icon-button>\n </div>\n `\n : nothing}\n\n <div class=\"container-content\">\n <div class=\"input-container\">\n <obc-text-input-field\n class=\"input-field\"\n .value=${this.value}\n .placeholder=${this.placeholder}\n .size=${this.inputSize}\n .type=${this.inputType}\n @input=${this.onInputFieldValueChanged}\n >\n </obc-text-input-field>\n\n ${!this.showNumberRow ? this.renderCursorNavigation() : nothing}\n </div>\n\n <div class=\"container-keyboard\">\n ${this.renderKeyboard()}\n\n <div class=\"container-right\">\n ${this.showNumberRow ? this.renderCursorNavigation() : nothing}\n\n <obc-button\n class=\"action-button delete-button\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onBackspace}\n showLeadingIcon\n >\n <obi-backspace-google slot=\"leading-icon\"></obi-backspace-google\n >DEL\n </obc-button>\n\n <obc-check-button\n class=\"action-button caps-button\"\n type=\"regular\"\n ?checked=${this.capsLock}\n @mousedown=${this.preventFocusLoss}\n @click=${this.onToggleCaps}\n ?showIcon=${true}\n >\n <obi-shift-lock slot=\"icon\"></obi-shift-lock>\n CAPS\n </obc-check-button>\n\n ${this.renderModeButton()}\n\n <obc-button\n class=\"action-button done-button\"\n variant=\"raised\"\n @mousedown=${this.preventFocusLoss}\n @click=${this.onDone}\n >\n DONE\n </obc-button>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-keyboard-full': ObcKeyboardFull;\n }\n}\n"],"names":["ObcKeyboardFullType","ObcKeyboardFullMode"],"mappings":"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"}
@@ -109,6 +109,21 @@ const componentStyle = css`* {
109
109
  cursor: not-allowed;
110
110
  }
111
111
 
112
+ /* A read-only field is still focusable and selectable, but it accepts no
113
+ edits — so it must not advertise the hover/pressed affordances that
114
+ \`@mixin style\` renders. Zeroing --obc-can-hover makes the mixin's hover
115
+ colour-mix collapse back onto the enabled colours; the pressed state has
116
+ no such switch and is restored explicitly. */
117
+
118
+ .wrapper.readonly {
119
+ --obc-can-hover: 0;
120
+ }
121
+
122
+ .wrapper.readonly:not(.disabled):active .input-field-container {
123
+ border-color: var(--normal-enabled-border-color);
124
+ background: var(--normal-enabled-background-color);
125
+ }
126
+
112
127
  .wrapper.helpertext,.wrapper.haslabel {
113
128
  flex-direction: column;
114
129
  align-items: flex-start;
@@ -119,6 +134,10 @@ const componentStyle = css`* {
119
134
  background: var(--container-background-color);
120
135
  }
121
136
 
137
+ .wrapper.readonly.empty:not(.disabled):active .input-field-container {
138
+ background: var(--container-background-color);
139
+ }
140
+
122
141
  .wrapper.empty:not(.disabled):focus-within .input-field-container {
123
142
  background: var(--normal-enabled-background-color);
124
143
  }
@@ -1 +1 @@
1
- {"version":3,"file":"number-input-field.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"number-input-field.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"number-input-field.d.ts","sourceRoot":"","sources":["../../../src/components/number-input-field/number-input-field.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"number-input-field.d.ts","sourceRoot":"","sources":["../../../src/components/number-input-field/number-input-field.ts"],"names":[],"mappings":"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"}
@@ -121,6 +121,7 @@ let ObcNumberInputField = class extends LitElement {
121
121
  }
122
122
  onFocus() {
123
123
  this.hasFocus = true;
124
+ if (this.readonly) return;
124
125
  const source = this.displayOverride || this.displayText;
125
126
  this.displayText = removeGroupingFromDisplay(
126
127
  source,
@@ -130,6 +131,7 @@ let ObcNumberInputField = class extends LitElement {
130
131
  }
131
132
  onBlur() {
132
133
  this.hasFocus = false;
134
+ if (this.readonly) return;
133
135
  this.commitDisplay();
134
136
  if (!valuesEqual(this.value, this.lastCommittedValue)) {
135
137
  this.lastCommittedValue = this.value;
@@ -302,6 +304,7 @@ let ObcNumberInputField = class extends LitElement {
302
304
  [`size-${this.size}`]: true,
303
305
  error: this.error,
304
306
  disabled: this.disabled,
307
+ readonly: this.readonly,
305
308
  empty: this.isEmpty,
306
309
  helpertext: hasHelperOrError,
307
310
  haslabel: Boolean(this.label),
@@ -1 +1 @@
1
- {"version":3,"file":"number-input-field.js","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 * @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 /** @availableWhen error==true */\n @property({type: String}) errorText = '';\n /** If true, the input field will not update its value on focus */\n @property({type: Boolean}) rejectUpdatesOnFocus = false;\n /** If true, the value will only be initially set, and not updated on change */\n @property({type: Boolean}) rejectUpdates = false;\n\n /** 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 */\n @property({type: Boolean}) rejectDuplicateUpdates = false;\n\n /** Name attribute for form integration */\n @property({type: String}) name = '';\n\n /** Maximum number of characters allowed */\n @property({type: Number}) maxlength?: number;\n\n /** Minimum number of characters required */\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 /** @availableWhen label!='' */\n @property({type: Boolean}) hasLabelIcon = false;\n /** @availableWhen label!='' */\n @property({type: String}) labelPlacement: ObcNumberInputFieldPlacement =\n ObcNumberInputFieldPlacement.Left;\n\n /** @availableWhen helperText!='' || (error==true && errorText!='') */\n @property({type: Boolean}) hasHelperIcon = false;\n /** @availableWhen helperText!='' || (error==true && errorText!='') */\n @property({type: String}) helperPlacement: ObcNumberInputFieldPlacement =\n ObcNumberInputFieldPlacement.Left;\n\n /** Internal property for squared corners, used when input is used in stepper-box */\n @property({type: Boolean}) squared = false;\n\n /**\n * Optional display text override for controlled consumers (e.g. keyboard-numeric)\n * that manage formatted strings while the committed value may be NaN.\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 /**\n * 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 */\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 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 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 ${this.hasHelperIcon\n ? html`<div class=\"helper-icon\"><slot name=\"helper-icon\"></slot></div>`\n : nothing}\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 empty: this.isEmpty,\n helpertext: hasHelperOrError,\n haslabel: Boolean(this.label),\n squared: this.squared,\n })}\n @pointerdown=${this.onPointerDown}\n >\n ${this.label\n ? html`<div\n class=${classMap({\n 'label-text-container': true,\n [`label-placement-${this.labelPlacement}`]: true,\n })}\n >\n ${this.hasLabelIcon\n ? html`<div class=\"label-icon\">\n <slot name=\"label-icon\"></slot>\n </div>`\n : nothing}\n <span class=\"label-text\">${this.label}</span>\n ${this.required\n ? html`<div class=\"required-indicator\"></div>`\n : nothing}\n </div>`\n : nothing}\n\n <div class=\"horizontal-container\">\n <div class=\"input-field-container\" part=\"input-field-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"leading-icon\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing}\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 ${unitInside\n ? html`<span class=\"unit-text\">${this.unit}</span>`\n : nothing}\n </div>\n </div>\n ${unitOutside\n ? html`<span class=\"unit-text external\">${this.unit}</span>`\n : nothing}\n </div>\n\n ${this.error && this.errorText\n ? this.renderFooterText(this.errorText, true)\n : this.renderFooterText(this.helperText, false)}\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"],"names":["ObcNumberInputFieldTextAlign","ObcNumberInputFieldSize","ObcNumberInputFieldPlacement"],"mappings":"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"}
1
+ {"version":3,"file":"number-input-field.js","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 * @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 /** @availableWhen error==true */\n @property({type: String}) errorText = '';\n /** If true, the input field will not update its value on focus */\n @property({type: Boolean}) rejectUpdatesOnFocus = false;\n /** If true, the value will only be initially set, and not updated on change */\n @property({type: Boolean}) rejectUpdates = false;\n\n /** 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 */\n @property({type: Boolean}) rejectDuplicateUpdates = false;\n\n /** Name attribute for form integration */\n @property({type: String}) name = '';\n\n /** Maximum number of characters allowed */\n @property({type: Number}) maxlength?: number;\n\n /** Minimum number of characters required */\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 /** @availableWhen label!='' */\n @property({type: Boolean}) hasLabelIcon = false;\n /** @availableWhen label!='' */\n @property({type: String}) labelPlacement: ObcNumberInputFieldPlacement =\n ObcNumberInputFieldPlacement.Left;\n\n /** @availableWhen helperText!='' || (error==true && errorText!='') */\n @property({type: Boolean}) hasHelperIcon = false;\n /** @availableWhen helperText!='' || (error==true && errorText!='') */\n @property({type: String}) helperPlacement: ObcNumberInputFieldPlacement =\n ObcNumberInputFieldPlacement.Left;\n\n /** Internal property for squared corners, used when input is used in stepper-box */\n @property({type: Boolean}) squared = false;\n\n /**\n * Optional display text override for controlled consumers (e.g. keyboard-numeric)\n * that manage formatted strings while the committed value may be NaN.\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 /**\n * 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 */\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 ${this.hasHelperIcon\n ? html`<div class=\"helper-icon\"><slot name=\"helper-icon\"></slot></div>`\n : nothing}\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 ${this.label\n ? html`<div\n class=${classMap({\n 'label-text-container': true,\n [`label-placement-${this.labelPlacement}`]: true,\n })}\n >\n ${this.hasLabelIcon\n ? html`<div class=\"label-icon\">\n <slot name=\"label-icon\"></slot>\n </div>`\n : nothing}\n <span class=\"label-text\">${this.label}</span>\n ${this.required\n ? html`<div class=\"required-indicator\"></div>`\n : nothing}\n </div>`\n : nothing}\n\n <div class=\"horizontal-container\">\n <div class=\"input-field-container\" part=\"input-field-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"leading-icon\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing}\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 ${unitInside\n ? html`<span class=\"unit-text\">${this.unit}</span>`\n : nothing}\n </div>\n </div>\n ${unitOutside\n ? html`<span class=\"unit-text external\">${this.unit}</span>`\n : nothing}\n </div>\n\n ${this.error && this.errorText\n ? this.renderFooterText(this.errorText, true)\n : this.renderFooterText(this.helperText, false)}\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"],"names":["ObcNumberInputFieldTextAlign","ObcNumberInputFieldSize","ObcNumberInputFieldPlacement"],"mappings":"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"}
@@ -109,6 +109,21 @@ const componentStyle = css`* {
109
109
  cursor: not-allowed;
110
110
  }
111
111
 
112
+ /* A read-only field is still focusable and selectable, but it accepts no
113
+ edits — so it must not advertise the hover/pressed affordances that
114
+ \`@mixin style\` renders. Zeroing --obc-can-hover makes the mixin's hover
115
+ colour-mix collapse back onto the enabled colours; the pressed state has
116
+ no such switch and is restored explicitly. */
117
+
118
+ .wrapper.readonly {
119
+ --obc-can-hover: 0;
120
+ }
121
+
122
+ .wrapper.readonly:not(.disabled):active .input-field-container {
123
+ border-color: var(--normal-enabled-border-color);
124
+ background: var(--normal-enabled-background-color);
125
+ }
126
+
112
127
  .wrapper.helpertext,.wrapper.haslabel {
113
128
  flex-direction: column;
114
129
  align-items: flex-start;
@@ -119,6 +134,10 @@ const componentStyle = css`* {
119
134
  background: var(--container-background-color);
120
135
  }
121
136
 
137
+ .wrapper.readonly.empty:not(.disabled):active .input-field-container {
138
+ background: var(--container-background-color);
139
+ }
140
+
122
141
  .wrapper.empty:not(.disabled):focus-within .input-field-container {
123
142
  background: var(--normal-enabled-background-color);
124
143
  }
@@ -1 +1 @@
1
- {"version":3,"file":"text-input-field.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"text-input-field.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"text-input-field.d.ts","sourceRoot":"","sources":["../../../src/components/text-input-field/text-input-field.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAIV,cAAc,EACd,cAAc,EACf,MAAM,KAAK,CAAC;AAMb,OAAO,+BAA+B,CAAC;AACvC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,0CAA0C,CAAC;AAClD,OAAO,2CAA2C,CAAC;AAEnD,MAAM,MAAM,0BAA0B,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AAEtE;;;GAGG;AACH,oBAAY,sBAAsB;IAChC,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,oBAAY,0BAA0B;IACpC,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED,oBAAY,qBAAqB;IAC/B,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED,oBAAY,0BAA0B;IACpC,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,KAAK,UAAU;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IACrB,KAAK,SAAM;IACX,WAAW,SAAM;IACjB,IAAI,EAAE,sBAAsB,CACxB;IACJ,SAAS,EAAE,0BAA0B,CAC7B;IAEQ,QAAQ,UAAS;IACjB,QAAQ,UAAS;IACjB,KAAK,UAAS;IACxD,iCAAiC;IACP,SAAS,SAAM;IACzC,kEAAkE;IACvC,oBAAoB,UAAS;IACxD,+EAA+E;IACpD,aAAa,UAAS;IAEjD;;OAEG;IACwB,sBAAsB,UAAS;IAE1D,0CAA0C;IAChB,IAAI,SAAM;IAEpC,2CAA2C;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IAE7C,4CAA4C;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,qBAAqB,CACrB;IAEL,cAAc,UAAS;IAElD,sDAAsD;IAC3B,cAAc,UAAS;IAExB,UAAU,SAAM;IAEhB,KAAK,SAAM;IACV,QAAQ,UAAS;IAC5C,+BAA+B;IACJ,YAAY,UAAS;IAChD,+BAA+B;IACL,cAAc,EAAE,0BAA0B,CAClC;IAEP,aAAa,UAAS;IACvB,eAAe,EAAE,0BAA0B,CACnC;IAElC,oDAAoD;IAC3C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,yBAAyB,CAAM;IAEzB,OAAO,CAAC,YAAY,CAAC,CAAmB;IAE/D,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,eAAe;IAOvB,OAAO,KAAK,iBAAiB,GAO5B;IAED,OAAO,KAAK,OAAO,GAMlB;IAEQ,UAAU,CAAC,iBAAiB,EAAE,cAAc;IAU5C,OAAO;IAUP,MAAM;IAwHf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,iBAAiB,CAAC;KAC3C;CACF"}
1
+ {"version":3,"file":"text-input-field.d.ts","sourceRoot":"","sources":["../../../src/components/text-input-field/text-input-field.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAIV,cAAc,EACd,cAAc,EACf,MAAM,KAAK,CAAC;AAMb,OAAO,+BAA+B,CAAC;AACvC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,0CAA0C,CAAC;AAClD,OAAO,2CAA2C,CAAC;AAEnD,MAAM,MAAM,0BAA0B,GAAG,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AAEtE;;;GAGG;AACH,oBAAY,sBAAsB;IAChC,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,oBAAY,0BAA0B;IACpC,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED,oBAAY,qBAAqB;IAC/B,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED,oBAAY,0BAA0B;IACpC,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,KAAK,UAAU;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IACrB,KAAK,SAAM;IACX,WAAW,SAAM;IACjB,IAAI,EAAE,sBAAsB,CACxB;IACJ,SAAS,EAAE,0BAA0B,CAC7B;IAEQ,QAAQ,UAAS;IACjB,QAAQ,UAAS;IACjB,KAAK,UAAS;IACxD,iCAAiC;IACP,SAAS,SAAM;IACzC,kEAAkE;IACvC,oBAAoB,UAAS;IACxD,+EAA+E;IACpD,aAAa,UAAS;IAEjD;;OAEG;IACwB,sBAAsB,UAAS;IAE1D,0CAA0C;IAChB,IAAI,SAAM;IAEpC,2CAA2C;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IAE7C,4CAA4C;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,qBAAqB,CACrB;IAEL,cAAc,UAAS;IAElD,sDAAsD;IAC3B,cAAc,UAAS;IAExB,UAAU,SAAM;IAEhB,KAAK,SAAM;IACV,QAAQ,UAAS;IAC5C,+BAA+B;IACJ,YAAY,UAAS;IAChD,+BAA+B;IACL,cAAc,EAAE,0BAA0B,CAClC;IAEP,aAAa,UAAS;IACvB,eAAe,EAAE,0BAA0B,CACnC;IAElC,oDAAoD;IAC3C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,yBAAyB,CAAM;IAEzB,OAAO,CAAC,YAAY,CAAC,CAAmB;IAE/D,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,eAAe;IAOvB,OAAO,KAAK,iBAAiB,GAO5B;IAED,OAAO,KAAK,OAAO,GAMlB;IAEQ,UAAU,CAAC,iBAAiB,EAAE,cAAc;IAU5C,OAAO;IAUP,MAAM;IA4Hf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,iBAAiB,CAAC;KAC3C;CACF"}
@@ -159,7 +159,7 @@ let ObcTextInputField = class extends LitElement {
159
159
  }
160
160
  render() {
161
161
  const hasHelperOrError = Boolean(this.helperText) || Boolean(this.error && this.errorText);
162
- const showClearButton = this.hasClearButton && this.value.length > 0 && !this.disabled;
162
+ const showClearButton = this.hasClearButton && this.value.length > 0 && !this.disabled && !this.readonly;
163
163
  const isPasswordField = this.type === "password";
164
164
  const showPasswordToggle = isPasswordField && !this.disabled;
165
165
  const isClearButtonVisible = showClearButton && !showPasswordToggle;
@@ -177,6 +177,7 @@ let ObcTextInputField = class extends LitElement {
177
177
  [`size-${this.size}`]: true,
178
178
  error: this.error,
179
179
  disabled: this.disabled,
180
+ readonly: this.readonly,
180
181
  empty: this.isEmpty,
181
182
  helpertext: hasHelperOrError,
182
183
  haslabel: Boolean(this.label),