@felleslosninger/minid-elements 0.1.5 → 0.1.6

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.
@@ -9,10 +9,17 @@ declare const MinidCheckbox_base: import('../types/mixin-constructor.ts').Constr
9
9
  * @slot -- The default slot for the label text of the checkbox
10
10
  * @slot description - The slot for the description text of the checkbox
11
11
  *
12
+ * @csspart label - The checkbox's label.
13
+ * @csspart description - The checkbox's description.
14
+ * @csspart validation-message - The error message shown by `invalidmessage`.
15
+ *
12
16
  * @event mid-change - Emitted when the checked state changes
13
17
  */
14
18
  export declare class MinidCheckbox extends MinidCheckbox_base {
15
19
  private input;
20
+ private readonly hasSlotController;
21
+ private readonly descriptionId;
22
+ private readonly validationId;
16
23
  /**
17
24
  * The name of the checkbox, submitted as a name/value pair with form data.
18
25
  */
@@ -26,6 +33,7 @@ export declare class MinidCheckbox extends MinidCheckbox_base {
26
33
  disabled: boolean;
27
34
  readonly: boolean;
28
35
  invalid: boolean;
36
+ invalidmessage: string;
29
37
  required: boolean;
30
38
  static get formControlValidators(): import('../types/validator.type.ts').Validator[];
31
39
  shouldFormValueUpdate(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.component.d.ts","sourceRoot":"","sources":["../../src/components/checkbox.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,MAAM,KAAK,CAAC;AAIvC,OAAO,0BAA0B,CAAC;AAMlC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,aAAa,CAAC;KAC/B;CACF;;AAED;;;;;GAKG;AAEH,qBACa,aAAc,SAAQ,kBAAoC;IAErE,OAAO,CAAC,KAAK,CAAoB;IAEjC;;OAEG;IAEH,IAAI,SAAM;IAEV;;OAEG;IAEH,KAAK,SAAQ;IAGb,OAAO,UAAS;IAGhB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,QAAQ,UAAS;IAGjB,QAAQ,UAAS;IAGjB,OAAO,UAAS;IAGhB,QAAQ,UAAS;IAEjB,MAAM,KAAK,qBAAqB,qDAE/B;IAED,qBAAqB,IAAI,OAAO;IAIhC,IAAI,gBAAgB,qBAEnB;IAED,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,KAAK;IAIL;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY;IAI5B;;OAEG;IACH,IAAI;IAKJ,iBAAiB;IAKR,MAAM;CAmChB"}
1
+ {"version":3,"file":"checkbox.component.d.ts","sourceRoot":"","sources":["../../src/components/checkbox.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAK5C,OAAO,0BAA0B,CAAC;AAOlC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,aAAa,CAAC;KAC/B;CACF;;AAUD;;;;;;;;;GASG;AAEH,qBACa,aAAc,SAAQ,kBAElC;IAEC,OAAO,CAAC,KAAK,CAAoB;IAEjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAGhC;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAE7C;;OAEG;IAEH,IAAI,SAAM;IAEV;;OAEG;IAEH,KAAK,SAAQ;IAGb,OAAO,UAAS;IAGhB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,QAAQ,UAAS;IAGjB,QAAQ,UAAS;IAGjB,OAAO,UAAS;IAGhB,cAAc,SAAM;IAGpB,QAAQ,UAAS;IAEjB,MAAM,KAAK,qBAAqB,qDAE/B;IAED,qBAAqB,IAAI,OAAO;IAIhC,IAAI,gBAAgB,qBAEnB;IAED,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,KAAK;IAIL;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY;IAI5B;;OAEG;IACH,IAAI;IAKJ,iBAAiB;IAKR,MAAM;CAoEhB"}
@@ -1,5 +1,6 @@
1
- import { LitElement, html } from "lit";
1
+ import { css, LitElement, html } from "lit";
2
2
  import { query, property, customElement } from "lit/decorators.js";
3
+ import { classMap } from "lit/directives/class-map.js";
3
4
  import { live } from "lit/directives/live.js";
4
5
  import { styled } from "../mixins/tailwind.mixin.js";
5
6
  import "./icon/icon.js";
@@ -7,6 +8,7 @@ import { ifDefined } from "lit/directives/if-defined.js";
7
8
  import { FormControlMixin } from "../mixins/form-control.mixin.js";
8
9
  import { watch } from "../internal/watch.js";
9
10
  import { requiredValidator } from "../mixins/validators.js";
11
+ import { HasSlotController } from "../internal/slot.js";
10
12
  var __defProp = Object.defineProperty;
11
13
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
14
  var __decorateClass = (decorators, target, key, kind) => {
@@ -17,15 +19,31 @@ var __decorateClass = (decorators, target, key, kind) => {
17
19
  if (kind && result) __defProp(target, key, result);
18
20
  return result;
19
21
  };
20
- let MinidCheckbox = class extends FormControlMixin(styled(LitElement)) {
22
+ const styles = [
23
+ css`
24
+ .description {
25
+ color: var(--ds-color-neutral-text-subtle);
26
+ }
27
+ `
28
+ ];
29
+ let MinidCheckbox = class extends FormControlMixin(
30
+ styled(LitElement, styles)
31
+ ) {
21
32
  constructor() {
22
33
  super(...arguments);
34
+ this.hasSlotController = new HasSlotController(
35
+ this,
36
+ "description"
37
+ );
38
+ this.descriptionId = "description";
39
+ this.validationId = "validation";
23
40
  this.name = "";
24
41
  this.value = "on";
25
42
  this.checked = false;
26
43
  this.disabled = false;
27
44
  this.readonly = false;
28
45
  this.invalid = false;
46
+ this.invalidmessage = "";
29
47
  this.required = false;
30
48
  }
31
49
  static get formControlValidators() {
@@ -73,6 +91,12 @@ let MinidCheckbox = class extends FormControlMixin(styled(LitElement)) {
73
91
  this.setValue(this.value);
74
92
  }
75
93
  render() {
94
+ const hasDescription = !!this.description || this.hasSlotController.test("description");
95
+ const isInvalid = this.invalid || !!this.invalidmessage;
96
+ const describedBy = [
97
+ hasDescription ? this.descriptionId : void 0,
98
+ this.invalidmessage ? this.validationId : void 0
99
+ ].filter(Boolean).join(" ") || void 0;
76
100
  return html`
77
101
  <ds-field class="ds-field">
78
102
  <input
@@ -85,6 +109,11 @@ let MinidCheckbox = class extends FormControlMixin(styled(LitElement)) {
85
109
  ?checked=${this.checked}
86
110
  ?readonly=${this.readonly}
87
111
  ?required=${this.required}
112
+ aria-invalid=${isInvalid ? "true" : "false"}
113
+ aria-describedby=${ifDefined(describedBy)}
114
+ aria-errormessage=${ifDefined(
115
+ this.invalidmessage ? this.validationId : void 0
116
+ )}
88
117
  @click=${this.handleClick}
89
118
  @keydown=${this.handleKeydown}
90
119
  />
@@ -95,7 +124,11 @@ let MinidCheckbox = class extends FormControlMixin(styled(LitElement)) {
95
124
  >
96
125
  <slot></slot>
97
126
  </label>
98
- <div data-field="description">
127
+ <div
128
+ class="description"
129
+ id="${this.descriptionId}"
130
+ aria-hidden="true"
131
+ >
99
132
  <slot
100
133
  name="description"
101
134
  part="description"
@@ -103,6 +136,16 @@ let MinidCheckbox = class extends FormControlMixin(styled(LitElement)) {
103
136
  ${this.description}
104
137
  </slot>
105
138
  </div>
139
+ <p
140
+ class="${classMap({
141
+ "ds-validation-message": !!this.invalidmessage
142
+ })}"
143
+ part="validation-message"
144
+ id="${this.validationId}"
145
+ aria-live="polite"
146
+ >
147
+ ${this.invalidmessage}
148
+ </p>
106
149
  </ds-field>
107
150
  `;
108
151
  }
@@ -131,6 +174,9 @@ __decorateClass([
131
174
  __decorateClass([
132
175
  property({ type: Boolean })
133
176
  ], MinidCheckbox.prototype, "invalid", 2);
177
+ __decorateClass([
178
+ property()
179
+ ], MinidCheckbox.prototype, "invalidmessage", 2);
134
180
  __decorateClass([
135
181
  property({ type: Boolean, reflect: true })
136
182
  ], MinidCheckbox.prototype, "required", 2);
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.js","sources":["../../src/components/checkbox.component.ts"],"sourcesContent":["import { html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\nimport { styled } from '../mixins/tailwind.mixin';\nimport './icon/icon.component.ts';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { FormControlMixin } from '../mixins/form-control.mixin.ts';\nimport { watch } from '../internal/watch.ts';\nimport { requiredValidator } from '../mixins/validators.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-checkbox': MinidCheckbox;\n }\n}\n\n/**\n * @slot -- The default slot for the label text of the checkbox\n * @slot description - The slot for the description text of the checkbox\n *\n * @event mid-change - Emitted when the checked state changes\n */\n\n@customElement('mid-checkbox')\nexport class MinidCheckbox extends FormControlMixin(styled(LitElement)) {\n @query('input[type=\"checkbox\"]')\n private input!: HTMLInputElement;\n\n /**\n * The name of the checkbox, submitted as a name/value pair with form data.\n */\n @property()\n name = '';\n\n /**\n * The current value of the checkbox, submitted as a name/value pair with form data.\n */\n @property()\n value = 'on';\n\n @property({ type: Boolean })\n checked = false;\n\n @property()\n description?: string;\n\n @property({ type: Boolean })\n disabled = false;\n\n @property({ type: Boolean })\n readonly = false;\n\n @property({ type: Boolean })\n invalid = false;\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n static get formControlValidators() {\n return [requiredValidator];\n }\n\n shouldFormValueUpdate(): boolean {\n return this.checked;\n }\n\n get validationTarget() {\n return this.input;\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n // Pressing enter when focused on an input should submit the form like a native input, but we wait a tick before\n // submitting to allow users to cancel the keydown event if they need to\n if (event.key === 'Enter' && !hasModifier) {\n setTimeout(() => {\n //\n // When using an Input Method Editor (IME), pressing enter will cause the form to submit unexpectedly. One way\n // to check for this is to look at event.isComposing, which will be true when the IME is open.\n if (!event.defaultPrevented && !event.isComposing) {\n this.form.requestSubmit();\n }\n });\n }\n }\n\n private handleClick() {\n this.checked = !this.checked;\n // this.indeterminate = false;\n this.dispatchEvent(new Event('mid-change'));\n }\n\n /**\n * Simulates a click on the checkbox.\n */\n click() {\n this.input.click();\n }\n\n /**\n * Sets focus on the checkbox.\n */\n focus(options?: FocusOptions) {\n this.input.focus(options);\n }\n\n /**\n * Removes focus from the checkbox.\n */\n blur() {\n this.input.blur();\n }\n\n @watch(['checked', 'value'])\n handleStateChange() {\n // this.input.indeterminate = this.indeterminate; // force a sync update\n this.setValue(this.value);\n }\n\n override render() {\n\n return html`\n <ds-field class=\"ds-field\">\n <input\n id=\"input\"\n class=\"ds-input\"\n type=\"checkbox\"\n value=${ifDefined(this.value)}\n .checked=${live(this.checked)}\n ?disabled=${this.disabled}\n ?checked=${this.checked}\n ?readonly=${this.readonly}\n ?required=${this.required}\n @click=${this.handleClick}\n @keydown=${this.handleKeydown}\n />\n <label\n class=\"ds-label\"\n part=\"label\"\n for=\"input\"\n >\n <slot></slot>\n </label>\n <div data-field=\"description\">\n <slot\n name=\"description\"\n part=\"description\"\n >\n ${this.description}\n </slot>\n </div>\n </ds-field>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkbox.js","sources":["../../src/components/checkbox.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { live } from 'lit/directives/live.js';\nimport { styled } from '../mixins/tailwind.mixin';\nimport './icon/icon.component.ts';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { FormControlMixin } from '../mixins/form-control.mixin.ts';\nimport { watch } from '../internal/watch.ts';\nimport { requiredValidator } from '../mixins/validators.ts';\nimport { HasSlotController } from '../internal/slot.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-checkbox': MinidCheckbox;\n }\n}\n\nconst styles = [\n css`\n .description {\n color: var(--ds-color-neutral-text-subtle);\n }\n `,\n];\n\n/**\n * @slot -- The default slot for the label text of the checkbox\n * @slot description - The slot for the description text of the checkbox\n *\n * @csspart label - The checkbox's label.\n * @csspart description - The checkbox's description.\n * @csspart validation-message - The error message shown by `invalidmessage`.\n *\n * @event mid-change - Emitted when the checked state changes\n */\n\n@customElement('mid-checkbox')\nexport class MinidCheckbox extends FormControlMixin(\n styled(LitElement, styles)\n) {\n @query('input[type=\"checkbox\"]')\n private input!: HTMLInputElement;\n\n private readonly hasSlotController = new HasSlotController(\n this,\n 'description'\n );\n\n private readonly descriptionId = 'description';\n private readonly validationId = 'validation';\n\n /**\n * The name of the checkbox, submitted as a name/value pair with form data.\n */\n @property()\n name = '';\n\n /**\n * The current value of the checkbox, submitted as a name/value pair with form data.\n */\n @property()\n value = 'on';\n\n @property({ type: Boolean })\n checked = false;\n\n @property()\n description?: string;\n\n @property({ type: Boolean })\n disabled = false;\n\n @property({ type: Boolean })\n readonly = false;\n\n @property({ type: Boolean })\n invalid = false;\n\n @property()\n invalidmessage = '';\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n static get formControlValidators() {\n return [requiredValidator];\n }\n\n shouldFormValueUpdate(): boolean {\n return this.checked;\n }\n\n get validationTarget() {\n return this.input;\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n // Pressing enter when focused on an input should submit the form like a native input, but we wait a tick before\n // submitting to allow users to cancel the keydown event if they need to\n if (event.key === 'Enter' && !hasModifier) {\n setTimeout(() => {\n //\n // When using an Input Method Editor (IME), pressing enter will cause the form to submit unexpectedly. One way\n // to check for this is to look at event.isComposing, which will be true when the IME is open.\n if (!event.defaultPrevented && !event.isComposing) {\n this.form.requestSubmit();\n }\n });\n }\n }\n\n private handleClick() {\n this.checked = !this.checked;\n // this.indeterminate = false;\n this.dispatchEvent(new Event('mid-change'));\n }\n\n /**\n * Simulates a click on the checkbox.\n */\n click() {\n this.input.click();\n }\n\n /**\n * Sets focus on the checkbox.\n */\n focus(options?: FocusOptions) {\n this.input.focus(options);\n }\n\n /**\n * Removes focus from the checkbox.\n */\n blur() {\n this.input.blur();\n }\n\n @watch(['checked', 'value'])\n handleStateChange() {\n // this.input.indeterminate = this.indeterminate; // force a sync update\n this.setValue(this.value);\n }\n\n override render() {\n const hasDescription =\n !!this.description || this.hasSlotController.test('description');\n const isInvalid = this.invalid || !!this.invalidmessage;\n const describedBy =\n [\n hasDescription ? this.descriptionId : undefined,\n this.invalidmessage ? this.validationId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n // The description wrapper is aria-hidden. It is already announced through\n // the aria-describedby above, and without this the text is also reachable as\n // its own node when navigating the page, so it is read out twice.\n\n return html`\n <ds-field class=\"ds-field\">\n <input\n id=\"input\"\n class=\"ds-input\"\n type=\"checkbox\"\n value=${ifDefined(this.value)}\n .checked=${live(this.checked)}\n ?disabled=${this.disabled}\n ?checked=${this.checked}\n ?readonly=${this.readonly}\n ?required=${this.required}\n aria-invalid=${isInvalid ? 'true' : 'false'}\n aria-describedby=${ifDefined(describedBy)}\n aria-errormessage=${ifDefined(\n this.invalidmessage ? this.validationId : undefined\n )}\n @click=${this.handleClick}\n @keydown=${this.handleKeydown}\n />\n <label\n class=\"ds-label\"\n part=\"label\"\n for=\"input\"\n >\n <slot></slot>\n </label>\n <div\n class=\"description\"\n id=\"${this.descriptionId}\"\n aria-hidden=\"true\"\n >\n <slot\n name=\"description\"\n part=\"description\"\n >\n ${this.description}\n </slot>\n </div>\n <p\n class=\"${classMap({\n 'ds-validation-message': !!this.invalidmessage,\n })}\"\n part=\"validation-message\"\n id=\"${this.validationId}\"\n aria-live=\"polite\"\n >\n ${this.invalidmessage}\n </p>\n </ds-field>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -14,10 +14,13 @@ declare const MinidCodeInput_base: import('../types/mixin-constructor.ts').Const
14
14
  * @event {detail: { validity: ValidityState }} mid-invalid-show - Emitted when the error message should be shown
15
15
  *
16
16
  * @slot label - The input's label if you need to use HTML. Alternatively, you can use the `label` attribute.
17
+ * @slot description - The input's description if you need to use HTML. Alternatively, you can use the `description` attribute.
17
18
  *
18
19
  * @csspart input-container - The wrapper around the input elements. This can be used to adjust font-size.
20
+ * @csspart description - The description shown between the label and the character boxes.
19
21
  * @csspart character-boxes - The container for the visual character boxes.
20
22
  * @csspart character-box - An individual character box.
23
+ * @csspart validation-message - The error message shown by `invalidmessage`.
21
24
  *
22
25
  * @method focus - Focuses the input element
23
26
  * @method clear - Clears the input
@@ -25,10 +28,12 @@ declare const MinidCodeInput_base: import('../types/mixin-constructor.ts').Const
25
28
  export declare class MinidCodeInput extends MinidCodeInput_base {
26
29
  private readonly hasSlotControler;
27
30
  private readonly labelId;
31
+ private readonly descriptionId;
28
32
  private readonly validationId;
29
33
  private inputElement;
30
34
  value: string;
31
35
  label: string;
36
+ description: string;
32
37
  type: 'number' | 'text';
33
38
  /**
34
39
  * For displaying appropriate virtual keyboard
@@ -38,6 +43,7 @@ export declare class MinidCodeInput extends MinidCodeInput_base {
38
43
  * Adjusts the font-size of the code inputs
39
44
  */
40
45
  size: 'sm' | 'md' | 'lg';
46
+ labelsize?: 'sm' | 'md' | 'lg';
41
47
  /**
42
48
  * Number of input characters or digits
43
49
  */
@@ -59,6 +65,7 @@ export declare class MinidCodeInput extends MinidCodeInput_base {
59
65
  * Visually hides `label` (still available for screen readers)
60
66
  */
61
67
  hidelabel: boolean;
68
+ hidedescription: boolean;
62
69
  /**
63
70
  * Makes the input required
64
71
  */
@@ -68,13 +75,28 @@ export declare class MinidCodeInput extends MinidCodeInput_base {
68
75
  */
69
76
  pattern?: string;
70
77
  private isFocused;
78
+ private caretPosition;
71
79
  static get formControlValidators(): import('../types/validator.type.ts').Validator[];
72
80
  get validationTarget(): HTMLInputElement;
73
81
  protected firstUpdated(_changedProperties: PropertyValues): void;
82
+ connectedCallback(): void;
83
+ disconnectedCallback(): void;
74
84
  private handleBoxClick;
85
+ /**
86
+ * Catches caret moves we did not make - arrow keys, Home/End, word jumps,
87
+ * shift-selection - without enumerating keys, and keeps up while a key is held.
88
+ *
89
+ * Must be listened for on the document: for a caret move the user made,
90
+ * Chromium fires it only there, not at the input and not into the shadow root,
91
+ * so an `@selectionchange` binding on either never runs.
92
+ */
93
+ private handleSelectionChange;
94
+ private syncCaretPosition;
75
95
  private handleFocus;
76
96
  private handleBlur;
97
+ private filterValue;
77
98
  private handleBeforeInput;
99
+ private handlePaste;
78
100
  private handleInput;
79
101
  private handleChange;
80
102
  private handleKeydown;
@@ -82,6 +104,7 @@ export declare class MinidCodeInput extends MinidCodeInput_base {
82
104
  resetFormControl(): void;
83
105
  focus(options?: FocusOptions): void;
84
106
  handleLengthChange(): void;
107
+ handleValueChange(): void;
85
108
  render(): import('lit').TemplateResult<1>;
86
109
  }
87
110
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"code-input.component.d.ts","sourceRoot":"","sources":["../../src/components/code-input.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAS5D,OAAO,0BAA0B,CAAC;AASlC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,cAAc,CAAC;KAClC;CACF;;AAmOD;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,cAAe,SAAQ,mBAEnC;IACC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IACpE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiD;IAG9E,OAAO,CAAC,YAAY,CAAoB;IAGxC,KAAK,SAAM;IAGX,KAAK,SAAM;IAGX,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAU;IAEjC;;OAEG;IAEH,SAAS,EAAE,SAAS,GAAG,MAAM,CAAa;IAE1C;;OAEG;IAEH,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IAEH,MAAM,SAAK;IAGX,QAAQ,UAAS;IAEjB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,cAAc,SAAM;IAEpB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAEH,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,OAAO,CAAC,SAAS,CAAS;IAE1B,MAAM,KAAK,qBAAqB,qDAO/B;IAED,IAAI,gBAAgB,qBAEnB;IAED,SAAS,CAAC,YAAY,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAIhE,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,aAAa;IAiBrB,KAAK;IAML,gBAAgB;IAIhB,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAUnC,kBAAkB;IAMT,MAAM;CAkGhB"}
1
+ {"version":3,"file":"code-input.component.d.ts","sourceRoot":"","sources":["../../src/components/code-input.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,cAAc,EAAE,MAAM,KAAK,CAAC;AASrE,OAAO,0BAA0B,CAAC;AASlC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,cAAc,CAAC;KAClC;CACF;;AA2PD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,cAAe,SAAQ,mBAEnC;IACC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAI/B;IACF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IACpE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkD;IAChF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiD;IAG9E,OAAO,CAAC,YAAY,CAAoB;IAGxC,KAAK,SAAM;IAGX,KAAK,SAAM;IAGX,WAAW,SAAM;IAGjB,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAU;IAEjC;;OAEG;IAEH,SAAS,EAAE,SAAS,GAAG,MAAM,CAAa;IAE1C;;OAEG;IAEH,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAGhC,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAE/B;;OAEG;IAEH,MAAM,SAAK;IAGX,QAAQ,UAAS;IAEjB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,cAAc,SAAM;IAEpB;;OAEG;IAEH,SAAS,UAAS;IAGlB,eAAe,UAAS;IAExB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAEH,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,aAAa,CAAK;IAE1B,MAAM,KAAK,qBAAqB,qDAO/B;IAED,IAAI,gBAAgB,qBAEnB;IAED,SAAS,CAAC,YAAY,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAIvD,iBAAiB;IAQjB,oBAAoB;IAQ7B,OAAO,CAAC,cAAc;IAYtB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB,CAK3B;IAEF,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,WAAW;IAqCnB,OAAO,CAAC,WAAW;IA6BnB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,aAAa;IAiBrB,KAAK;IAOL,gBAAgB;IAIhB,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAWnC,kBAAkB;IAOlB,iBAAiB;IAWR,MAAM;CAsIhB"}
@@ -1,4 +1,4 @@
1
- import { css, LitElement, html } from "lit";
1
+ import { css, LitElement, nothing, html } from "lit";
2
2
  import { query, property, state, customElement } from "lit/decorators.js";
3
3
  import { classMap } from "lit/directives/class-map.js";
4
4
  import { ifDefined } from "lit/directives/if-defined.js";
@@ -35,7 +35,32 @@ const styles = [
35
35
  font-weight: 500;
36
36
  }
37
37
 
38
- .code-input-label--hidden {
38
+ .code-input-label--with-description {
39
+ margin-block-end: 0.25rem;
40
+ }
41
+
42
+ .code-input-label--sm {
43
+ font-size: var(--ds-body-sm-font-size, 1rem);
44
+ line-height: var(--ds-body-md-line-height, 1.5);
45
+ }
46
+
47
+ .code-input-label--md {
48
+ font-size: var(--ds-body-md-font-size, 1.125rem);
49
+ line-height: var(--ds-body-md-line-height, 1.5);
50
+ }
51
+
52
+ .code-input-label--lg {
53
+ font-size: var(--ds-body-lg-font-size, 1.3125rem);
54
+ line-height: var(--ds-body-md-line-height, 1.5);
55
+ }
56
+
57
+ .code-input-description {
58
+ margin-block-end: 0.5rem;
59
+ color: var(--ds-color-neutral-text-subtle, #545e6b);
60
+ }
61
+
62
+ .code-input-label--hidden,
63
+ .code-input-description--hidden {
39
64
  position: absolute;
40
65
  width: 1px;
41
66
  height: 1px;
@@ -48,6 +73,7 @@ const styles = [
48
73
  }
49
74
 
50
75
  .code-input-label--disabled,
76
+ .code-input-description--disabled,
51
77
  .input-wrapper--disabled {
52
78
  opacity: var(--ds-opacity-disabled, 0.38);
53
79
  }
@@ -215,27 +241,25 @@ const styles = [
215
241
  animation: blink 1s step-end infinite;
216
242
  }
217
243
 
244
+ .character-box--caret-leading::after {
245
+ inset-inline-start: 0;
246
+ }
247
+
218
248
  /* Hide placeholder circle when the caret is at this position */
219
249
  .character-box--caret.character-box--empty {
220
250
  color: transparent;
221
251
  }
222
252
 
223
- /* Hide increment/decrement buttons on number inputs */
224
- input[type='number']::-webkit-outer-spin-button,
225
- input[type='number']::-webkit-inner-spin-button,
226
- input[type='number'] {
227
- -webkit-appearance: none;
228
- margin: 0;
229
- -moz-appearance: textfield !important;
230
- }
231
-
232
253
  .validation-message {
233
254
  display: flex;
234
255
  gap: 0.25rem;
235
- margin-block-start: 0.5rem;
236
256
  color: var(--ds-color-danger-text-subtle, #a22e2e);
237
257
  }
238
258
 
259
+ .validation-message--visible {
260
+ margin-block-start: 0.5rem;
261
+ }
262
+
239
263
  .validation-icon {
240
264
  margin-block-start: 0.25rem;
241
265
  min-width: 1.25rem;
@@ -248,11 +272,17 @@ let MinidCodeInput = class extends FormControlMixin(
248
272
  ) {
249
273
  constructor() {
250
274
  super(...arguments);
251
- this.hasSlotControler = new HasSlotController(this, "label");
275
+ this.hasSlotControler = new HasSlotController(
276
+ this,
277
+ "label",
278
+ "description"
279
+ );
252
280
  this.labelId = `mid-code-input-label-${nextUniqueId++}`;
281
+ this.descriptionId = `mid-code-input-description-${nextUniqueId++}`;
253
282
  this.validationId = `mid-code-input-validation-${nextUniqueId++}`;
254
283
  this.value = "";
255
284
  this.label = "";
285
+ this.description = "";
256
286
  this.type = "text";
257
287
  this.inputmode = "numeric";
258
288
  this.size = "sm";
@@ -261,8 +291,15 @@ let MinidCodeInput = class extends FormControlMixin(
261
291
  this.autofocus = false;
262
292
  this.invalidmessage = "";
263
293
  this.hidelabel = false;
294
+ this.hidedescription = false;
264
295
  this.required = false;
265
296
  this.isFocused = false;
297
+ this.caretPosition = 0;
298
+ this.handleSelectionChange = () => {
299
+ if (this.isFocused) {
300
+ this.syncCaretPosition();
301
+ }
302
+ };
266
303
  }
267
304
  static get formControlValidators() {
268
305
  return [
@@ -278,6 +315,20 @@ let MinidCodeInput = class extends FormControlMixin(
278
315
  firstUpdated(_changedProperties) {
279
316
  webOtpApiInit(this.renderRoot);
280
317
  }
318
+ connectedCallback() {
319
+ super.connectedCallback();
320
+ this.ownerDocument.addEventListener(
321
+ "selectionchange",
322
+ this.handleSelectionChange
323
+ );
324
+ }
325
+ disconnectedCallback() {
326
+ super.disconnectedCallback();
327
+ this.ownerDocument.removeEventListener(
328
+ "selectionchange",
329
+ this.handleSelectionChange
330
+ );
331
+ }
281
332
  handleBoxClick(index) {
282
333
  if (this.disabled) {
283
334
  return;
@@ -285,30 +336,67 @@ let MinidCodeInput = class extends FormControlMixin(
285
336
  this.value = this.value.substring(0, index);
286
337
  this.focus();
287
338
  }
339
+ syncCaretPosition() {
340
+ const input = this.inputElement;
341
+ if (!input) {
342
+ return;
343
+ }
344
+ this.caretPosition = (input.selectionDirection === "backward" ? input.selectionStart : input.selectionEnd) ?? this.value.length;
345
+ }
288
346
  handleFocus() {
289
347
  this.isFocused = true;
290
348
  if (this.value.length > 0) {
291
349
  const length = this.value.length;
292
350
  this.inputElement.setSelectionRange(length, length);
293
351
  }
352
+ this.syncCaretPosition();
294
353
  }
295
354
  handleBlur() {
296
355
  this.isFocused = false;
297
356
  }
357
+ filterValue(value) {
358
+ return this.type === "number" ? value.replace(/\D/g, "") : value;
359
+ }
298
360
  handleBeforeInput(e) {
299
- if (e.inputType === "insertText" && e.data) {
300
- if (this.type == "number" && e.data.replace(/\D/g, "") == "") {
361
+ if (this.type === "number" && e.inputType === "insertText" && e.data) {
362
+ if (!/\d/.test(e.data)) {
301
363
  e.preventDefault();
302
364
  }
303
365
  }
304
366
  }
367
+ handlePaste(event) {
368
+ if (this.type !== "number") {
369
+ return;
370
+ }
371
+ const pasted = event.clipboardData?.getData("text") ?? "";
372
+ const digits = this.filterValue(pasted);
373
+ if (digits === pasted) {
374
+ return;
375
+ }
376
+ event.preventDefault();
377
+ const input = this.inputElement;
378
+ const start = input.selectionStart ?? input.value.length;
379
+ const end = input.selectionEnd ?? start;
380
+ const next = (input.value.slice(0, start) + digits + input.value.slice(end)).substring(0, this.length);
381
+ if (next === input.value) {
382
+ return;
383
+ }
384
+ input.value = next;
385
+ input.dispatchEvent(
386
+ new InputEvent("input", { bubbles: true, composed: true })
387
+ );
388
+ const caret = Math.min(start + digits.length, input.value.length);
389
+ input.setSelectionRange(caret, caret);
390
+ this.syncCaretPosition();
391
+ }
305
392
  handleInput(event) {
306
393
  const input = event.target;
307
- let value = input.value;
394
+ let value = this.filterValue(input.value);
308
395
  value = value.substring(0, this.length);
309
396
  if (input.value !== value) {
310
397
  input.value = value;
311
398
  }
399
+ this.syncCaretPosition();
312
400
  if (this.value !== value) {
313
401
  this.value = value;
314
402
  this.setValue(value);
@@ -344,6 +432,7 @@ let MinidCodeInput = class extends FormControlMixin(
344
432
  this.value = "";
345
433
  this.setValue("");
346
434
  this.invalidmessage = "";
435
+ this.caretPosition = 0;
347
436
  }
348
437
  resetFormControl() {
349
438
  this.clear();
@@ -354,34 +443,65 @@ let MinidCodeInput = class extends FormControlMixin(
354
443
  const length = this.value.length;
355
444
  this.inputElement.setSelectionRange(length, length);
356
445
  }
446
+ this.syncCaretPosition();
357
447
  }
358
448
  handleLengthChange() {
359
449
  if (this.value.length > this.length) {
360
450
  this.value = this.value.substring(0, this.length);
361
451
  }
362
452
  }
453
+ handleValueChange() {
454
+ const filtered = this.filterValue(this.value);
455
+ if (filtered !== this.value) {
456
+ this.value = filtered;
457
+ }
458
+ this.caretPosition = Math.min(this.caretPosition, this.value.length);
459
+ this.setValue(filtered);
460
+ }
363
461
  render() {
364
462
  const hasLabelSlot = this.hasSlotControler.test("label");
365
463
  const hasLabel = !!this.label || !!hasLabelSlot;
366
- const describedBy = this.invalidmessage ? this.validationId : void 0;
464
+ const hasDescriptionSlot = this.hasSlotControler.test("description");
465
+ const hasDescription = !!this.description || !!hasDescriptionSlot;
466
+ const describedBy = [
467
+ hasDescription ? this.descriptionId : void 0,
468
+ this.invalidmessage ? this.validationId : void 0
469
+ ].filter(Boolean).join(" ") || void 0;
367
470
  const chars = this.value.split("");
368
471
  const displayValues = Array.from(
369
472
  { length: this.length },
370
473
  (_, i) => chars[i] || ""
371
474
  );
372
- const isComplete = this.value.length >= this.length;
373
- const caretIndex = this.disabled || this.length === 0 ? -1 : Math.min(this.value.length, this.length - 1);
475
+ const caretIndex = this.disabled || this.length === 0 ? -1 : Math.min(this.caretPosition, this.length - 1);
476
+ const caretIsInABox = this.caretPosition < this.length;
374
477
  return html`
375
478
  <label
376
479
  id="${this.labelId}"
377
480
  for="mid-code-input-hidden"
378
481
  class="code-input-label ${classMap({
482
+ "code-input-label--sm": this.labelsize === "sm",
483
+ "code-input-label--md": this.labelsize === "md",
484
+ "code-input-label--lg": this.labelsize === "lg",
379
485
  "code-input-label--hidden": this.hidelabel || !hasLabel,
486
+ "code-input-label--with-description": hasDescription,
380
487
  "code-input-label--disabled": this.disabled
381
488
  })}"
382
489
  >
383
490
  <slot name="label"> ${this.label} </slot>
384
491
  </label>
492
+ ${hasDescription ? html`
493
+ <div
494
+ id="${this.descriptionId}"
495
+ part="description"
496
+ aria-hidden="true"
497
+ class="code-input-description ${classMap({
498
+ "code-input-description--hidden": this.hidedescription,
499
+ "code-input-description--disabled": this.disabled
500
+ })}"
501
+ >
502
+ <slot name="description"> ${this.description} </slot>
503
+ </div>
504
+ ` : nothing}
385
505
  <div
386
506
  part="input-container"
387
507
  class="input-wrapper ${classMap({
@@ -395,7 +515,7 @@ let MinidCodeInput = class extends FormControlMixin(
395
515
  <div part="character-boxes" class="character-boxes" aria-hidden="true">
396
516
  ${displayValues.map((char, index) => {
397
517
  const isFocusTarget = this.isFocused && index === caretIndex;
398
- const hasCaret = isFocusTarget && !isComplete;
518
+ const hasCaret = isFocusTarget && caretIsInABox;
399
519
  return html`
400
520
  <div
401
521
  part="character-box"
@@ -403,6 +523,7 @@ let MinidCodeInput = class extends FormControlMixin(
403
523
  class="character-box ${classMap({
404
524
  "character-box--invalid": !!this.invalidmessage,
405
525
  "character-box--caret": hasCaret,
526
+ "character-box--caret-leading": hasCaret && !!char,
406
527
  "character-box--empty": !char,
407
528
  "focus-ring-sm": isFocusTarget
408
529
  })}"
@@ -420,7 +541,7 @@ let MinidCodeInput = class extends FormControlMixin(
420
541
  class="hidden-input"
421
542
  .value="${live(this.value)}"
422
543
  id="mid-code-input-hidden"
423
- type="${this.type}"
544
+ type="text"
424
545
  aria-labelledby="${this.labelId}"
425
546
  aria-describedby=${ifDefined(describedBy)}
426
547
  aria-invalid=${this.invalidmessage ? "true" : "false"}
@@ -435,6 +556,7 @@ let MinidCodeInput = class extends FormControlMixin(
435
556
  inputmode="${this.inputmode}"
436
557
  autocomplete="one-time-code"
437
558
  @beforeinput="${this.handleBeforeInput}"
559
+ @paste="${this.handlePaste}"
438
560
  @input="${this.handleInput}"
439
561
  @change="${this.handleChange}"
440
562
  @keydown="${this.handleKeydown}"
@@ -443,13 +565,18 @@ let MinidCodeInput = class extends FormControlMixin(
443
565
  />
444
566
  </div>
445
567
  <div
446
- class="validation-message"
568
+ class="validation-message ${classMap({
569
+ "validation-message--visible": !!this.invalidmessage
570
+ })}"
571
+ part="validation-message"
447
572
  id="${this.validationId}"
448
573
  aria-live="polite"
449
- ?hidden=${!this.invalidmessage}
450
574
  >
451
- <mid-icon name="xmark-octagon-fill" class="validation-icon"></mid-icon>
452
- ${this.invalidmessage}
575
+ ${this.invalidmessage ? html`<mid-icon
576
+ name="xmark-octagon-fill"
577
+ class="validation-icon"
578
+ ></mid-icon>
579
+ ${this.invalidmessage}` : nothing}
453
580
  </div>
454
581
  `;
455
582
  }
@@ -463,6 +590,9 @@ __decorateClass([
463
590
  __decorateClass([
464
591
  property()
465
592
  ], MinidCodeInput.prototype, "label", 2);
593
+ __decorateClass([
594
+ property()
595
+ ], MinidCodeInput.prototype, "description", 2);
466
596
  __decorateClass([
467
597
  property()
468
598
  ], MinidCodeInput.prototype, "type", 2);
@@ -472,6 +602,9 @@ __decorateClass([
472
602
  __decorateClass([
473
603
  property()
474
604
  ], MinidCodeInput.prototype, "size", 2);
605
+ __decorateClass([
606
+ property()
607
+ ], MinidCodeInput.prototype, "labelsize", 2);
475
608
  __decorateClass([
476
609
  property({ type: Number })
477
610
  ], MinidCodeInput.prototype, "length", 2);
@@ -490,6 +623,9 @@ __decorateClass([
490
623
  __decorateClass([
491
624
  property({ type: Boolean })
492
625
  ], MinidCodeInput.prototype, "hidelabel", 2);
626
+ __decorateClass([
627
+ property({ type: Boolean })
628
+ ], MinidCodeInput.prototype, "hidedescription", 2);
493
629
  __decorateClass([
494
630
  property({ type: Boolean })
495
631
  ], MinidCodeInput.prototype, "required", 2);
@@ -499,9 +635,15 @@ __decorateClass([
499
635
  __decorateClass([
500
636
  state()
501
637
  ], MinidCodeInput.prototype, "isFocused", 2);
638
+ __decorateClass([
639
+ state()
640
+ ], MinidCodeInput.prototype, "caretPosition", 2);
502
641
  __decorateClass([
503
642
  watch("length")
504
643
  ], MinidCodeInput.prototype, "handleLengthChange", 1);
644
+ __decorateClass([
645
+ watch(["value", "type"])
646
+ ], MinidCodeInput.prototype, "handleValueChange", 1);
505
647
  MinidCodeInput = __decorateClass([
506
648
  customElement("mid-code-input")
507
649
  ], MinidCodeInput);
@@ -1 +1 @@
1
- {"version":3,"file":"code-input.js","sources":["../../src/components/code-input.component.ts"],"sourcesContent":["import { css, html, LitElement, PropertyValues } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { watch } from '../internal/watch.ts';\nimport { FormControlMixin } from '../mixins/form-control.mixin.ts';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { HasSlotController } from '../internal/slot.ts';\nimport './icon/icon.component.ts';\nimport {\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n requiredValidator,\n} from '../mixins/validators.ts';\nimport { webOtpApiInit } from '../utilities/web-otp-api.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-code-input': MinidCodeInput;\n }\n}\n\nlet nextUniqueId = 0;\n\nconst styles = [\n css`\n :host {\n display: block;\n }\n\n .code-input-label {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n margin-block-end: 0.5rem;\n font-weight: 500;\n }\n\n .code-input-label--hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n .code-input-label--disabled,\n .input-wrapper--disabled {\n opacity: var(--ds-opacity-disabled, 0.38);\n }\n\n .input-wrapper {\n position: relative;\n cursor: text;\n width: fit-content;\n font-size: 1rem;\n line-height: 1.3;\n font-weight: 500;\n }\n\n .input-wrapper--sm {\n font-size: var(--ds-heading-sm-font-size, 1.125rem);\n line-height: var(--ds-heading-sm-line-height, 1.3);\n font-weight: var(--ds-heading-sm-font-weight, 500);\n }\n\n .input-wrapper--md {\n font-size: var(--ds-heading-md-font-size, 1.25rem);\n line-height: var(--ds-heading-md-line-height, 1.3);\n font-weight: var(--ds-heading-md-font-weight, 500);\n }\n\n .input-wrapper--lg {\n font-size: var(--ds-heading-lg-font-size, 1.5rem);\n line-height: var(--ds-heading-lg-line-height, 1.3);\n font-weight: var(--ds-heading-lg-font-weight, 500);\n }\n\n .input-wrapper--disabled {\n cursor: not-allowed;\n }\n\n .character-boxes {\n display: inline-flex;\n gap: var(--mid-code-input-gap, 0.5rem);\n }\n\n .character-box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n box-sizing: border-box;\n width: var(--mid-code-input-box-size, var(--ds-size-13, 3.25rem));\n height: var(--mid-code-input-box-size, var(--ds-size-13, 3.25rem));\n padding-inline: 0.25rem;\n user-select: none;\n text-align: center;\n font-family:\n ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,\n 'Liberation Mono', 'Courier New', monospace;\n line-height: 1;\n border: var(--ds-border-width-default, 1px) solid\n var(\n --mid-code-input-border-color,\n var(--ds-color-neutral-border-default, #717a84)\n );\n border-radius: var(\n --mid-code-input-border-radius,\n var(--ds-border-radius-md, 0.25rem)\n );\n background-color: var(\n --mid-code-input-background,\n var(--ds-color-neutral-background-default, #ffffff)\n );\n color: var(--mid-code-input-text-color, inherit);\n }\n\n .character-box--empty {\n color: var(\n --mid-code-input-placeholder-color,\n var(--ds-color-neutral-surface-active, #c7cacf)\n );\n }\n\n .character-box--empty::before {\n content: '';\n box-sizing: border-box;\n width: 0.55em;\n height: 0.55em;\n border: 2px solid currentColor;\n border-radius: 50%;\n }\n\n .character-box--invalid {\n border-width: 2px;\n border-color: var(\n --mid-code-input-danger-border-color,\n var(--ds-color-danger-border-default, #ce4d4d)\n );\n background-color: var(\n --mid-code-input-danger-background,\n var(--ds-color-danger-surface-tinted, #f8e4e4)\n );\n }\n\n .character-box--invalid.character-box--empty {\n color: var(\n --mid-code-input-danger-placeholder-color,\n var(--ds-color-danger-surface-active, #edbfbf)\n );\n }\n\n .focus-ring-sm {\n outline: 2px solid var(--ds-color-focus-outer, #1f2c3d);\n outline-offset: 2px;\n box-shadow: 0 0 0 2px var(--ds-color-focus-inner, #ffffff);\n }\n\n /* Ensure hidden attribute always hides elements even when Tailwind's\n @layer base [hidden] rule is not available in the shadow DOM */\n [hidden] {\n display: none !important;\n }\n\n .hidden-input {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n padding: 0;\n margin: 0;\n background: transparent;\n border: none;\n outline: none;\n color: transparent;\n caret-color: transparent;\n font-size: 16px; /* Minimum 16px prevents iOS zoom on focus */\n pointer-events: none;\n -webkit-appearance: none;\n appearance: none;\n }\n\n .hidden-input:focus {\n outline: none;\n }\n\n .hidden-input:disabled {\n cursor: not-allowed;\n }\n\n @keyframes blink {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n }\n }\n\n .character-box--caret::after {\n content: '';\n position: absolute;\n width: 2px;\n height: 60%;\n background-color: var(\n --color-accent-base,\n var(--ds-color-accent-base-default, blue)\n );\n animation: blink 1s step-end infinite;\n }\n\n /* Hide placeholder circle when the caret is at this position */\n .character-box--caret.character-box--empty {\n color: transparent;\n }\n\n /* Hide increment/decrement buttons on number inputs */\n input[type='number']::-webkit-outer-spin-button,\n input[type='number']::-webkit-inner-spin-button,\n input[type='number'] {\n -webkit-appearance: none;\n margin: 0;\n -moz-appearance: textfield !important;\n }\n\n .validation-message {\n display: flex;\n gap: 0.25rem;\n margin-block-start: 0.5rem;\n color: var(--ds-color-danger-text-subtle, #a22e2e);\n }\n\n .validation-icon {\n margin-block-start: 0.25rem;\n min-width: 1.25rem;\n min-height: 1.25rem;\n }\n `,\n];\n\n/**\n *\n * @event mid-change - Emitted when a change to the input value is comitted by the user\n * @event mid-input - Emitted when the input element recieves input\n * @event mid-complete - Emitted when all characters have been entered.\n * @event {detail: { validity: ValidityState }} mid-invalid-hide - Emitted when the error message should be hidden\n * @event {detail: { validity: ValidityState }} mid-invalid-show - Emitted when the error message should be shown\n *\n * @slot label - The input's label if you need to use HTML. Alternatively, you can use the `label` attribute.\n *\n * @csspart input-container - The wrapper around the input elements. This can be used to adjust font-size.\n * @csspart character-boxes - The container for the visual character boxes.\n * @csspart character-box - An individual character box.\n *\n * @method focus - Focuses the input element\n * @method clear - Clears the input\n */\n@customElement('mid-code-input')\nexport class MinidCodeInput extends FormControlMixin(\n styled(LitElement, styles)\n) {\n private readonly hasSlotControler = new HasSlotController(this, 'label');\n private readonly labelId = `mid-code-input-label-${nextUniqueId++}`;\n private readonly validationId = `mid-code-input-validation-${nextUniqueId++}`;\n\n @query('.hidden-input')\n private inputElement!: HTMLInputElement;\n\n @property({ reflect: true })\n value = '';\n\n @property()\n label = '';\n\n @property()\n type: 'number' | 'text' = 'text';\n\n /**\n * For displaying appropriate virtual keyboard\n */\n @property()\n inputmode: 'numeric' | 'text' = 'numeric';\n\n /**\n * Adjusts the font-size of the code inputs\n */\n @property()\n size: 'sm' | 'md' | 'lg' = 'sm';\n\n /**\n * Number of input characters or digits\n */\n @property({ type: Number })\n length = 5;\n\n @property({ type: Boolean })\n disabled = false;\n\n /**\n * Focuses the first input element on page load\n */\n @property({ type: Boolean })\n autofocus = false;\n\n /**\n * The minimum length of input that will be considered valid.\n */\n @property({ type: Number })\n minlength?: number;\n\n /**\n * Error message to display when the input is invalid, also activates invalid styling\n */\n @property()\n invalidmessage = '';\n\n /**\n * Visually hides `label` (still available for screen readers)\n */\n @property({ type: Boolean })\n hidelabel = false;\n\n /**\n * Makes the input required\n */\n @property({ type: Boolean })\n required = false;\n\n /**\n * A regular expression pattern to validate input against.\n */\n @property()\n pattern?: string;\n\n @state()\n private isFocused = false;\n\n static get formControlValidators() {\n return [\n requiredValidator,\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n ];\n }\n\n get validationTarget() {\n return this.inputElement;\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n webOtpApiInit(this.renderRoot);\n }\n\n private handleBoxClick(index: number) {\n if (this.disabled) {\n return;\n }\n\n // Truncate the value to the clicked position\n this.value = this.value.substring(0, index);\n\n // Focus the input to move the caret\n this.focus();\n }\n\n private handleFocus() {\n this.isFocused = true;\n /* don't select text, move caret to the end */\n if (this.value.length > 0) {\n const length = this.value.length;\n this.inputElement.setSelectionRange(length, length);\n }\n }\n\n private handleBlur() {\n this.isFocused = false;\n }\n\n private handleBeforeInput(e: InputEvent) {\n if (e.inputType === 'insertText' && e.data) {\n if (this.type == 'number' && e.data.replace(/\\D/g, '') == '') {\n e.preventDefault();\n }\n }\n }\n\n private handleInput(event: InputEvent) {\n const input = event.target as HTMLInputElement;\n let value = input.value;\n\n value = value.substring(0, this.length);\n\n if (input.value !== value) {\n input.value = value;\n }\n\n // Update the component's public `value` property if it has changed.\n if (this.value !== value) {\n this.value = value;\n this.setValue(value);\n }\n\n this.inputElement.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n\n if (this.value.length === this.length && this.value.length > 0) {\n this.inputElement.dispatchEvent(\n new Event('mid-complete', { bubbles: true, composed: true })\n );\n }\n }\n\n private handleChange() {\n this.inputElement.dispatchEvent(\n new Event('mid-change', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n if (event.key === 'Enter' && !hasModifier) {\n // Pressing enter when focused on an input should submit the form like a native input, but we wait a tick before\n // submitting to allow users to cancel the keydown event if they need to\n setTimeout(() => {\n // When using an Input Method Editor (IME), pressing enter will cause the form to submit unexpectedly. One way\n // to check for this is to look at event.isComposing, which will be true when the IME is open.\n if (!event.defaultPrevented && !event.isComposing) {\n this.form?.requestSubmit();\n }\n });\n }\n }\n\n clear() {\n this.value = '';\n this.setValue('');\n this.invalidmessage = '';\n }\n\n resetFormControl() {\n this.clear();\n }\n\n focus(options?: FocusOptions): void {\n this.inputElement?.focus(options);\n /* don't select text, move caret to the end */\n if (this.value.length > 0) {\n const length = this.value.length;\n this.inputElement.setSelectionRange(length, length);\n }\n }\n\n @watch('length')\n handleLengthChange() {\n if (this.value.length > this.length) {\n this.value = this.value.substring(0, this.length);\n }\n }\n\n override render() {\n const hasLabelSlot = this.hasSlotControler.test('label');\n const hasLabel = !!this.label || !!hasLabelSlot;\n const describedBy = this.invalidmessage ? this.validationId : undefined;\n\n const chars = this.value.split('');\n const displayValues = Array.from(\n { length: this.length },\n (_, i) => chars[i] || ''\n );\n const isComplete = this.value.length >= this.length;\n const caretIndex =\n this.disabled || this.length === 0\n ? -1\n : Math.min(this.value.length, this.length - 1);\n\n return html`\n <label\n id=\"${this.labelId}\"\n for=\"mid-code-input-hidden\"\n class=\"code-input-label ${classMap({\n 'code-input-label--hidden': this.hidelabel || !hasLabel,\n 'code-input-label--disabled': this.disabled,\n })}\"\n >\n <slot name=\"label\"> ${this.label} </slot>\n </label>\n <div\n part=\"input-container\"\n class=\"input-wrapper ${classMap({\n 'input-wrapper--sm': this.size === 'sm',\n 'input-wrapper--md': this.size === 'md',\n 'input-wrapper--lg': this.size === 'lg',\n 'input-wrapper--disabled': this.disabled,\n })}\"\n @click=${() => this.focus()}\n >\n <div part=\"character-boxes\" class=\"character-boxes\" aria-hidden=\"true\">\n ${displayValues.map((char, index) => {\n const isFocusTarget = this.isFocused && index === caretIndex;\n const hasCaret = isFocusTarget && !isComplete;\n return html`\n <div\n part=\"character-box\"\n aria-hidden=\"true\"\n class=\"character-box ${classMap({\n 'character-box--invalid': !!this.invalidmessage,\n 'character-box--caret': hasCaret,\n 'character-box--empty': !char,\n 'focus-ring-sm': isFocusTarget,\n })}\"\n @click=${(e: MouseEvent) => {\n e.stopPropagation();\n this.handleBoxClick(index);\n }}\n >\n ${char}\n </div>\n `;\n })}\n </div>\n <input\n class=\"hidden-input\"\n .value=\"${live(this.value)}\"\n id=\"mid-code-input-hidden\"\n type=\"${this.type}\"\n aria-labelledby=\"${this.labelId}\"\n aria-describedby=${ifDefined(describedBy)}\n aria-invalid=${this.invalidmessage ? 'true' : 'false'}\n aria-errormessage=${ifDefined(\n this.invalidmessage ? this.validationId : undefined\n )}\n maxlength=\"${this.length}\"\n ?autofocus=\"${this.autofocus}\"\n ?disabled=\"${this.disabled}\"\n ?required=\"${this.required}\"\n pattern=${ifDefined(this.pattern)}\n inputmode=\"${this.inputmode}\"\n autocomplete=\"one-time-code\"\n @beforeinput=\"${this.handleBeforeInput}\"\n @input=\"${this.handleInput}\"\n @change=\"${this.handleChange}\"\n @keydown=\"${this.handleKeydown}\"\n @focus=\"${this.handleFocus}\"\n @blur=\"${this.handleBlur}\"\n />\n </div>\n <div\n class=\"validation-message\"\n id=\"${this.validationId}\"\n aria-live=\"polite\"\n ?hidden=${!this.invalidmessage}\n >\n <mid-icon name=\"xmark-octagon-fill\" class=\"validation-icon\"></mid-icon>\n ${this.invalidmessage}\n </div>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code-input.js","sources":["../../src/components/code-input.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing, PropertyValues } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { watch } from '../internal/watch.ts';\nimport { FormControlMixin } from '../mixins/form-control.mixin.ts';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { HasSlotController } from '../internal/slot.ts';\nimport './icon/icon.component.ts';\nimport {\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n requiredValidator,\n} from '../mixins/validators.ts';\nimport { webOtpApiInit } from '../utilities/web-otp-api.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-code-input': MinidCodeInput;\n }\n}\n\nlet nextUniqueId = 0;\n\nconst styles = [\n css`\n :host {\n display: block;\n }\n\n .code-input-label {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n margin-block-end: 0.5rem;\n font-weight: 500;\n }\n\n .code-input-label--with-description {\n margin-block-end: 0.25rem;\n }\n\n .code-input-label--sm {\n font-size: var(--ds-body-sm-font-size, 1rem);\n line-height: var(--ds-body-md-line-height, 1.5);\n }\n\n .code-input-label--md {\n font-size: var(--ds-body-md-font-size, 1.125rem);\n line-height: var(--ds-body-md-line-height, 1.5);\n }\n\n .code-input-label--lg {\n font-size: var(--ds-body-lg-font-size, 1.3125rem);\n line-height: var(--ds-body-md-line-height, 1.5);\n }\n\n .code-input-description {\n margin-block-end: 0.5rem;\n color: var(--ds-color-neutral-text-subtle, #545e6b);\n }\n\n .code-input-label--hidden,\n .code-input-description--hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n .code-input-label--disabled,\n .code-input-description--disabled,\n .input-wrapper--disabled {\n opacity: var(--ds-opacity-disabled, 0.38);\n }\n\n .input-wrapper {\n position: relative;\n cursor: text;\n width: fit-content;\n font-size: 1rem;\n line-height: 1.3;\n font-weight: 500;\n }\n\n .input-wrapper--sm {\n font-size: var(--ds-heading-sm-font-size, 1.125rem);\n line-height: var(--ds-heading-sm-line-height, 1.3);\n font-weight: var(--ds-heading-sm-font-weight, 500);\n }\n\n .input-wrapper--md {\n font-size: var(--ds-heading-md-font-size, 1.25rem);\n line-height: var(--ds-heading-md-line-height, 1.3);\n font-weight: var(--ds-heading-md-font-weight, 500);\n }\n\n .input-wrapper--lg {\n font-size: var(--ds-heading-lg-font-size, 1.5rem);\n line-height: var(--ds-heading-lg-line-height, 1.3);\n font-weight: var(--ds-heading-lg-font-weight, 500);\n }\n\n .input-wrapper--disabled {\n cursor: not-allowed;\n }\n\n .character-boxes {\n display: inline-flex;\n gap: var(--mid-code-input-gap, 0.5rem);\n }\n\n .character-box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n box-sizing: border-box;\n width: var(--mid-code-input-box-size, var(--ds-size-13, 3.25rem));\n height: var(--mid-code-input-box-size, var(--ds-size-13, 3.25rem));\n padding-inline: 0.25rem;\n user-select: none;\n text-align: center;\n font-family:\n ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,\n 'Liberation Mono', 'Courier New', monospace;\n line-height: 1;\n border: var(--ds-border-width-default, 1px) solid\n var(\n --mid-code-input-border-color,\n var(--ds-color-neutral-border-default, #717a84)\n );\n border-radius: var(\n --mid-code-input-border-radius,\n var(--ds-border-radius-md, 0.25rem)\n );\n background-color: var(\n --mid-code-input-background,\n var(--ds-color-neutral-background-default, #ffffff)\n );\n color: var(--mid-code-input-text-color, inherit);\n }\n\n .character-box--empty {\n color: var(\n --mid-code-input-placeholder-color,\n var(--ds-color-neutral-surface-active, #c7cacf)\n );\n }\n\n .character-box--empty::before {\n content: '';\n box-sizing: border-box;\n width: 0.55em;\n height: 0.55em;\n border: 2px solid currentColor;\n border-radius: 50%;\n }\n\n .character-box--invalid {\n border-width: 2px;\n border-color: var(\n --mid-code-input-danger-border-color,\n var(--ds-color-danger-border-default, #ce4d4d)\n );\n background-color: var(\n --mid-code-input-danger-background,\n var(--ds-color-danger-surface-tinted, #f8e4e4)\n );\n }\n\n .character-box--invalid.character-box--empty {\n color: var(\n --mid-code-input-danger-placeholder-color,\n var(--ds-color-danger-surface-active, #edbfbf)\n );\n }\n\n .focus-ring-sm {\n outline: 2px solid var(--ds-color-focus-outer, #1f2c3d);\n outline-offset: 2px;\n box-shadow: 0 0 0 2px var(--ds-color-focus-inner, #ffffff);\n }\n\n /* Ensure hidden attribute always hides elements even when Tailwind's\n @layer base [hidden] rule is not available in the shadow DOM */\n [hidden] {\n display: none !important;\n }\n\n .hidden-input {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n padding: 0;\n margin: 0;\n background: transparent;\n border: none;\n outline: none;\n color: transparent;\n caret-color: transparent;\n font-size: 16px; /* Minimum 16px prevents iOS zoom on focus */\n pointer-events: none;\n -webkit-appearance: none;\n appearance: none;\n }\n\n .hidden-input:focus {\n outline: none;\n }\n\n .hidden-input:disabled {\n cursor: not-allowed;\n }\n\n @keyframes blink {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n }\n }\n\n .character-box--caret::after {\n content: '';\n position: absolute;\n width: 2px;\n height: 60%;\n background-color: var(\n --color-accent-base,\n var(--ds-color-accent-base-default, blue)\n );\n animation: blink 1s step-end infinite;\n }\n\n .character-box--caret-leading::after {\n inset-inline-start: 0;\n }\n\n /* Hide placeholder circle when the caret is at this position */\n .character-box--caret.character-box--empty {\n color: transparent;\n }\n\n .validation-message {\n display: flex;\n gap: 0.25rem;\n color: var(--ds-color-danger-text-subtle, #a22e2e);\n }\n\n .validation-message--visible {\n margin-block-start: 0.5rem;\n }\n\n .validation-icon {\n margin-block-start: 0.25rem;\n min-width: 1.25rem;\n min-height: 1.25rem;\n }\n `,\n];\n\n/**\n *\n * @event mid-change - Emitted when a change to the input value is comitted by the user\n * @event mid-input - Emitted when the input element recieves input\n * @event mid-complete - Emitted when all characters have been entered.\n * @event {detail: { validity: ValidityState }} mid-invalid-hide - Emitted when the error message should be hidden\n * @event {detail: { validity: ValidityState }} mid-invalid-show - Emitted when the error message should be shown\n *\n * @slot label - The input's label if you need to use HTML. Alternatively, you can use the `label` attribute.\n * @slot description - The input's description if you need to use HTML. Alternatively, you can use the `description` attribute.\n *\n * @csspart input-container - The wrapper around the input elements. This can be used to adjust font-size.\n * @csspart description - The description shown between the label and the character boxes.\n * @csspart character-boxes - The container for the visual character boxes.\n * @csspart character-box - An individual character box.\n * @csspart validation-message - The error message shown by `invalidmessage`.\n *\n * @method focus - Focuses the input element\n * @method clear - Clears the input\n */\n@customElement('mid-code-input')\nexport class MinidCodeInput extends FormControlMixin(\n styled(LitElement, styles)\n) {\n private readonly hasSlotControler = new HasSlotController(\n this,\n 'label',\n 'description'\n );\n private readonly labelId = `mid-code-input-label-${nextUniqueId++}`;\n private readonly descriptionId = `mid-code-input-description-${nextUniqueId++}`;\n private readonly validationId = `mid-code-input-validation-${nextUniqueId++}`;\n\n @query('.hidden-input')\n private inputElement!: HTMLInputElement;\n\n @property({ reflect: true })\n value = '';\n\n @property()\n label = '';\n\n @property()\n description = '';\n\n @property()\n type: 'number' | 'text' = 'text';\n\n /**\n * For displaying appropriate virtual keyboard\n */\n @property()\n inputmode: 'numeric' | 'text' = 'numeric';\n\n /**\n * Adjusts the font-size of the code inputs\n */\n @property()\n size: 'sm' | 'md' | 'lg' = 'sm';\n\n @property()\n labelsize?: 'sm' | 'md' | 'lg';\n\n /**\n * Number of input characters or digits\n */\n @property({ type: Number })\n length = 5;\n\n @property({ type: Boolean })\n disabled = false;\n\n /**\n * Focuses the first input element on page load\n */\n @property({ type: Boolean })\n autofocus = false;\n\n /**\n * The minimum length of input that will be considered valid.\n */\n @property({ type: Number })\n minlength?: number;\n\n /**\n * Error message to display when the input is invalid, also activates invalid styling\n */\n @property()\n invalidmessage = '';\n\n /**\n * Visually hides `label` (still available for screen readers)\n */\n @property({ type: Boolean })\n hidelabel = false;\n\n @property({ type: Boolean })\n hidedescription = false;\n\n /**\n * Makes the input required\n */\n @property({ type: Boolean })\n required = false;\n\n /**\n * A regular expression pattern to validate input against.\n */\n @property()\n pattern?: string;\n\n @state()\n private isFocused = false;\n\n @state()\n private caretPosition = 0;\n\n static get formControlValidators() {\n return [\n requiredValidator,\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n ];\n }\n\n get validationTarget() {\n return this.inputElement;\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n webOtpApiInit(this.renderRoot);\n }\n\n override connectedCallback() {\n super.connectedCallback();\n this.ownerDocument.addEventListener(\n 'selectionchange',\n this.handleSelectionChange\n );\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.ownerDocument.removeEventListener(\n 'selectionchange',\n this.handleSelectionChange\n );\n }\n\n private handleBoxClick(index: number) {\n if (this.disabled) {\n return;\n }\n\n // Truncate the value to the clicked position\n this.value = this.value.substring(0, index);\n\n // Focus the input to move the caret\n this.focus();\n }\n\n /**\n * Catches caret moves we did not make - arrow keys, Home/End, word jumps,\n * shift-selection - without enumerating keys, and keeps up while a key is held.\n *\n * Must be listened for on the document: for a caret move the user made,\n * Chromium fires it only there, not at the input and not into the shadow root,\n * so an `@selectionchange` binding on either never runs.\n */\n private handleSelectionChange = () => {\n // Fires for selection changes anywhere on the page\n if (this.isFocused) {\n this.syncCaretPosition();\n }\n };\n\n private syncCaretPosition() {\n const input = this.inputElement;\n\n if (!input) {\n return;\n }\n\n this.caretPosition =\n (input.selectionDirection === 'backward'\n ? input.selectionStart\n : input.selectionEnd) ?? this.value.length;\n }\n\n private handleFocus() {\n this.isFocused = true;\n /* don't select text, move caret to the end */\n if (this.value.length > 0) {\n const length = this.value.length;\n this.inputElement.setSelectionRange(length, length);\n }\n this.syncCaretPosition();\n }\n\n private handleBlur() {\n this.isFocused = false;\n }\n\n private filterValue(value: string) {\n return this.type === 'number' ? value.replace(/\\D/g, '') : value;\n }\n\n private handleBeforeInput(e: InputEvent) {\n if (this.type === 'number' && e.inputType === 'insertText' && e.data) {\n if (!/\\d/.test(e.data)) {\n e.preventDefault();\n }\n }\n }\n\n private handlePaste(event: ClipboardEvent) {\n if (this.type !== 'number') {\n return;\n }\n\n const pasted = event.clipboardData?.getData('text') ?? '';\n const digits = this.filterValue(pasted);\n\n if (digits === pasted) {\n return;\n }\n\n event.preventDefault();\n\n const input = this.inputElement;\n const start = input.selectionStart ?? input.value.length;\n const end = input.selectionEnd ?? start;\n const next = (\n input.value.slice(0, start) +\n digits +\n input.value.slice(end)\n ).substring(0, this.length);\n\n if (next === input.value) {\n return;\n }\n\n input.value = next;\n input.dispatchEvent(\n new InputEvent('input', { bubbles: true, composed: true })\n );\n\n const caret = Math.min(start + digits.length, input.value.length);\n input.setSelectionRange(caret, caret);\n this.syncCaretPosition();\n }\n\n private handleInput(event: InputEvent) {\n const input = event.target as HTMLInputElement;\n let value = this.filterValue(input.value);\n\n value = value.substring(0, this.length);\n\n if (input.value !== value) {\n input.value = value;\n }\n\n this.syncCaretPosition();\n\n // Update the component's public `value` property if it has changed.\n if (this.value !== value) {\n this.value = value;\n this.setValue(value);\n }\n\n this.inputElement.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n\n if (this.value.length === this.length && this.value.length > 0) {\n this.inputElement.dispatchEvent(\n new Event('mid-complete', { bubbles: true, composed: true })\n );\n }\n }\n\n private handleChange() {\n this.inputElement.dispatchEvent(\n new Event('mid-change', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n if (event.key === 'Enter' && !hasModifier) {\n // Pressing enter when focused on an input should submit the form like a native input, but we wait a tick before\n // submitting to allow users to cancel the keydown event if they need to\n setTimeout(() => {\n // When using an Input Method Editor (IME), pressing enter will cause the form to submit unexpectedly. One way\n // to check for this is to look at event.isComposing, which will be true when the IME is open.\n if (!event.defaultPrevented && !event.isComposing) {\n this.form?.requestSubmit();\n }\n });\n }\n }\n\n clear() {\n this.value = '';\n this.setValue('');\n this.invalidmessage = '';\n this.caretPosition = 0;\n }\n\n resetFormControl() {\n this.clear();\n }\n\n focus(options?: FocusOptions): void {\n this.inputElement?.focus(options);\n /* don't select text, move caret to the end */\n if (this.value.length > 0) {\n const length = this.value.length;\n this.inputElement.setSelectionRange(length, length);\n }\n this.syncCaretPosition();\n }\n\n @watch('length')\n handleLengthChange() {\n if (this.value.length > this.length) {\n this.value = this.value.substring(0, this.length);\n }\n }\n\n @watch(['value', 'type'])\n handleValueChange() {\n const filtered = this.filterValue(this.value);\n\n if (filtered !== this.value) {\n this.value = filtered;\n }\n\n this.caretPosition = Math.min(this.caretPosition, this.value.length);\n this.setValue(filtered);\n }\n\n override render() {\n const hasLabelSlot = this.hasSlotControler.test('label');\n const hasLabel = !!this.label || !!hasLabelSlot;\n const hasDescriptionSlot = this.hasSlotControler.test('description');\n const hasDescription = !!this.description || !!hasDescriptionSlot;\n const describedBy =\n [\n hasDescription ? this.descriptionId : undefined,\n this.invalidmessage ? this.validationId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n const chars = this.value.split('');\n const displayValues = Array.from(\n { length: this.length },\n (_, i) => chars[i] || ''\n );\n const caretIndex =\n this.disabled || this.length === 0\n ? -1\n : Math.min(this.caretPosition, this.length - 1);\n const caretIsInABox = this.caretPosition < this.length;\n\n return html`\n <label\n id=\"${this.labelId}\"\n for=\"mid-code-input-hidden\"\n class=\"code-input-label ${classMap({\n 'code-input-label--sm': this.labelsize === 'sm',\n 'code-input-label--md': this.labelsize === 'md',\n 'code-input-label--lg': this.labelsize === 'lg',\n 'code-input-label--hidden': this.hidelabel || !hasLabel,\n 'code-input-label--with-description': hasDescription,\n 'code-input-label--disabled': this.disabled,\n })}\"\n >\n <slot name=\"label\"> ${this.label} </slot>\n </label>\n ${hasDescription\n ? html`\n <div\n id=\"${this.descriptionId}\"\n part=\"description\"\n aria-hidden=\"true\"\n class=\"code-input-description ${classMap({\n 'code-input-description--hidden': this.hidedescription,\n 'code-input-description--disabled': this.disabled,\n })}\"\n >\n <slot name=\"description\"> ${this.description} </slot>\n </div>\n `\n : nothing}\n <div\n part=\"input-container\"\n class=\"input-wrapper ${classMap({\n 'input-wrapper--sm': this.size === 'sm',\n 'input-wrapper--md': this.size === 'md',\n 'input-wrapper--lg': this.size === 'lg',\n 'input-wrapper--disabled': this.disabled,\n })}\"\n @click=${() => this.focus()}\n >\n <div part=\"character-boxes\" class=\"character-boxes\" aria-hidden=\"true\">\n ${displayValues.map((char, index) => {\n const isFocusTarget = this.isFocused && index === caretIndex;\n const hasCaret = isFocusTarget && caretIsInABox;\n return html`\n <div\n part=\"character-box\"\n aria-hidden=\"true\"\n class=\"character-box ${classMap({\n 'character-box--invalid': !!this.invalidmessage,\n 'character-box--caret': hasCaret,\n 'character-box--caret-leading': hasCaret && !!char,\n 'character-box--empty': !char,\n 'focus-ring-sm': isFocusTarget,\n })}\"\n @click=${(e: MouseEvent) => {\n e.stopPropagation();\n this.handleBoxClick(index);\n }}\n >\n ${char}\n </div>\n `;\n })}\n </div>\n <input\n class=\"hidden-input\"\n .value=\"${live(this.value)}\"\n id=\"mid-code-input-hidden\"\n type=\"text\"\n aria-labelledby=\"${this.labelId}\"\n aria-describedby=${ifDefined(describedBy)}\n aria-invalid=${this.invalidmessage ? 'true' : 'false'}\n aria-errormessage=${ifDefined(\n this.invalidmessage ? this.validationId : undefined\n )}\n maxlength=\"${this.length}\"\n ?autofocus=\"${this.autofocus}\"\n ?disabled=\"${this.disabled}\"\n ?required=\"${this.required}\"\n pattern=${ifDefined(this.pattern)}\n inputmode=\"${this.inputmode}\"\n autocomplete=\"one-time-code\"\n @beforeinput=\"${this.handleBeforeInput}\"\n @paste=\"${this.handlePaste}\"\n @input=\"${this.handleInput}\"\n @change=\"${this.handleChange}\"\n @keydown=\"${this.handleKeydown}\"\n @focus=\"${this.handleFocus}\"\n @blur=\"${this.handleBlur}\"\n />\n </div>\n <div\n class=\"validation-message ${classMap({\n 'validation-message--visible': !!this.invalidmessage,\n })}\"\n part=\"validation-message\"\n id=\"${this.validationId}\"\n aria-live=\"polite\"\n >\n ${this.invalidmessage\n ? html`<mid-icon\n name=\"xmark-octagon-fill\"\n class=\"validation-icon\"\n ></mid-icon>\n ${this.invalidmessage}`\n : nothing}\n </div>\n `;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAwBA,IAAI,eAAe;AAEnB,MAAM,SAAS;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
@@ -25,6 +25,7 @@ declare const MinidTextfield_base: import('../types/mixin-constructor.ts').Const
25
25
  * @csspart field - The element that wraps the label, input, and help text.
26
26
  * @csspart clear-button - The clear button
27
27
  * @csspart password-toggle-button - The button for toggling password visibility
28
+ * @csspart validation-message - The error message shown by `invalidmessage`.
28
29
  */
29
30
  export declare class MinidTextfield extends MinidTextfield_base {
30
31
  private readonly inputId;
@@ -1 +1 @@
1
- {"version":3,"file":"textfield.component.d.ts","sourceRoot":"","sources":["../../src/components/textfield.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAiB1E,OAAO,0BAA0B,CAAC;AAClC,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAC;AAKjD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,cAAc,CAAC;KACjC;CACF;;AAyBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,cAAe,SAAQ,mBAA4C;IAC9E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4D;IAC7F,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,YAAY,CAAM;IAG1B,KAAK,EAAG,gBAAgB,CAAC;IAGzB,KAAK,SAAM;IAGX,WAAW,SAAM;IAGjB,KAAK,SAAM;IAGX,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAGhC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,YAAY,CAAC,EAAE,QAAQ,CAAC;IAExB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IAEH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IAEH,cAAc,SAAM;IAGpB,IAAI,EACA,MAAM,GACN,gBAAgB,GAChB,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,KAAK,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,MAAM,CAAU;IAEpB;;OAEG;IAEH,SAAS,EACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,KAAK,GACL,OAAO,GACP,SAAS,GACT,SAAS,CAAU;IAEvB;;OAEG;IAEH,SAAS,UAAS;IAElB;;;OAGG;IAEH,cAAc,UAAS;IAEvB;;;OAGG;IAEH,eAAe,UAAS;IAGxB,QAAQ,UAAS;IAGjB,QAAQ,UAAS;IAEjB;;OAEG;IAEH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAEH,SAAS,UAAS;IAElB;;;;;;OAMG;IAEH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAGhB,QAAQ,UAAS;IAEjB,MAAM,KAAK,qBAAqB,qDAQ/B;;IAYQ,iBAAiB,IAAI,IAAI;IAKlC,IAAI,gBAAgB,qBAEnB;IAED,SAAS,CAAC,YAAY,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAKhE,oBAAoB,IAAI,IAAI;IAI5B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,gBAAgB;IAmBxB,KAAK;IAKL,gBAAgB;IAKhB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAKlC,iBAAiB;IAKX,gBAAgB;IAUb,MAAM;CA6IhB"}
1
+ {"version":3,"file":"textfield.component.d.ts","sourceRoot":"","sources":["../../src/components/textfield.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAiB1E,OAAO,0BAA0B,CAAC;AAClC,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAC;AAKjD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,cAAc,CAAC;KACjC;CACF;;AAoCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,cAAe,SAAQ,mBAA4C;IAC9E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4D;IAC7F,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,YAAY,CAAM;IAG1B,KAAK,EAAG,gBAAgB,CAAC;IAGzB,KAAK,SAAM;IAGX,WAAW,SAAM;IAGjB,KAAK,SAAM;IAGX,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAGhC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,YAAY,CAAC,EAAE,QAAQ,CAAC;IAExB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IAEH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IAEH,cAAc,SAAM;IAGpB,IAAI,EACA,MAAM,GACN,gBAAgB,GAChB,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,KAAK,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,MAAM,CAAU;IAEpB;;OAEG;IAEH,SAAS,EACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,KAAK,GACL,OAAO,GACP,SAAS,GACT,SAAS,CAAU;IAEvB;;OAEG;IAEH,SAAS,UAAS;IAElB;;;OAGG;IAEH,cAAc,UAAS;IAEvB;;;OAGG;IAEH,eAAe,UAAS;IAGxB,QAAQ,UAAS;IAGjB,QAAQ,UAAS;IAEjB;;OAEG;IAEH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAEH,SAAS,UAAS;IAElB;;;;;;OAMG;IAEH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAGhB,QAAQ,UAAS;IAEjB,MAAM,KAAK,qBAAqB,qDAQ/B;;IAYQ,iBAAiB,IAAI,IAAI;IAKlC,IAAI,gBAAgB,qBAEnB;IAED,SAAS,CAAC,YAAY,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAKhE,oBAAoB,IAAI,IAAI;IAI5B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,gBAAgB;IAmBxB,KAAK;IAKL,gBAAgB;IAKhB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAKlC,iBAAiB;IAKX,gBAAgB;IAUb,MAAM;CAiJhB"}
@@ -42,6 +42,17 @@ const styles = [
42
42
  .ds-field-affixes {
43
43
  background: var(--ds-color-neutral-background-tinted);
44
44
  }
45
+
46
+ /* The validation message stays in the DOM so its text lands in a live region
47
+ the screen reader is already watching - WebKit does not reliably announce
48
+ one revealed at the same moment the text arrives. When empty it must paint
49
+ nothing and take no room: the element drops the ds-validation-message class
50
+ (whose ::before paints an error icon regardless of the text) and this rule
51
+ cancels the sibling spacing from .ds-field > * + *, which the .ds-field >
52
+ prefix is enough to outrank without !important. */
53
+ .ds-field > .validation-message--empty {
54
+ margin-top: 0;
55
+ }
45
56
  `
46
57
  ];
47
58
  let nextUniqueId = 0;
@@ -230,6 +241,7 @@ let MinidTextfield = class extends FormControlMixin(styled(LitElement, styles))
230
241
  .value=${live(this.value)}
231
242
  ?disabled=${this.disabled}
232
243
  ?readonly=${this.readonly}
244
+ ?required=${this.required}
233
245
  ?autofocus=${this.autofocus}
234
246
  autocomplete=${ifDefined(this.autocomplete)}
235
247
  type=${this.type === "password" && this.passwordvisible ? "text" : this.type}
@@ -292,10 +304,13 @@ let MinidTextfield = class extends FormControlMixin(styled(LitElement, styles))
292
304
  ${hasSuffix ? html`<span part="suffix" class="ds-field-affix"><slot name="suffix"></slot></span>` : html`<slot name="suffix"></slot>`}
293
305
  </div>
294
306
  <p
295
- class="ds-validation-message"
307
+ class="${classMap({
308
+ "ds-validation-message": !!this.invalidmessage,
309
+ "validation-message--empty": !this.invalidmessage
310
+ })}"
311
+ part="validation-message"
296
312
  id="${this.validationId}"
297
313
  aria-live="polite"
298
- ?hidden=${!this.invalidmessage}
299
314
  >
300
315
  ${this.invalidmessage}
301
316
  </p>
@@ -1 +1 @@
1
- {"version":3,"file":"textfield.js","sources":["../../src/components/textfield.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing, type PropertyValues } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\nimport { stringConverter } from '../internal/string-converter';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HasSlotController } from '../internal/slot';\nimport { FormControlMixin } from '../mixins/form-control.mixin';\nimport {\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n requiredValidator,\n typeMismatchValidator,\n} from '../mixins/validators';\nimport { watch } from '../internal/watch';\nimport './icon/icon.component.ts';\nimport { MaskInput, type MaskType } from 'maska';\nimport { getLang } from '../utilities/lang';\nimport { getTranslations } from '../utilities/translations';\nimport { LangController } from '../controllers/lang.controller.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-textfield': MinidTextfield;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: block;\n }\n\n /* Hide increment/decrement buttons on inputs */\n input[type='number']::-webkit-outer-spin-button,\n input[type='number']::-webkit-inner-spin-button,\n input[type='number'] {\n -webkit-appearance: none;\n margin: 0;\n -moz-appearance: textfield !important;\n }\n\n .ds-field-affixes {\n background: var(--ds-color-neutral-background-tinted);\n }\n `,\n];\n\nlet nextUniqueId = 0;\n\n/**\n *\n * @event mid-change - Emitted when a change to the input value is comitted by the user\n * @event mid-input - Emitted when the input element recieves input\n * @event mid-clear - Emitted when the input value is cleared\n * @event mid-focus - Emitted when input element is focused\n * @event mid-blur - Emitted when focus moves away from input element\n * @event {detail: { validity: ValidityState }} mid-invalid-hide - Emitted when the error message should be hidden\n * @event {detail: { validity: ValidityState }} mid-invalid-show - Emitted when the error message should be shown\n *\n * @slot prefix - Used for decoration to the left of the input\n * @slot suffix - Used for decoration to the right of the input\n * @slot label - The input's label. Alternatively, you can use the `label` attribute.\n *\n * @csspart base - The input's wrapper that has the input field styling.\n * @csspart input - The internal `<input>` element.\n * @csspart field - The element that wraps the label, input, and help text.\n * @csspart clear-button - The clear button\n * @csspart password-toggle-button - The button for toggling password visibility\n */\n@customElement('mid-textfield')\nexport class MinidTextfield extends FormControlMixin(styled(LitElement, styles)) {\n private readonly inputId!: string;\n private readonly descriptionId!: string;\n private readonly validationId!: string;\n private readonly hasSlotControler = new HasSlotController(this, 'label', 'prefix', 'suffix');\n private inputMask?: MaskInput;\n private initialValue = '';\n\n @query('input')\n input!: HTMLInputElement;\n\n @property()\n label = '';\n\n @property()\n description = '';\n\n @property()\n value = '';\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ converter: stringConverter })\n placeholder?: string;\n\n /**\n * Autofocus the input field on page load\n */\n @property({ type: Boolean })\n autofocus = false;\n\n /**\n * User agent autocomplete hint\n */\n @property()\n autocomplete?: AutoFill;\n\n /**\n * The minimum length of input that will be considered valid.\n */\n @property({ type: Number })\n minlength?: number;\n\n /**\n * The maximum length of input that will be considered valid.\n */\n @property({ type: Number })\n maxlength?: number;\n\n /**\n * The input's minimum value. Only applies to date and number input types.\n */\n @property()\n min?: number | string;\n\n /**\n * The input's maximum value. Only applies to date and number input types.\n */\n @property()\n max?: number | string;\n\n /**\n * Error message to display when the input is invalid, also activates invalid styling\n */\n @property()\n invalidmessage = '';\n\n @property()\n type:\n | 'date'\n | 'datetime-local'\n | 'email'\n | 'file'\n | 'month'\n | 'number'\n | 'password'\n | 'search'\n | 'tel'\n | 'text'\n | 'time'\n | 'url'\n | 'week' = 'text';\n\n /**\n * For displaying appropriate virtual keyboard\n */\n @property()\n inputmode:\n | 'none'\n | 'text'\n | 'tel'\n | 'url'\n | 'email'\n | 'numeric'\n | 'decimal' = 'text';\n\n /**\n * Adds a clear button when the input is not empty.\n */\n @property({ type: Boolean })\n clearable = false;\n\n /**\n * Adds a button to toggle the password's visibility.\n * Only applies if type is password\n */\n @property({ type: Boolean })\n passwordtoggle = false;\n\n /**\n * Determines wether the password is currently visible.\n * Only applies if type is password\n */\n @property({ type: Boolean })\n passwordvisible = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /**\n * A regular expression pattern to validate input against.\n */\n @property()\n pattern?: string;\n\n /**\n * Makes the input required\n */\n @property({ type: Boolean })\n required = false;\n\n /**\n * Visually hides `label` and `description` (still available for screen readers)\n */\n @property({ type: Boolean })\n hidelabel = false;\n\n /**\n * Modify input value based on mask e.g: `\"##:##\"` = 12:34.\n * `#`: /[0-9]/\n * `@`: /[a-zA-Z]/\n * `*`: /[a-zA-Z0-9]/\n * For more information go to https://beholdr.github.io/maska\n */\n @property()\n mask?: MaskType;\n\n @state()\n hasFocus = false;\n\n static get formControlValidators() {\n return [\n requiredValidator,\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n typeMismatchValidator,\n ];\n }\n\n constructor() {\n super();\n new LangController(this);\n nextUniqueId++;\n this.inputId = `mid-textfield-input-${nextUniqueId}`;\n this.descriptionId = `mid-textfield-description-${nextUniqueId}`;\n this.validationId = `mid-textfield-validation-${nextUniqueId}`;\n this.setValue(this.value);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.initialValue = this.value;\n }\n\n get validationTarget() {\n return this.input;\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n super.firstUpdated(_changedProperties);\n this.setValue(this.value);\n }\n\n disconnectedCallback(): void {\n this.inputMask?.destroy();\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n if (event.key === 'Enter' && !hasModifier) {\n setTimeout(() => {\n if (!event.defaultPrevented && !event.isComposing) {\n this.form.requestSubmit();\n }\n });\n }\n }\n\n private handleBlur() {\n this.hasFocus = false;\n this.dispatchEvent(\n new Event('mid-blur', { bubbles: true, composed: true })\n );\n }\n\n private handleChange() {\n this.value = this.input.value;\n this.dispatchEvent(\n new Event('mid-change', { bubbles: true, composed: true })\n );\n }\n\n private handleInput() {\n let tmp_value = this.input.value;\n\n if (this.type === 'number') {\n tmp_value = tmp_value.replace(/[^0-9]/g, '');\n }\n\n this.value = tmp_value;\n this.setValue(this.value);\n this.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n }\n\n private handleFocus() {\n this.hasFocus = true;\n this.dispatchEvent(\n new Event('mid-focus', { composed: true, bubbles: true })\n );\n }\n\n private handlePasswordToggle() {\n this.passwordvisible = !this.passwordvisible;\n }\n\n private handleClearClick(event: MouseEvent) {\n event.preventDefault();\n\n if (this.value !== '') {\n this.value = '';\n this.dispatchEvent(\n new Event('mid-clear', { composed: true, bubbles: true })\n );\n this.dispatchEvent(\n new Event('mid-input', { composed: true, bubbles: true })\n );\n this.dispatchEvent(\n new Event('mid-change', { composed: true, bubbles: true })\n );\n }\n\n this.input.focus();\n }\n\n focus() {\n this.hasFocus = true;\n this.input.focus();\n }\n\n resetFormControl() {\n this.invalidmessage = '';\n this.value = this.initialValue;\n }\n\n forceError(message?: string): void {\n super.forceError(message);\n }\n\n @watch('value')\n handleValueUpdate() {\n this.setValue(this.value);\n }\n\n @watch('mask')\n async handleMaskUpdate() {\n if (!this.mask) return;\n await this.updateComplete;\n this.inputMask?.destroy();\n this.inputMask = new MaskInput(this.input, {\n mask: this.mask,\n eager: true,\n });\n }\n\n override render() {\n const lang = getLang(this);\n const t = getTranslations(lang);\n const hasLabelSlot = this.hasSlotControler.test('label');\n const hasLabel = !!this.label || !!hasLabelSlot;\n const hasPrefix = this.hasSlotControler.test('prefix');\n const hasSuffix = this.hasSlotControler.test('suffix');\n const hasClearIcon = this.clearable && !this.disabled && !this.readonly;\n const hasAffixes = hasPrefix || hasSuffix || hasClearIcon || (this.passwordtoggle && !this.disabled);\n const isClearIconVisible =\n hasClearIcon && (typeof this.value === 'number' || this.value.length > 0);\n const describedBy = [\n this.description ? this.descriptionId : undefined,\n this.invalidmessage ? this.validationId : undefined,\n ]\n .filter(Boolean)\n .join(' ');\n\n return html`\n <ds-field\n part=\"field\"\n class=\"ds-field\"\n data-size=${this.size}\n >\n <label\n for=\"${this.inputId}\"\n class=\"${classMap({\n 'sr-only': this.hidelabel || !hasLabel,\n })} ds-label\"\n >\n <slot name=\"label\"> ${this.label} </slot>\n </label>\n ${this.description\n ? html`\n <div\n id=\"${this.descriptionId}\"\n part=\"description\"\n aria-hidden=\"true\"\n class=\"${classMap({\n 'sr-only': this.hidelabel,\n })}\"\n >\n ${this.description}\n </div>\n `\n : nothing}\n <div\n part=\"base\"\n class=\"${hasAffixes ? 'ds-field-affixes' : ''}\"\n >\n ${hasPrefix ? html`<span class=\"ds-field-affix\"><slot name=\"prefix\"></slot></span>` : html`<slot name=\"prefix\"></slot>`}\n <input\n id=\"${this.inputId}\"\n class=\"ds-input\"\n part=\"input\"\n lang=${lang}\n .value=${live(this.value)}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?autofocus=${this.autofocus}\n autocomplete=${ifDefined(this.autocomplete as any)}\n type=${this.type === 'password' && this.passwordvisible\n ? 'text'\n : this.type}\n aria-describedby=${ifDefined(describedBy || undefined)}\n aria-invalid=${this.invalidmessage ? 'true' : 'false'}\n aria-errormessage=${ifDefined(\n this.invalidmessage ? this.validationId : undefined\n )}\n placeholder=${ifDefined(this.placeholder)}\n minlength=${ifDefined(this.minlength)}\n maxlength=${ifDefined(this.maxlength)}\n min=${ifDefined(this.min)}\n max=${ifDefined(this.max)}\n pattern=${ifDefined(this.pattern)}\n inputmode=${this.inputmode}\n @input=${this.handleInput}\n @change=${this.handleChange}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n @keydown=${this.handleKeydown}\n />\n ${isClearIconVisible\n ? html`\n <span class=\"ds-field-affix\" part=\"clear-button\">\n <button\n type=\"button\"\n class=\"focus-visible:focus-ring flex items-center justify-center rounded-sm\"\n aria-label=${t.clear}\n @click=${this.handleClearClick}\n >\n <mid-icon\n class=\"size-7\"\n library=\"nav-aksel\"\n name=\"trash\"\n ></mid-icon>\n </button>\n </span>\n `\n : ''}\n ${this.passwordtoggle && !this.disabled\n ? html`\n <span class=\"ds-field-affix\" part=\"password-toggle-button\">\n <button\n type=\"button\"\n class=\"focus-visible:focus-ring flex items-center justify-center rounded-sm\"\n aria-label=${this.passwordvisible\n ? t.hidePassword\n : t.showPassword}\n @click=${this.handlePasswordToggle}\n >\n ${this.passwordvisible\n ? html` <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"eye-slash\"\n ></mid-icon>`\n : html`\n <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"eye\"\n ></mid-icon>\n `}\n </button>\n </span>\n `\n : ''}\n ${hasSuffix ? html`<span part=\"suffix\" class=\"ds-field-affix\"><slot name=\"suffix\"></slot></span>` : html`<slot name=\"suffix\"></slot>`}\n </div>\n <p\n class=\"ds-validation-message\"\n id=\"${this.validationId}\"\n aria-live=\"polite\"\n ?hidden=${!this.invalidmessage}\n >\n ${this.invalidmessage}\n </p>\n </ds-field>\n `;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAM,SAAS;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBF;AAEA,IAAI,eAAe;AAuBZ,IAAM,iBAAN,cAA6B,iBAAiB,OAAO,YAAY,MAAM,CAAC,EAAE;AAAA,EAoK/E,cAAc;AACZ,UAAA;AAjKF,SAAiB,mBAAmB,IAAI,kBAAkB,MAAM,SAAS,UAAU,QAAQ;AAE3F,SAAQ,eAAe;AAMvB,SAAA,QAAQ;AAGR,SAAA,cAAc;AAGd,SAAA,QAAQ;AAGR,SAAA,OAA2B;AAS3B,SAAA,YAAY;AAoCZ,SAAA,iBAAiB;AAGjB,SAAA,OAaa;AAMb,SAAA,YAOgB;AAMhB,SAAA,YAAY;AAOZ,SAAA,iBAAiB;AAOjB,SAAA,kBAAkB;AAGlB,SAAA,WAAW;AAGX,SAAA,WAAW;AAYX,SAAA,WAAW;AAMX,SAAA,YAAY;AAaZ,SAAA,WAAW;AAcT,QAAI,eAAe,IAAI;AACvB;AACA,SAAK,UAAU,uBAAuB,YAAY;AAClD,SAAK,gBAAgB,6BAA6B,YAAY;AAC9D,SAAK,eAAe,4BAA4B,YAAY;AAC5D,SAAK,SAAS,KAAK,KAAK;AAAA,EAC1B;AAAA,EAlBA,WAAW,wBAAwB;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAYS,oBAA0B;AACjC,UAAM,kBAAA;AACN,SAAK,eAAe,KAAK;AAAA,EAC3B;AAAA,EAEA,IAAI,mBAAmB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,aAAa,oBAA0C;AAC/D,UAAM,aAAa,kBAAkB;AACrC,SAAK,SAAS,KAAK,KAAK;AAAA,EAC1B;AAAA,EAEA,uBAA6B;AAC3B,SAAK,WAAW,QAAA;AAAA,EAClB;AAAA,EAEQ,cAAc,OAAsB;AAC1C,UAAM,cACJ,MAAM,WAAW,MAAM,WAAW,MAAM,YAAY,MAAM;AAE5D,QAAI,MAAM,QAAQ,WAAW,CAAC,aAAa;AACzC,iBAAW,MAAM;AACf,YAAI,CAAC,MAAM,oBAAoB,CAAC,MAAM,aAAa;AACjD,eAAK,KAAK,cAAA;AAAA,QACZ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,aAAa;AACnB,SAAK,WAAW;AAChB,SAAK;AAAA,MACH,IAAI,MAAM,YAAY,EAAE,SAAS,MAAM,UAAU,MAAM;AAAA,IAAA;AAAA,EAE3D;AAAA,EAEQ,eAAe;AACrB,SAAK,QAAQ,KAAK,MAAM;AACxB,SAAK;AAAA,MACH,IAAI,MAAM,cAAc,EAAE,SAAS,MAAM,UAAU,MAAM;AAAA,IAAA;AAAA,EAE7D;AAAA,EAEQ,cAAc;AACpB,QAAI,YAAY,KAAK,MAAM;AAE3B,QAAI,KAAK,SAAS,UAAU;AAC1B,kBAAY,UAAU,QAAQ,WAAW,EAAE;AAAA,IAC7C;AAEA,SAAK,QAAQ;AACb,SAAK,SAAS,KAAK,KAAK;AACxB,SAAK;AAAA,MACH,IAAI,MAAM,aAAa,EAAE,SAAS,MAAM,UAAU,MAAM;AAAA,IAAA;AAAA,EAE5D;AAAA,EAEQ,cAAc;AACpB,SAAK,WAAW;AAChB,SAAK;AAAA,MACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,MAAM;AAAA,IAAA;AAAA,EAE5D;AAAA,EAEQ,uBAAuB;AAC7B,SAAK,kBAAkB,CAAC,KAAK;AAAA,EAC/B;AAAA,EAEQ,iBAAiB,OAAmB;AAC1C,UAAM,eAAA;AAEN,QAAI,KAAK,UAAU,IAAI;AACrB,WAAK,QAAQ;AACb,WAAK;AAAA,QACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,MAAM;AAAA,MAAA;AAE1D,WAAK;AAAA,QACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,MAAM;AAAA,MAAA;AAE1D,WAAK;AAAA,QACH,IAAI,MAAM,cAAc,EAAE,UAAU,MAAM,SAAS,MAAM;AAAA,MAAA;AAAA,IAE7D;AAEA,SAAK,MAAM,MAAA;AAAA,EACb;AAAA,EAEA,QAAQ;AACN,SAAK,WAAW;AAChB,SAAK,MAAM,MAAA;AAAA,EACb;AAAA,EAEA,mBAAmB;AACjB,SAAK,iBAAiB;AACtB,SAAK,QAAQ,KAAK;AAAA,EACpB;AAAA,EAEA,WAAW,SAAwB;AACjC,UAAM,WAAW,OAAO;AAAA,EAC1B;AAAA,EAGA,oBAAoB;AAClB,SAAK,SAAS,KAAK,KAAK;AAAA,EAC1B;AAAA,EAGA,MAAM,mBAAmB;AACvB,QAAI,CAAC,KAAK,KAAM;AAChB,UAAM,KAAK;AACX,SAAK,WAAW,QAAA;AAChB,SAAK,YAAY,IAAI,UAAU,KAAK,OAAO;AAAA,MACzC,MAAM,KAAK;AAAA,MACX,OAAO;AAAA,IAAA,CACR;AAAA,EACH;AAAA,EAES,SAAS;AAChB,UAAM,OAAO,QAAQ,IAAI;AACzB,UAAM,IAAI,gBAAgB,IAAI;AAC9B,UAAM,eAAe,KAAK,iBAAiB,KAAK,OAAO;AACvD,UAAM,WAAW,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;AACnC,UAAM,YAAY,KAAK,iBAAiB,KAAK,QAAQ;AACrD,UAAM,YAAY,KAAK,iBAAiB,KAAK,QAAQ;AACrD,UAAM,eAAe,KAAK,aAAa,CAAC,KAAK,YAAY,CAAC,KAAK;AAC/D,UAAM,aAAa,aAAa,aAAa,gBAAiB,KAAK,kBAAkB,CAAC,KAAK;AAC3F,UAAM,qBACJ,iBAAiB,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,SAAS;AACzE,UAAM,cAAc;AAAA,MAClB,KAAK,cAAc,KAAK,gBAAgB;AAAA,MACxC,KAAK,iBAAiB,KAAK,eAAe;AAAA,IAAA,EAEzC,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,WAAO;AAAA;AAAA;AAAA;AAAA,oBAIS,KAAK,IAAI;AAAA;AAAA;AAAA,iBAGZ,KAAK,OAAO;AAAA,mBACV,SAAS;AAAA,MAChB,WAAW,KAAK,aAAa,CAAC;AAAA,IAAA,CAC/B,CAAC;AAAA;AAAA,gCAEoB,KAAK,KAAK;AAAA;AAAA,UAEhC,KAAK,cACH;AAAA;AAAA,sBAEU,KAAK,aAAa;AAAA;AAAA;AAAA,yBAGf,SAAS;AAAA,MAChB,WAAW,KAAK;AAAA,IAAA,CACjB,CAAC;AAAA;AAAA,kBAEA,KAAK,WAAW;AAAA;AAAA,gBAGtB,OAAO;AAAA;AAAA;AAAA,mBAGA,aAAa,qBAAqB,EAAE;AAAA;AAAA,YAE3C,YAAY,wEAAwE,iCAAiC;AAAA;AAAA,kBAE/G,KAAK,OAAO;AAAA;AAAA;AAAA,mBAGX,IAAI;AAAA,qBACF,KAAK,KAAK,KAAK,CAAC;AAAA,wBACb,KAAK,QAAQ;AAAA,wBACb,KAAK,QAAQ;AAAA,yBACZ,KAAK,SAAS;AAAA,2BACZ,UAAU,KAAK,YAAmB,CAAC;AAAA,mBAC3C,KAAK,SAAS,cAAc,KAAK,kBACpC,SACA,KAAK,IAAI;AAAA,+BACM,UAAU,eAAe,MAAS,CAAC;AAAA,2BACvC,KAAK,iBAAiB,SAAS,OAAO;AAAA,gCACjC;AAAA,MAClB,KAAK,iBAAiB,KAAK,eAAe;AAAA,IAAA,CAC3C;AAAA,0BACa,UAAU,KAAK,WAAW,CAAC;AAAA,wBAC7B,UAAU,KAAK,SAAS,CAAC;AAAA,wBACzB,UAAU,KAAK,SAAS,CAAC;AAAA,kBAC/B,UAAU,KAAK,GAAG,CAAC;AAAA,kBACnB,UAAU,KAAK,GAAG,CAAC;AAAA,sBACf,UAAU,KAAK,OAAO,CAAC;AAAA,wBACrB,KAAK,SAAS;AAAA,qBACjB,KAAK,WAAW;AAAA,sBACf,KAAK,YAAY;AAAA,qBAClB,KAAK,WAAW;AAAA,oBACjB,KAAK,UAAU;AAAA,uBACZ,KAAK,aAAa;AAAA;AAAA,YAE7B,qBACE;AAAA;AAAA;AAAA;AAAA;AAAA,iCAKmB,EAAE,KAAK;AAAA,6BACX,KAAK,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAUpC,EAAE;AAAA,YACJ,KAAK,kBAAkB,CAAC,KAAK,WAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,iCAKmB,KAAK,kBACd,EAAE,eACF,EAAE,YAAY;AAAA,6BACT,KAAK,oBAAoB;AAAA;AAAA,sBAEhC,KAAK,kBACH;AAAA;AAAA;AAAA;AAAA,wCAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAMC;AAAA;AAAA;AAAA,kBAIX,EAAE;AAAA,YACJ,YAAY,sFAAsF,iCAAiC;AAAA;AAAA;AAAA;AAAA,gBAI/H,KAAK,YAAY;AAAA;AAAA,oBAEb,CAAC,KAAK,cAAc;AAAA;AAAA,YAE5B,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA,EAI7B;AACF;AAzaE,gBAAA;AAAA,EADC,MAAM,OAAO;AAAA,GARH,eASX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAA;AAAS,GAXC,eAYX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAA;AAAS,GAdC,eAeX,WAAA,eAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAA;AAAS,GAjBC,eAkBX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAA;AAAS,GApBC,eAqBX,WAAA,QAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,WAAW,gBAAA,CAAiB;AAAA,GAvB7B,eAwBX,WAAA,eAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GA7BhB,eA8BX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAA;AAAS,GAnCC,eAoCX,WAAA,gBAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAzCf,eA0CX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA/Cf,eAgDX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAA;AAAS,GArDC,eAsDX,WAAA,OAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAA;AAAS,GA3DC,eA4DX,WAAA,OAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAA;AAAS,GAjEC,eAkEX,WAAA,kBAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAA;AAAS,GApEC,eAqEX,WAAA,QAAA,CAAA;AAmBA,gBAAA;AAAA,EADC,SAAA;AAAS,GAvFC,eAwFX,WAAA,aAAA,CAAA;AAaA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GApGhB,eAqGX,WAAA,aAAA,CAAA;AAOA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GA3GhB,eA4GX,WAAA,kBAAA,CAAA;AAOA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GAlHhB,eAmHX,WAAA,mBAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,MAAM;AAAA,GArH/B,eAsHX,WAAA,YAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,MAAM;AAAA,GAxH/B,eAyHX,WAAA,YAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAA;AAAS,GA9HC,eA+HX,WAAA,WAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GApIhB,eAqIX,WAAA,YAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GA1IhB,eA2IX,WAAA,aAAA,CAAA;AAUA,gBAAA;AAAA,EADC,SAAA;AAAS,GApJC,eAqJX,WAAA,QAAA,CAAA;AAGA,gBAAA;AAAA,EADC,MAAA;AAAM,GAvJI,eAwJX,WAAA,YAAA,CAAA;AA8HA,gBAAA;AAAA,EADC,MAAM,OAAO;AAAA,GArRH,eAsRX,WAAA,qBAAA,CAAA;AAKM,gBAAA;AAAA,EADL,MAAM,MAAM;AAAA,GA1RF,eA2RL,WAAA,oBAAA,CAAA;AA3RK,iBAAN,gBAAA;AAAA,EADN,cAAc,eAAe;AAAA,GACjB,cAAA;"}
1
+ {"version":3,"file":"textfield.js","sources":["../../src/components/textfield.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing, type PropertyValues } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\nimport { stringConverter } from '../internal/string-converter';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HasSlotController } from '../internal/slot';\nimport { FormControlMixin } from '../mixins/form-control.mixin';\nimport {\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n requiredValidator,\n typeMismatchValidator,\n} from '../mixins/validators';\nimport { watch } from '../internal/watch';\nimport './icon/icon.component.ts';\nimport { MaskInput, type MaskType } from 'maska';\nimport { getLang } from '../utilities/lang';\nimport { getTranslations } from '../utilities/translations';\nimport { LangController } from '../controllers/lang.controller.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-textfield': MinidTextfield;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: block;\n }\n\n /* Hide increment/decrement buttons on inputs */\n input[type='number']::-webkit-outer-spin-button,\n input[type='number']::-webkit-inner-spin-button,\n input[type='number'] {\n -webkit-appearance: none;\n margin: 0;\n -moz-appearance: textfield !important;\n }\n\n .ds-field-affixes {\n background: var(--ds-color-neutral-background-tinted);\n }\n\n /* The validation message stays in the DOM so its text lands in a live region\n the screen reader is already watching - WebKit does not reliably announce\n one revealed at the same moment the text arrives. When empty it must paint\n nothing and take no room: the element drops the ds-validation-message class\n (whose ::before paints an error icon regardless of the text) and this rule\n cancels the sibling spacing from .ds-field > * + *, which the .ds-field >\n prefix is enough to outrank without !important. */\n .ds-field > .validation-message--empty {\n margin-top: 0;\n }\n `,\n];\n\nlet nextUniqueId = 0;\n\n/**\n *\n * @event mid-change - Emitted when a change to the input value is comitted by the user\n * @event mid-input - Emitted when the input element recieves input\n * @event mid-clear - Emitted when the input value is cleared\n * @event mid-focus - Emitted when input element is focused\n * @event mid-blur - Emitted when focus moves away from input element\n * @event {detail: { validity: ValidityState }} mid-invalid-hide - Emitted when the error message should be hidden\n * @event {detail: { validity: ValidityState }} mid-invalid-show - Emitted when the error message should be shown\n *\n * @slot prefix - Used for decoration to the left of the input\n * @slot suffix - Used for decoration to the right of the input\n * @slot label - The input's label. Alternatively, you can use the `label` attribute.\n *\n * @csspart base - The input's wrapper that has the input field styling.\n * @csspart input - The internal `<input>` element.\n * @csspart field - The element that wraps the label, input, and help text.\n * @csspart clear-button - The clear button\n * @csspart password-toggle-button - The button for toggling password visibility\n * @csspart validation-message - The error message shown by `invalidmessage`.\n */\n@customElement('mid-textfield')\nexport class MinidTextfield extends FormControlMixin(styled(LitElement, styles)) {\n private readonly inputId!: string;\n private readonly descriptionId!: string;\n private readonly validationId!: string;\n private readonly hasSlotControler = new HasSlotController(this, 'label', 'prefix', 'suffix');\n private inputMask?: MaskInput;\n private initialValue = '';\n\n @query('input')\n input!: HTMLInputElement;\n\n @property()\n label = '';\n\n @property()\n description = '';\n\n @property()\n value = '';\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ converter: stringConverter })\n placeholder?: string;\n\n /**\n * Autofocus the input field on page load\n */\n @property({ type: Boolean })\n autofocus = false;\n\n /**\n * User agent autocomplete hint\n */\n @property()\n autocomplete?: AutoFill;\n\n /**\n * The minimum length of input that will be considered valid.\n */\n @property({ type: Number })\n minlength?: number;\n\n /**\n * The maximum length of input that will be considered valid.\n */\n @property({ type: Number })\n maxlength?: number;\n\n /**\n * The input's minimum value. Only applies to date and number input types.\n */\n @property()\n min?: number | string;\n\n /**\n * The input's maximum value. Only applies to date and number input types.\n */\n @property()\n max?: number | string;\n\n /**\n * Error message to display when the input is invalid, also activates invalid styling\n */\n @property()\n invalidmessage = '';\n\n @property()\n type:\n | 'date'\n | 'datetime-local'\n | 'email'\n | 'file'\n | 'month'\n | 'number'\n | 'password'\n | 'search'\n | 'tel'\n | 'text'\n | 'time'\n | 'url'\n | 'week' = 'text';\n\n /**\n * For displaying appropriate virtual keyboard\n */\n @property()\n inputmode:\n | 'none'\n | 'text'\n | 'tel'\n | 'url'\n | 'email'\n | 'numeric'\n | 'decimal' = 'text';\n\n /**\n * Adds a clear button when the input is not empty.\n */\n @property({ type: Boolean })\n clearable = false;\n\n /**\n * Adds a button to toggle the password's visibility.\n * Only applies if type is password\n */\n @property({ type: Boolean })\n passwordtoggle = false;\n\n /**\n * Determines wether the password is currently visible.\n * Only applies if type is password\n */\n @property({ type: Boolean })\n passwordvisible = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /**\n * A regular expression pattern to validate input against.\n */\n @property()\n pattern?: string;\n\n /**\n * Makes the input required\n */\n @property({ type: Boolean })\n required = false;\n\n /**\n * Visually hides `label` and `description` (still available for screen readers)\n */\n @property({ type: Boolean })\n hidelabel = false;\n\n /**\n * Modify input value based on mask e.g: `\"##:##\"` = 12:34.\n * `#`: /[0-9]/\n * `@`: /[a-zA-Z]/\n * `*`: /[a-zA-Z0-9]/\n * For more information go to https://beholdr.github.io/maska\n */\n @property()\n mask?: MaskType;\n\n @state()\n hasFocus = false;\n\n static get formControlValidators() {\n return [\n requiredValidator,\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n typeMismatchValidator,\n ];\n }\n\n constructor() {\n super();\n new LangController(this);\n nextUniqueId++;\n this.inputId = `mid-textfield-input-${nextUniqueId}`;\n this.descriptionId = `mid-textfield-description-${nextUniqueId}`;\n this.validationId = `mid-textfield-validation-${nextUniqueId}`;\n this.setValue(this.value);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.initialValue = this.value;\n }\n\n get validationTarget() {\n return this.input;\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n super.firstUpdated(_changedProperties);\n this.setValue(this.value);\n }\n\n disconnectedCallback(): void {\n this.inputMask?.destroy();\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n if (event.key === 'Enter' && !hasModifier) {\n setTimeout(() => {\n if (!event.defaultPrevented && !event.isComposing) {\n this.form.requestSubmit();\n }\n });\n }\n }\n\n private handleBlur() {\n this.hasFocus = false;\n this.dispatchEvent(\n new Event('mid-blur', { bubbles: true, composed: true })\n );\n }\n\n private handleChange() {\n this.value = this.input.value;\n this.dispatchEvent(\n new Event('mid-change', { bubbles: true, composed: true })\n );\n }\n\n private handleInput() {\n let tmp_value = this.input.value;\n\n if (this.type === 'number') {\n tmp_value = tmp_value.replace(/[^0-9]/g, '');\n }\n\n this.value = tmp_value;\n this.setValue(this.value);\n this.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n }\n\n private handleFocus() {\n this.hasFocus = true;\n this.dispatchEvent(\n new Event('mid-focus', { composed: true, bubbles: true })\n );\n }\n\n private handlePasswordToggle() {\n this.passwordvisible = !this.passwordvisible;\n }\n\n private handleClearClick(event: MouseEvent) {\n event.preventDefault();\n\n if (this.value !== '') {\n this.value = '';\n this.dispatchEvent(\n new Event('mid-clear', { composed: true, bubbles: true })\n );\n this.dispatchEvent(\n new Event('mid-input', { composed: true, bubbles: true })\n );\n this.dispatchEvent(\n new Event('mid-change', { composed: true, bubbles: true })\n );\n }\n\n this.input.focus();\n }\n\n focus() {\n this.hasFocus = true;\n this.input.focus();\n }\n\n resetFormControl() {\n this.invalidmessage = '';\n this.value = this.initialValue;\n }\n\n forceError(message?: string): void {\n super.forceError(message);\n }\n\n @watch('value')\n handleValueUpdate() {\n this.setValue(this.value);\n }\n\n @watch('mask')\n async handleMaskUpdate() {\n if (!this.mask) return;\n await this.updateComplete;\n this.inputMask?.destroy();\n this.inputMask = new MaskInput(this.input, {\n mask: this.mask,\n eager: true,\n });\n }\n\n override render() {\n const lang = getLang(this);\n const t = getTranslations(lang);\n const hasLabelSlot = this.hasSlotControler.test('label');\n const hasLabel = !!this.label || !!hasLabelSlot;\n const hasPrefix = this.hasSlotControler.test('prefix');\n const hasSuffix = this.hasSlotControler.test('suffix');\n const hasClearIcon = this.clearable && !this.disabled && !this.readonly;\n const hasAffixes = hasPrefix || hasSuffix || hasClearIcon || (this.passwordtoggle && !this.disabled);\n const isClearIconVisible =\n hasClearIcon && (typeof this.value === 'number' || this.value.length > 0);\n const describedBy = [\n this.description ? this.descriptionId : undefined,\n this.invalidmessage ? this.validationId : undefined,\n ]\n .filter(Boolean)\n .join(' ');\n\n return html`\n <ds-field\n part=\"field\"\n class=\"ds-field\"\n data-size=${this.size}\n >\n <label\n for=\"${this.inputId}\"\n class=\"${classMap({\n 'sr-only': this.hidelabel || !hasLabel,\n })} ds-label\"\n >\n <slot name=\"label\"> ${this.label} </slot>\n </label>\n ${this.description\n ? html`\n <div\n id=\"${this.descriptionId}\"\n part=\"description\"\n aria-hidden=\"true\"\n class=\"${classMap({\n 'sr-only': this.hidelabel,\n })}\"\n >\n ${this.description}\n </div>\n `\n : nothing}\n <div\n part=\"base\"\n class=\"${hasAffixes ? 'ds-field-affixes' : ''}\"\n >\n ${hasPrefix ? html`<span class=\"ds-field-affix\"><slot name=\"prefix\"></slot></span>` : html`<slot name=\"prefix\"></slot>`}\n <input\n id=\"${this.inputId}\"\n class=\"ds-input\"\n part=\"input\"\n lang=${lang}\n .value=${live(this.value)}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n ?autofocus=${this.autofocus}\n autocomplete=${ifDefined(this.autocomplete as any)}\n type=${this.type === 'password' && this.passwordvisible\n ? 'text'\n : this.type}\n aria-describedby=${ifDefined(describedBy || undefined)}\n aria-invalid=${this.invalidmessage ? 'true' : 'false'}\n aria-errormessage=${ifDefined(\n this.invalidmessage ? this.validationId : undefined\n )}\n placeholder=${ifDefined(this.placeholder)}\n minlength=${ifDefined(this.minlength)}\n maxlength=${ifDefined(this.maxlength)}\n min=${ifDefined(this.min)}\n max=${ifDefined(this.max)}\n pattern=${ifDefined(this.pattern)}\n inputmode=${this.inputmode}\n @input=${this.handleInput}\n @change=${this.handleChange}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n @keydown=${this.handleKeydown}\n />\n ${isClearIconVisible\n ? html`\n <span class=\"ds-field-affix\" part=\"clear-button\">\n <button\n type=\"button\"\n class=\"focus-visible:focus-ring flex items-center justify-center rounded-sm\"\n aria-label=${t.clear}\n @click=${this.handleClearClick}\n >\n <mid-icon\n class=\"size-7\"\n library=\"nav-aksel\"\n name=\"trash\"\n ></mid-icon>\n </button>\n </span>\n `\n : ''}\n ${this.passwordtoggle && !this.disabled\n ? html`\n <span class=\"ds-field-affix\" part=\"password-toggle-button\">\n <button\n type=\"button\"\n class=\"focus-visible:focus-ring flex items-center justify-center rounded-sm\"\n aria-label=${this.passwordvisible\n ? t.hidePassword\n : t.showPassword}\n @click=${this.handlePasswordToggle}\n >\n ${this.passwordvisible\n ? html` <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"eye-slash\"\n ></mid-icon>`\n : html`\n <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"eye\"\n ></mid-icon>\n `}\n </button>\n </span>\n `\n : ''}\n ${hasSuffix ? html`<span part=\"suffix\" class=\"ds-field-affix\"><slot name=\"suffix\"></slot></span>` : html`<slot name=\"suffix\"></slot>`}\n </div>\n <p\n class=\"${classMap({\n 'ds-validation-message': !!this.invalidmessage,\n 'validation-message--empty': !this.invalidmessage,\n })}\"\n part=\"validation-message\"\n id=\"${this.validationId}\"\n aria-live=\"polite\"\n >\n ${this.invalidmessage}\n </p>\n </ds-field>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@felleslosninger/minid-elements",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "MinID Web Components",
5
5
  "author": "Digitaliseringsdirektoratet",
6
6
  "license": "MIT",