fds-vue-core 7.2.3 → 7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fds-vue-core",
3
- "version": "7.2.3",
3
+ "version": "7.2.4",
4
4
  "description": "FDS Vue Core Component Library",
5
5
  "type": "module",
6
6
  "main": "./dist/fds-vue-core.cjs.js",
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, ref, watch } from 'vue'
2
+ import { computed, ref, useAttrs, watch } from 'vue'
3
3
  import { useFdsI18n } from '../../../plugin/useFdsI18n'
4
4
  import FdsInput from '../FdsInput/FdsInput.vue'
5
5
  import { buildCountryOptions, sortCountryOptionsByName } from './countries'
@@ -11,8 +11,9 @@ defineOptions({
11
11
  inheritAttrs: false,
12
12
  })
13
13
 
14
- const nationalNumber = defineModel<string>({ default: '' })
14
+ const [nationalNumber, modelModifiers] = defineModel<string>({ default: '' })
15
15
  const country = defineModel<string>('country', { default: 'SE' })
16
+ const attrs = useAttrs()
16
17
 
17
18
  const props = withDefaults(defineProps<FdsPhonenumberProps>(), {
18
19
  label: undefined,
@@ -20,6 +21,16 @@ const props = withDefaults(defineProps<FdsPhonenumberProps>(), {
20
21
  optional: false,
21
22
  valid: undefined,
22
23
  invalidMessage: undefined,
24
+ id: undefined,
25
+ autocomplete: 'tel',
26
+ required: false,
27
+ placeholder: undefined,
28
+ maxlength: undefined,
29
+ minlength: undefined,
30
+ name: undefined,
31
+ autofocus: false,
32
+ readonly: false,
33
+ pattern: undefined,
23
34
  defaultCountry: 'SE',
24
35
  countries: undefined,
25
36
  locale: undefined,
@@ -35,6 +46,26 @@ const emit = defineEmits<FdsPhonenumberEmits>()
35
46
  const { t, locale: fdsLocale } = useFdsI18n()
36
47
 
37
48
  const resolvedLocale = computed(() => props.locale ?? fdsLocale.value)
49
+ const inputAttrs = computed(() => {
50
+ const { class: _class, style, ...rest } = attrs
51
+ return {
52
+ ...rest,
53
+ ...(style == null ? {} : { style: style as string | Record<string, unknown> }),
54
+ }
55
+ })
56
+ const forwardedInputProps = computed(() => ({
57
+ id: props.id,
58
+ autocomplete: props.autocomplete,
59
+ required: props.required,
60
+ placeholder: props.placeholder,
61
+ maxlength: props.maxlength,
62
+ minlength: props.minlength,
63
+ name: props.name,
64
+ autofocus: props.autofocus,
65
+ readonly: props.readonly,
66
+ pattern: props.pattern,
67
+ ...inputAttrs.value,
68
+ }))
38
69
 
39
70
  const countryItems = computed(() => {
40
71
  const options = props.countries?.length
@@ -52,6 +83,12 @@ const phoneValidationOptions = computed(() => ({ numberType: props.numberType })
52
83
  /** Set after the phone number field has blurred; validation does not run on input. */
53
84
  const committedValid = ref<boolean | null>(null)
54
85
 
86
+ const resolvedLabel = computed(() => (props.label === undefined ? t('FdsPhonenumber.phoneNumber') : props.label))
87
+
88
+ const resolvedInvalidMessage = computed(() =>
89
+ props.invalidMessage === undefined ? t('FdsPhonenumber.invalidPhone') : props.invalidMessage,
90
+ )
91
+
55
92
  const displayValid = computed((): boolean | null | undefined => {
56
93
  if (props.valid === false) return false
57
94
  if (props.valid === true) return true
@@ -61,7 +98,7 @@ const displayValid = computed((): boolean | null | undefined => {
61
98
  })
62
99
 
63
100
  const showInvalidMessage = computed(
64
- () => displayValid.value === false && !props.optional && props.invalidMessage && !props.disabled,
101
+ () => displayValid.value === false && !props.optional && !!resolvedInvalidMessage.value && !props.disabled,
65
102
  )
66
103
 
67
104
  const noCountryResults = ref(false)
@@ -99,8 +136,12 @@ function onNoCountryResults(value: boolean) {
99
136
 
100
137
  <template>
101
138
  <div class="w-full mb-6">
102
- <label v-if="label" class="block font-bold text-gray-900 cursor-pointer" :class="{ 'mb-0': meta, 'mb-1': !meta }">
103
- {{ label }}
139
+ <label
140
+ v-if="resolvedLabel"
141
+ class="block font-bold text-gray-900 cursor-pointer"
142
+ :class="{ 'mb-0': meta, 'mb-1': !meta }"
143
+ >
144
+ {{ resolvedLabel }}
104
145
  </label>
105
146
  <div v-if="meta" class="font-thin mb-1">
106
147
  {{ meta }}
@@ -118,6 +159,7 @@ function onNoCountryResults(value: boolean) {
118
159
  />
119
160
  <FdsInput
120
161
  v-model="nationalNumber"
162
+ :modelModifiers="modelModifiers"
121
163
  type="tel"
122
164
  :valid="displayValid"
123
165
  :disabled="disabled"
@@ -125,6 +167,7 @@ function onNoCountryResults(value: boolean) {
125
167
  :ariaLabel="t('FdsPhonenumber.phoneNumber')"
126
168
  :data-testid="dataTestid ? `${dataTestid}-number` : undefined"
127
169
  :class="['mb-0! min-w-0 flex-1', inputClass ?? '']"
170
+ v-bind="forwardedInputProps"
128
171
  @blur="handleBlur"
129
172
  />
130
173
  </div>
@@ -132,7 +175,7 @@ function onNoCountryResults(value: boolean) {
132
175
  {{ t('FdsPhonenumber.noCountryResults') }}
133
176
  </div>
134
177
  <div v-if="showInvalidMessage" class="text-red-700 font-bold mt-1">
135
- {{ invalidMessage }}
178
+ {{ resolvedInvalidMessage }}
136
179
  </div>
137
180
  </div>
138
181
  </template>
@@ -1,3 +1,4 @@
1
+ import type { FdsInputProps } from '../FdsInput/types'
1
2
  import type { CountryPhoneOption } from './countries'
2
3
 
3
4
  /**
@@ -6,13 +7,18 @@ import type { CountryPhoneOption } from './countries'
6
7
  */
7
8
  export type FdsPhonenumberNumberType = 'mobile' | 'any'
8
9
 
9
- export interface FdsPhonenumberProps {
10
+ type FdsPhonenumberInputPassthroughProps = Pick<
11
+ FdsInputProps,
12
+ 'id' | 'autocomplete' | 'required' | 'placeholder' | 'maxlength' | 'minlength' | 'name' | 'autofocus' | 'readonly' | 'pattern'
13
+ >
14
+
15
+ export interface FdsPhonenumberProps extends FdsPhonenumberInputPassthroughProps {
10
16
  label?: string
11
17
  meta?: string
12
18
  optional?: boolean
13
19
  valid?: boolean | null
14
20
  invalidMessage?: string
15
- /** National number (without country calling code). */
21
+ /** National number as typed by the user (without country calling code). */
16
22
  modelValue?: string
17
23
  /** ISO 3166-1 alpha-2 country code, e.g. `SE`. */
18
24
  country?: string
@@ -28,6 +34,12 @@ export interface FdsPhonenumberProps {
28
34
  dataTestid?: string
29
35
  selectClass?: string
30
36
  inputClass?: string
37
+ // Event handler props for consumer type inference
38
+ onValid?: ((value: boolean | null) => void) | Array<(value: boolean | null) => void>
39
+ onNoCountryResults?: ((value: boolean) => void) | Array<(value: boolean) => void>
40
+ onBlur?: ((event: FocusEvent) => void) | Array<(event: FocusEvent) => void>
41
+ 'onUpdate:e164'?: ((value: string) => void) | Array<(value: string) => void>
42
+ 'onUpdate:country'?: ((value: string) => void) | Array<(value: string) => void>
31
43
  }
32
44
 
33
45
  export interface FdsPhonenumberEmits {
package/src/lang/en.json CHANGED
@@ -44,6 +44,7 @@
44
44
  "FdsPagination.nextPage": "Go to next page",
45
45
  "FdsPagination.previousPage": "Go to previous page",
46
46
  "FdsPhonenumber.countryCode": "Country code",
47
+ "FdsPhonenumber.invalidPhone": "Enter a valid phone number",
47
48
  "FdsPhonenumber.noCountryResults": "No country matches your search",
48
49
  "FdsPhonenumber.phoneNumber": "Phone number",
49
50
  "FdsSearchSelectPro.loadingMore": "Loading more...",
package/src/lang/sv.json CHANGED
@@ -44,6 +44,7 @@
44
44
  "FdsPagination.nextPage": "Gå till nästa sida",
45
45
  "FdsPagination.previousPage": "Gå till föregående sida",
46
46
  "FdsPhonenumber.countryCode": "Landskod",
47
+ "FdsPhonenumber.invalidPhone": "Ange ett giltigt telefonnummer",
47
48
  "FdsPhonenumber.noCountryResults": "Inget land matchar sökningen",
48
49
  "FdsPhonenumber.phoneNumber": "Telefonnummer",
49
50
  "FdsSearchSelectPro.loadingMore": "Hämtar fler...",