fds-vue-core 8.2.2 → 8.2.4

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.
@@ -52,9 +52,9 @@ declare const _default: import('vue').DefineComponent<FdsSearchSelectProps, {
52
52
  } & import('../..').FdsInputProps> & Readonly<{
53
53
  onInput?: ((ev: Event) => any) | undefined;
54
54
  onBlur?: ((ev: FocusEvent) => any) | undefined;
55
- onChange?: ((ev: Event) => any) | undefined;
56
55
  onKeyup?: ((ev: KeyboardEvent) => any) | undefined;
57
56
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
57
+ onAutocomplete?: ((ev: Event) => any) | undefined;
58
58
  onClearInput?: (() => any) | undefined;
59
59
  "onUpdate:value"?: ((value: string) => any) | undefined;
60
60
  "onKeyup.enter"?: ((ev: KeyboardEvent) => any) | undefined;
@@ -63,8 +63,8 @@ declare const _default: import('vue').DefineComponent<FdsSearchSelectProps, {
63
63
  } & {
64
64
  input: (ev: Event) => any;
65
65
  blur: (ev: FocusEvent) => any;
66
- change: (ev: Event) => any;
67
66
  keyup: (ev: KeyboardEvent) => any;
67
+ autocomplete: (ev: Event) => any;
68
68
  clearInput: () => any;
69
69
  "update:value": (value: string) => any;
70
70
  "keyup.enter": (ev: KeyboardEvent) => any;
@@ -106,9 +106,9 @@ declare const _default: import('vue').DefineComponent<FdsSearchSelectProps, {
106
106
  } & import('../..').FdsInputProps> & Readonly<{
107
107
  onInput?: ((ev: Event) => any) | undefined;
108
108
  onBlur?: ((ev: FocusEvent) => any) | undefined;
109
- onChange?: ((ev: Event) => any) | undefined;
110
109
  onKeyup?: ((ev: KeyboardEvent) => any) | undefined;
111
110
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
111
+ onAutocomplete?: ((ev: Event) => any) | undefined;
112
112
  onClearInput?: (() => any) | undefined;
113
113
  "onUpdate:value"?: ((value: string) => any) | undefined;
114
114
  "onKeyup.enter"?: ((ev: KeyboardEvent) => any) | undefined;
@@ -73,9 +73,9 @@ declare const _default: import('vue').DefineComponent<FdsSearchSelectProProps, {
73
73
  } & import('../..').FdsInputProps> & Readonly<{
74
74
  onInput?: ((ev: Event) => any) | undefined;
75
75
  onBlur?: ((ev: FocusEvent) => any) | undefined;
76
- onChange?: ((ev: Event) => any) | undefined;
77
76
  onKeyup?: ((ev: KeyboardEvent) => any) | undefined;
78
77
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
78
+ onAutocomplete?: ((ev: Event) => any) | undefined;
79
79
  onClearInput?: (() => any) | undefined;
80
80
  "onUpdate:value"?: ((value: string) => any) | undefined;
81
81
  "onKeyup.enter"?: ((ev: KeyboardEvent) => any) | undefined;
@@ -84,8 +84,8 @@ declare const _default: import('vue').DefineComponent<FdsSearchSelectProProps, {
84
84
  } & {
85
85
  input: (ev: Event) => any;
86
86
  blur: (ev: FocusEvent) => any;
87
- change: (ev: Event) => any;
88
87
  keyup: (ev: KeyboardEvent) => any;
88
+ autocomplete: (ev: Event) => any;
89
89
  clearInput: () => any;
90
90
  "update:value": (value: string) => any;
91
91
  "keyup.enter": (ev: KeyboardEvent) => any;
@@ -127,9 +127,9 @@ declare const _default: import('vue').DefineComponent<FdsSearchSelectProProps, {
127
127
  } & import('../..').FdsInputProps> & Readonly<{
128
128
  onInput?: ((ev: Event) => any) | undefined;
129
129
  onBlur?: ((ev: FocusEvent) => any) | undefined;
130
- onChange?: ((ev: Event) => any) | undefined;
131
130
  onKeyup?: ((ev: KeyboardEvent) => any) | undefined;
132
131
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
132
+ onAutocomplete?: ((ev: Event) => any) | undefined;
133
133
  onClearInput?: (() => any) | undefined;
134
134
  "onUpdate:value"?: ((value: string) => any) | undefined;
135
135
  "onKeyup.enter"?: ((ev: KeyboardEvent) => any) | undefined;
@@ -8,17 +8,17 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
8
8
  } & {
9
9
  input: (ev: Event) => any;
10
10
  blur: (ev: FocusEvent) => any;
11
- change: (ev: Event) => any;
12
11
  keyup: (ev: KeyboardEvent) => any;
12
+ autocomplete: (ev: Event) => any;
13
13
  clearInput: () => any;
14
14
  "update:value": (value: string) => any;
15
15
  "keyup.enter": (ev: KeyboardEvent) => any;
16
16
  }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
17
17
  onInput?: ((ev: Event) => any) | undefined;
18
18
  onBlur?: ((ev: FocusEvent) => any) | undefined;
19
- onChange?: ((ev: Event) => any) | undefined;
20
19
  onKeyup?: ((ev: KeyboardEvent) => any) | undefined;
21
20
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
21
+ onAutocomplete?: ((ev: Event) => any) | undefined;
22
22
  onClearInput?: (() => any) | undefined;
23
23
  "onUpdate:value"?: ((value: string) => any) | undefined;
24
24
  "onKeyup.enter"?: ((ev: KeyboardEvent) => any) | undefined;
@@ -24,18 +24,15 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
24
24
  id: string;
25
25
  name: string;
26
26
  placeholder: string;
27
- maxlength: number;
28
27
  dataTestid: string;
29
28
  label: string;
30
29
  meta: string;
31
- pattern: string;
32
30
  autofocus: boolean;
33
31
  locale: string;
34
32
  inputClass: string;
35
33
  valid: boolean | null;
36
34
  optional: boolean;
37
35
  invalidMessage: string;
38
- minlength: number;
39
36
  autocomplete: string;
40
37
  readonly: boolean;
41
38
  defaultCountry: string;
@@ -0,0 +1,7 @@
1
+ /** Whether the value likely contains a country calling code or international formatting. */
2
+ export declare const shouldNormalizePhoneInput: (value: string, countryIso2: string) => boolean;
3
+ /**
4
+ * Converts international/autocomplete values to national digits for the IMask field.
5
+ * IMask reapplies spacing from the country mask.
6
+ */
7
+ export declare const normalizeNationalPhoneInput: (value: string, countryIso2: string) => string;
@@ -0,0 +1,2 @@
1
+ /** IMask pattern with space grouping derived from libphonenumber mobile example numbers. */
2
+ export declare const getPhoneMaskForCountry: (countryIso2: string) => string | undefined;
@@ -1,6 +1,6 @@
1
1
  import { FdsInputProps } from '../FdsInput/types';
2
2
  import { CountryPhoneOption } from './countries';
3
- type FdsPhonenumberInputPassthroughProps = Pick<FdsInputProps, 'id' | 'autocomplete' | 'required' | 'placeholder' | 'maxlength' | 'minlength' | 'name' | 'autofocus' | 'readonly' | 'pattern'>;
3
+ type FdsPhonenumberInputPassthroughProps = Pick<FdsInputProps, 'id' | 'autocomplete' | 'required' | 'placeholder' | 'name' | 'autofocus' | 'readonly'>;
4
4
  export interface FdsPhonenumberProps extends FdsPhonenumberInputPassthroughProps {
5
5
  label?: string;
6
6
  meta?: string;
@@ -9878,11 +9878,12 @@ const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
9878
9878
  });
9879
9879
  const _hoisted_1$j = ["for", "id"];
9880
9880
  const _hoisted_2$f = { class: "relative" };
9881
- const _hoisted_3$f = ["type", "required", "value", "disabled", "tabindex", "aria-invalid", "aria-label", "aria-labelledby", "aria-describedby", "autocomplete", "placeholder", "pattern", "searchIcon"];
9881
+ const _hoisted_3$f = ["type", "required", "disabled", "tabindex", "aria-invalid", "aria-label", "aria-labelledby", "aria-describedby", "autocomplete", "placeholder", "pattern", "searchIcon"];
9882
9882
  const _hoisted_4$e = {
9883
9883
  key: 0,
9884
9884
  class: "text-red-700 font-bold mt-1"
9885
9885
  };
9886
+ const inputPaddingClasses = "px-3 py-[calc(0.75rem-1px)]";
9886
9887
  const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
9887
9888
  ...{
9888
9889
  inheritAttrs: false
@@ -9933,14 +9934,17 @@ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
9933
9934
  "modelValue": { default: void 0, required: false },
9934
9935
  "modelModifiers": {}
9935
9936
  }),
9936
- emits: /* @__PURE__ */ vue.mergeModels(["input", "change", "clearInput", "update:value", "keyup", "keyup.enter", "blur"], ["update:modelValue"]),
9937
+ emits: /* @__PURE__ */ vue.mergeModels(["input", "autocomplete", "clearInput", "update:value", "keyup", "keyup.enter", "blur"], ["update:modelValue"]),
9937
9938
  setup(__props, { emit: __emit }) {
9938
9939
  const modelValue = vue.useModel(__props, "modelValue");
9939
9940
  const props = __props;
9940
9941
  const emit = __emit;
9941
9942
  const { id, type, maxlength, attrs } = useAttrsWithDefaults(props);
9942
9943
  const { t } = useFdsI18n();
9943
- const inputType = vue.computed(() => type.value ?? props.type ?? "text");
9944
+ const inputType = vue.computed(() => {
9945
+ if (props.mask) return "text";
9946
+ return type.value ?? props.type ?? "text";
9947
+ });
9944
9948
  const autoId = `fds-input-${Math.random().toString(36).slice(2, 9)}`;
9945
9949
  const inputId = vue.computed(() => id.value ?? autoId);
9946
9950
  const labelId = vue.computed(() => `${inputId.value}-label`);
@@ -10012,28 +10016,31 @@ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
10012
10016
  });
10013
10017
  const externalClass = vue.computed(() => props.class ?? attrs.class);
10014
10018
  const inputClasses = vue.computed(() => [
10015
- "block rounded-md border border-gray-500 px-3 py-[calc(0.75rem-1px)]",
10019
+ "block rounded-md border border-gray-500",
10016
10020
  maxlength.value ? "" : "w-full",
10021
+ inputPaddingClasses,
10017
10022
  inputPaddingRight.value,
10018
10023
  "focus:outline-2 focus:outline-blue-500 -outline-offset-2 focus:border-transparent",
10019
10024
  showDateIcon.value && "[&::-webkit-calendar-picker-indicator]:opacity-0 [&::-webkit-calendar-picker-indicator]:pointer-events-none",
10020
- props.disabled ? "text-gray-800 outline-dashed outline-2 outline-gray-400 cursor-not-allowed border-transparent" : "bg-white",
10025
+ props.disabled ? "text-gray-800 outline-dashed outline-2 outline-gray-400 cursor-not-allowed border-transparent" : "text-gray-900 bg-white",
10021
10026
  isInvalid.value && "outline-2 outline-red-600",
10022
10027
  props.inputClass
10023
10028
  ]);
10024
10029
  const inputStyle = vue.computed(() => {
10025
- if (maxlength.value) {
10026
- return {
10027
- width: `calc(${maxlength.value}ch + 1.5rem + 0.25rem)`,
10028
- maxWidth: "100%"
10029
- };
10030
- }
10031
- return {};
10030
+ if (!maxlength.value) return void 0;
10031
+ return {
10032
+ width: `calc(${maxlength.value}ch + 1.5rem + 0.25rem)`,
10033
+ maxWidth: "100%"
10034
+ };
10032
10035
  });
10033
10036
  const rightIconsContainerClasses = vue.computed(() => [
10034
10037
  "absolute flex gap-2 top-1/2 -translate-y-1/2 items-center justify-end",
10035
10038
  showClearButton.value ? "right-2" : "right-3"
10036
10039
  ]);
10040
+ const inputBindings = vue.computed(() => ({
10041
+ ...inputAttrs.value,
10042
+ ...props.mask ? {} : { value: internalValue.value }
10043
+ }));
10037
10044
  const internalValue = vue.computed({
10038
10045
  get: () => modelValue.value !== void 0 ? modelValue.value : props.value ?? "",
10039
10046
  set: (newValue) => {
@@ -10045,6 +10052,9 @@ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
10045
10052
  });
10046
10053
  function onClear() {
10047
10054
  internalValue.value = "";
10055
+ if (maskInstance) {
10056
+ maskInstance.value = "";
10057
+ }
10048
10058
  emit("clearInput");
10049
10059
  }
10050
10060
  function onDateIconClick() {
@@ -10079,11 +10089,11 @@ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
10079
10089
  maskInstance = null;
10080
10090
  }
10081
10091
  if (props.mask && inputRef.value) {
10082
- const maskConfig = {
10092
+ maskInstance = IMask(inputRef.value, {
10083
10093
  mask: props.mask,
10084
- ...props.maskOptions
10085
- };
10086
- maskInstance = IMask(inputRef.value, maskConfig);
10094
+ ...props.maskOptions,
10095
+ lazy: props.maskOptions?.lazy ?? true
10096
+ });
10087
10097
  if (internalValue.value) {
10088
10098
  maskInstance.value = internalValue.value;
10089
10099
  }
@@ -10120,18 +10130,30 @@ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
10120
10130
  return props.meta ? metaId.value : void 0;
10121
10131
  });
10122
10132
  vue.watch(
10123
- () => props.mask,
10133
+ () => [props.mask, props.maskOptions],
10124
10134
  () => {
10125
10135
  vue.nextTick(() => {
10126
10136
  createMask2();
10127
10137
  });
10128
- }
10138
+ },
10139
+ { deep: true }
10129
10140
  );
10141
+ function shouldSyncMaskFromModel(newValue, currentMaskedValue) {
10142
+ if (newValue === void 0) {
10143
+ return false;
10144
+ }
10145
+ if (document.activeElement !== inputRef.value) {
10146
+ return true;
10147
+ }
10148
+ const newDigits = String(newValue).replace(/\D/g, "");
10149
+ const currentDigits = String(currentMaskedValue ?? "").replace(/\D/g, "");
10150
+ return newDigits !== currentDigits;
10151
+ }
10130
10152
  vue.watch(
10131
10153
  () => props.value,
10132
10154
  (newValue) => {
10133
10155
  if (maskInstance && newValue !== void 0 && newValue !== maskInstance.value) {
10134
- if (document.activeElement !== inputRef.value) {
10156
+ if (shouldSyncMaskFromModel(newValue, maskInstance.value)) {
10135
10157
  maskInstance.value = newValue;
10136
10158
  }
10137
10159
  }
@@ -10141,7 +10163,7 @@ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
10141
10163
  () => modelValue.value,
10142
10164
  (newValue) => {
10143
10165
  if (maskInstance && newValue !== void 0 && newValue !== maskInstance.value) {
10144
- if (document.activeElement !== inputRef.value) {
10166
+ if (shouldSyncMaskFromModel(newValue, maskInstance.value)) {
10145
10167
  maskInstance.value = newValue;
10146
10168
  }
10147
10169
  }
@@ -10183,7 +10205,6 @@ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
10183
10205
  ref: inputRef,
10184
10206
  type: inputType.value === "password" ? showPassword.value ? "text" : "password" : inputType.value,
10185
10207
  required: props.required,
10186
- value: internalValue.value,
10187
10208
  disabled: props.disabled,
10188
10209
  tabindex: props.disabled ? -1 : void 0,
10189
10210
  "aria-invalid": props.valid === false ? "true" : void 0,
@@ -10196,11 +10217,12 @@ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
10196
10217
  placeholder: props.placeholder,
10197
10218
  pattern: props.pattern,
10198
10219
  searchIcon: props.searchIcon
10199
- }, inputAttrs.value, {
10220
+ }, inputBindings.value, {
10200
10221
  onInput: handleInputChange,
10201
10222
  onChange: handleInputChange,
10202
- onBlur: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("blur", $event)),
10203
- onKeyup: _cache[1] || (_cache[1] = (ev) => {
10223
+ onAutocomplete: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("autocomplete", $event)),
10224
+ onBlur: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("blur", $event)),
10225
+ onKeyup: _cache[2] || (_cache[2] = (ev) => {
10204
10226
  _ctx.$emit("keyup", ev);
10205
10227
  if (ev.key === "Enter") _ctx.$emit("keyup.enter", ev);
10206
10228
  })
@@ -18493,6 +18515,11 @@ function parsePhoneNumber$1() {
18493
18515
  function getCountries$1(metadata2) {
18494
18516
  return new Metadata(metadata2).getCountries();
18495
18517
  }
18518
+ function getExampleNumber$1(country, examples2, metadata2) {
18519
+ if (examples2[country]) {
18520
+ return new PhoneNumber$1(country, examples2[country], metadata2);
18521
+ }
18522
+ }
18496
18523
  class PhoneNumber2 extends PhoneNumber$1 {
18497
18524
  constructor(number) {
18498
18525
  super(number, metadata);
@@ -18507,6 +18534,9 @@ function getCountries() {
18507
18534
  function getCountryCallingCode() {
18508
18535
  return withMetadataArgument(getCountryCallingCode$1, arguments);
18509
18536
  }
18537
+ function getExampleNumber() {
18538
+ return withMetadataArgument(getExampleNumber$1, arguments);
18539
+ }
18510
18540
  function resolveDisplayLocale(locale) {
18511
18541
  const trimmed = locale.trim();
18512
18542
  if (!trimmed) {
@@ -18580,6 +18610,90 @@ function filterCountryOptions(options, query) {
18580
18610
  return option.label.toLowerCase().includes(normalizedQuery) || option.countryName.toLowerCase().includes(normalizedQuery) || option.value.toLowerCase().includes(normalizedQuery) || dialCode.includes(normalizedQuery) || `+${dialCode}`.includes(normalizedQuery);
18581
18611
  });
18582
18612
  }
18613
+ const examples = { "AC": "40123", "AD": "312345", "AE": "501234567", "AF": "701234567", "AG": "2684641234", "AI": "2642351234", "AL": "672123456", "AM": "77123456", "AO": "923123456", "AR": "91123456789", "AS": "6847331234", "AT": "664123456", "AU": "412345678", "AW": "5601234", "AX": "412345678", "AZ": "401234567", "BA": "61123456", "BB": "2462501234", "BD": "1812345678", "BE": "450001234", "BF": "70123456", "BG": "43012345", "BH": "36001234", "BI": "79561234", "BJ": "0195123456", "BL": "690001234", "BM": "4413701234", "BN": "7123456", "BO": "71234567", "BQ": "3181234", "BR": "11961234567", "BS": "2423591234", "BT": "17123456", "BW": "71123456", "BY": "294911911", "BZ": "6221234", "CA": "5062345678", "CC": "412345678", "CD": "991234567", "CF": "70012345", "CG": "061234567", "CH": "781234567", "CI": "0123456789", "CK": "71234", "CL": "221234567", "CM": "671234567", "CN": "13123456789", "CO": "3211234567", "CR": "83123456", "CU": "51234567", "CV": "9911234", "CW": "95181234", "CX": "412345678", "CY": "96123456", "CZ": "601123456", "DE": "15123456789", "DJ": "77831001", "DK": "34412345", "DM": "7672251234", "DO": "8092345678", "DZ": "551234567", "EC": "991234567", "EE": "51234567", "EG": "1001234567", "EH": "650123456", "ER": "7123456", "ES": "612345678", "ET": "911234567", "FI": "412345678", "FJ": "7012345", "FK": "51234", "FM": "3501234", "FO": "211234", "FR": "612345678", "GA": "06031234", "GB": "7400123456", "GD": "4734031234", "GE": "555123456", "GF": "694201234", "GG": "7781123456", "GH": "231234567", "GI": "57123456", "GL": "221234", "GM": "3012345", "GN": "601123456", "GP": "690001234", "GQ": "222123456", "GR": "6912345678", "GT": "51234567", "GU": "6713001234", "GW": "955012345", "GY": "6091234", "HK": "51234567", "HN": "91234567", "HR": "921234567", "HT": "34101234", "HU": "201234567", "ID": "812345678", "IE": "850123456", "IL": "502345678", "IM": "7924123456", "IN": "8123456789", "IO": "3801234", "IQ": "7912345678", "IR": "9123456789", "IS": "6111234", "IT": "3123456789", "JE": "7797712345", "JM": "8762101234", "JO": "790123456", "JP": "9012345678", "KE": "712123456", "KG": "700123456", "KH": "91234567", "KI": "72001234", "KM": "3212345", "KN": "8697652917", "KP": "1921234567", "KR": "1020000000", "KW": "50012345", "KY": "3453231234", "KZ": "7710009998", "LA": "2023123456", "LB": "71123456", "LC": "7582845678", "LI": "660234567", "LK": "712345678", "LR": "770123456", "LS": "50123456", "LT": "61234567", "LU": "628123456", "LV": "21234567", "LY": "912345678", "MA": "650123456", "MC": "612345678", "MD": "62112345", "ME": "60123456", "MF": "690001234", "MG": "321234567", "MH": "2351234", "MK": "72345678", "ML": "65012345", "MM": "92123456", "MN": "88123456", "MO": "66123456", "MP": "6702345678", "MQ": "696201234", "MR": "22123456", "MS": "6644923456", "MT": "96961234", "MU": "52512345", "MV": "7712345", "MW": "991234567", "MX": "2221234567", "MY": "123456789", "MZ": "821234567", "NA": "811234567", "NC": "751234", "NE": "93123456", "NF": "381234", "NG": "8021234567", "NI": "81234567", "NL": "612345678", "NO": "40612345", "NP": "9841234567", "NR": "5551234", "NU": "8884012", "NZ": "211234567", "OM": "92123456", "PA": "61234567", "PE": "912345678", "PF": "87123456", "PG": "70123456", "PH": "9051234567", "PK": "3012345678", "PL": "512345678", "PM": "551234", "PR": "7872345678", "PS": "599123456", "PT": "912345678", "PW": "6201234", "PY": "961456789", "QA": "33123456", "RE": "692123456", "RO": "712034567", "RS": "601234567", "RU": "9123456789", "RW": "720123456", "SA": "512345678", "SB": "7421234", "SC": "2510123", "SD": "911231234", "SE": "701234567", "SG": "81234567", "SH": "51234", "SI": "31234567", "SJ": "41234567", "SK": "912123456", "SL": "25123456", "SM": "66661212", "SN": "701234567", "SO": "71123456", "SR": "7412345", "SS": "977123456", "ST": "9812345", "SV": "70123456", "SX": "7215205678", "SY": "944567890", "SZ": "76123456", "TA": "8999", "TC": "6492311234", "TD": "63012345", "TG": "90112345", "TH": "812345678", "TJ": "917123456", "TK": "7290", "TL": "77212345", "TM": "66123456", "TN": "20123456", "TO": "7715123", "TR": "5012345678", "TT": "8682911234", "TV": "901234", "TW": "912345678", "TZ": "621234567", "UA": "501234567", "UG": "712345678", "US": "2015550123", "UY": "94231234", "UZ": "912345678", "VA": "3123456789", "VC": "7844301234", "VE": "4121234567", "VG": "2843001234", "VI": "3406421234", "VN": "912345678", "VU": "5912345", "WF": "821234", "WS": "7212345", "XK": "43201234", "YE": "712345678", "YT": "639012345", "ZA": "711234567", "ZM": "955123456", "ZW": "712345678" };
18614
+ const maskCache = /* @__PURE__ */ new Map();
18615
+ const getPhoneMaskForCountry = (countryIso2) => {
18616
+ const country = countryIso2.trim().toUpperCase();
18617
+ const cached = maskCache.get(country);
18618
+ if (cached) {
18619
+ return cached;
18620
+ }
18621
+ const example = getExampleNumber(country, examples);
18622
+ if (!example) {
18623
+ return void 0;
18624
+ }
18625
+ const groups = example.formatNational().split(/\D+/).filter(Boolean).map((part) => part.length);
18626
+ const mask = groups.map((size) => "0".repeat(size)).join(" ");
18627
+ maskCache.set(country, mask);
18628
+ return mask;
18629
+ };
18630
+ const nationalDigitsForMask = (parsed) => parsed.formatNational().replace(/\D/g, "");
18631
+ const tryParseForCountry = (candidate, country) => {
18632
+ const parsed = parsePhoneNumber(candidate, country) ?? parsePhoneNumber(candidate);
18633
+ if (!parsed?.isValid() || parsed.country !== country) {
18634
+ return void 0;
18635
+ }
18636
+ return parsed;
18637
+ };
18638
+ const shouldNormalizePhoneInput = (value, countryIso2) => {
18639
+ const trimmed = value.trim();
18640
+ if (!trimmed) {
18641
+ return false;
18642
+ }
18643
+ if (trimmed.includes("+") || trimmed.startsWith("00")) {
18644
+ return true;
18645
+ }
18646
+ const digits = trimmed.replace(/\D/g, "");
18647
+ const mask = getPhoneMaskForCountry(countryIso2);
18648
+ if (!mask) {
18649
+ return false;
18650
+ }
18651
+ const maxDigits = (mask.match(/0/g) ?? []).length;
18652
+ if (digits.length > maxDigits) {
18653
+ return true;
18654
+ }
18655
+ try {
18656
+ const callingCode = getCountryCallingCode(countryIso2);
18657
+ if (digits.startsWith(callingCode) && digits.length > maxDigits - 1) {
18658
+ return true;
18659
+ }
18660
+ } catch {
18661
+ return false;
18662
+ }
18663
+ return false;
18664
+ };
18665
+ const normalizeNationalPhoneInput = (value, countryIso2) => {
18666
+ const trimmed = value.trim();
18667
+ if (!trimmed) {
18668
+ return "";
18669
+ }
18670
+ const country = countryIso2.trim().toUpperCase();
18671
+ const digits = trimmed.replace(/\D/g, "");
18672
+ const candidates = /* @__PURE__ */ new Set([trimmed]);
18673
+ if (digits) {
18674
+ candidates.add(digits);
18675
+ candidates.add(`+${digits}`);
18676
+ }
18677
+ for (const candidate of candidates) {
18678
+ const parsed = tryParseForCountry(candidate, country);
18679
+ if (parsed) {
18680
+ return nationalDigitsForMask(parsed);
18681
+ }
18682
+ }
18683
+ try {
18684
+ const callingCode = getCountryCallingCode(country);
18685
+ if (digits.startsWith(callingCode) && digits.length > callingCode.length) {
18686
+ const withoutCode = digits.slice(callingCode.length);
18687
+ const parsed = tryParseForCountry(withoutCode, country) ?? tryParseForCountry(`0${withoutCode}`, country);
18688
+ if (parsed) {
18689
+ return nationalDigitsForMask(parsed);
18690
+ }
18691
+ }
18692
+ } catch {
18693
+ return trimmed;
18694
+ }
18695
+ return trimmed;
18696
+ };
18583
18697
  const _hoisted_1$5 = { class: "relative w-full" };
18584
18698
  const _hoisted_2$4 = { class: "absolute left-3 top-1/2 -translate-y-1/2 text-xl leading-none" };
18585
18699
  const _hoisted_3$4 = ["aria-expanded", "aria-label", "aria-controls", "aria-activedescendant", "value", "disabled"];
@@ -18916,7 +19030,7 @@ const _sfc_main$a = /* @__PURE__ */ vue.defineComponent({
18916
19030
  key: 0,
18917
19031
  role: "listbox",
18918
19032
  id: listboxId,
18919
- class: "absolute left-0 z-20 mt-1 min-w-[20rem] w-max max-w-[calc(100vw-2rem)] max-h-[280px] overflow-y-auto rounded-md border border-gray-300 bg-white"
19033
+ class: "absolute left-0 z-20 mt-2 min-w-[20rem] w-max max-w-[calc(100vw-2rem)] max-h-[280px] overflow-y-auto rounded-md border border-gray-300 bg-white"
18920
19034
  }, listDataAttrs.value, { onMouseleave: clearHoverPreview }), [
18921
19035
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(filteredCountries.value, (option, index) => {
18922
19036
  return vue.openBlock(), vue.createElementBlock("li", {
@@ -19025,7 +19139,7 @@ const _hoisted_2$3 = {
19025
19139
  key: 1,
19026
19140
  class: "font-thin mb-1"
19027
19141
  };
19028
- const _hoisted_3$3 = { class: "flex flex-wrap items-start gap-x-1" };
19142
+ const _hoisted_3$3 = { class: "flex flex-wrap items-start gap-x-2" };
19029
19143
  const _hoisted_4$3 = {
19030
19144
  key: 2,
19031
19145
  class: "text-red-700 font-bold mt-1"
@@ -19064,12 +19178,9 @@ const _sfc_main$9 = /* @__PURE__ */ vue.defineComponent({
19064
19178
  autocomplete: { default: "tel" },
19065
19179
  required: { type: Boolean, default: false },
19066
19180
  placeholder: { default: void 0 },
19067
- maxlength: { default: void 0 },
19068
- minlength: { default: void 0 },
19069
19181
  name: { default: void 0 },
19070
19182
  autofocus: { type: Boolean, default: false },
19071
- readonly: { type: Boolean, default: false },
19072
- pattern: { default: void 0 }
19183
+ readonly: { type: Boolean, default: false }
19073
19184
  }, {
19074
19185
  "modelValue": { default: "" },
19075
19186
  "modelModifiers": {},
@@ -19078,7 +19189,7 @@ const _sfc_main$9 = /* @__PURE__ */ vue.defineComponent({
19078
19189
  }),
19079
19190
  emits: /* @__PURE__ */ vue.mergeModels(["update:modelValue", "update:country", "update:e164", "valid", "noCountryResults", "blur"], ["update:modelValue", "update:country"]),
19080
19191
  setup(__props, { emit: __emit }) {
19081
- const [nationalNumber, modelModifiers] = vue.useModel(__props, "modelValue");
19192
+ const [nationalNumber] = vue.useModel(__props, "modelValue");
19082
19193
  const country = vue.useModel(__props, "country");
19083
19194
  const attrs = vue.useAttrs();
19084
19195
  const props = __props;
@@ -19097,12 +19208,10 @@ const _sfc_main$9 = /* @__PURE__ */ vue.defineComponent({
19097
19208
  autocomplete: props.autocomplete,
19098
19209
  required: props.required,
19099
19210
  placeholder: props.placeholder,
19100
- maxlength: props.maxlength,
19101
- minlength: props.minlength,
19102
19211
  name: props.name,
19103
19212
  autofocus: props.autofocus,
19104
19213
  readonly: props.readonly,
19105
- pattern: props.pattern,
19214
+ inputmode: "tel",
19106
19215
  ...inputAttrs.value
19107
19216
  }));
19108
19217
  const countryItems = vue.computed(() => {
@@ -19113,6 +19222,10 @@ const _sfc_main$9 = /* @__PURE__ */ vue.defineComponent({
19113
19222
  props.defaultCountry
19114
19223
  );
19115
19224
  });
19225
+ const phoneMask = vue.computed(() => getPhoneMaskForCountry(country.value ?? props.defaultCountry));
19226
+ const phoneMaskOptions = vue.computed(() => ({
19227
+ prepare: (value) => applyPhoneNormalization(value, country.value ?? props.defaultCountry)
19228
+ }));
19116
19229
  const committedValid = vue.ref(null);
19117
19230
  const resolvedLabel = vue.computed(() => props.label === void 0 ? t("FdsPhonenumber.phoneNumber") : props.label);
19118
19231
  const resolvedInvalidMessage = vue.computed(
@@ -19136,6 +19249,18 @@ const _sfc_main$9 = /* @__PURE__ */ vue.defineComponent({
19136
19249
  const result2 = validatePhoneNumber(nationalNumber.value ?? "", country.value ?? "SE");
19137
19250
  emit("update:e164", result2.isValid && result2.phoneNumber ? result2.phoneNumber : "");
19138
19251
  }
19252
+ function applyPhoneNormalization(value, countryCode = country.value ?? props.defaultCountry) {
19253
+ if (!shouldNormalizePhoneInput(value, countryCode)) {
19254
+ return value;
19255
+ }
19256
+ return normalizeNationalPhoneInput(value, countryCode);
19257
+ }
19258
+ vue.watch(nationalNumber, (value) => {
19259
+ const normalized = applyPhoneNormalization(value ?? "");
19260
+ if (normalized !== (value ?? "")) {
19261
+ nationalNumber.value = normalized;
19262
+ }
19263
+ });
19139
19264
  vue.watch(country, () => {
19140
19265
  if (committedValid.value === null) {
19141
19266
  return;
@@ -19143,6 +19268,10 @@ const _sfc_main$9 = /* @__PURE__ */ vue.defineComponent({
19143
19268
  runValidation();
19144
19269
  });
19145
19270
  function handleBlur(ev) {
19271
+ const normalized = applyPhoneNormalization(nationalNumber.value ?? "");
19272
+ if (normalized !== (nationalNumber.value ?? "")) {
19273
+ nationalNumber.value = normalized;
19274
+ }
19146
19275
  runValidation();
19147
19276
  emit("blur", ev);
19148
19277
  }
@@ -19172,15 +19301,15 @@ const _sfc_main$9 = /* @__PURE__ */ vue.defineComponent({
19172
19301
  vue.createVNode(_sfc_main$r, vue.mergeProps({
19173
19302
  modelValue: vue.unref(nationalNumber),
19174
19303
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.isRef(nationalNumber) ? nationalNumber.value = $event : null),
19175
- modelModifiers: vue.unref(modelModifiers),
19176
- type: "tel",
19304
+ mask: phoneMask.value,
19305
+ "mask-options": phoneMaskOptions.value,
19177
19306
  valid: displayValid.value,
19178
19307
  disabled: __props.disabled,
19179
19308
  optional: __props.optional,
19180
19309
  ariaLabel: vue.unref(t)("FdsPhonenumber.phoneNumber"),
19181
19310
  "data-testid": __props.dataTestid ? `${__props.dataTestid}-number` : void 0,
19182
19311
  class: ["mb-0! min-w-0 flex-1", __props.inputClass ?? ""]
19183
- }, forwardedInputProps.value, { onBlur: handleBlur }), null, 16, ["modelValue", "modelModifiers", "valid", "disabled", "optional", "ariaLabel", "data-testid", "class"])
19312
+ }, forwardedInputProps.value, { onBlur: handleBlur }), null, 16, ["modelValue", "mask", "mask-options", "valid", "disabled", "optional", "ariaLabel", "data-testid", "class"])
19184
19313
  ]),
19185
19314
  noCountryResults.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$3, vue.toDisplayString(vue.unref(t)("FdsPhonenumber.noCountryResults")), 1)) : vue.createCommentVNode("", true),
19186
19315
  showInvalidMessage.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5$3, vue.toDisplayString(resolvedInvalidMessage.value), 1)) : vue.createCommentVNode("", true)