@usssa/component-library 1.0.0-alpha.15 → 1.0.0-alpha.151

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +6 -3
  2. package/package.json +23 -5
  3. package/src/assets/logo.svg +19 -0
  4. package/src/assets/no-result.svg +25 -0
  5. package/src/assets/quasar-logo-vertical.svg +15 -0
  6. package/src/assets/upload-illustration.svg +48 -0
  7. package/src/components/core/UAvatar.vue +56 -24
  8. package/src/components/core/UAvatarGroup.vue +62 -52
  9. package/src/components/core/UBadgeStd.vue +6 -1
  10. package/src/components/core/UBannerStd.vue +100 -31
  11. package/src/components/core/UBreadCrumbs.vue +171 -0
  12. package/src/components/core/UBtnIcon.vue +58 -53
  13. package/src/components/core/UBtnStd.vue +39 -31
  14. package/src/components/core/UBtnToggle.vue +11 -6
  15. package/src/components/core/UCheckboxStd.vue +26 -20
  16. package/src/components/core/UChip.vue +76 -42
  17. package/src/components/core/UDate.vue +565 -0
  18. package/src/components/core/UDialogStd.vue +460 -53
  19. package/src/components/core/UDrawer.vue +321 -0
  20. package/src/components/core/UInnerLoader.vue +69 -0
  21. package/src/components/core/UInputAddressLookup.vue +471 -0
  22. package/src/components/core/UInputPhoneStd.vue +73 -68
  23. package/src/components/core/UInputTextStd.vue +133 -116
  24. package/src/components/core/UInputTypeahead.vue +44 -0
  25. package/src/components/core/UInputTypeaheadAdvanceSearch.vue +126 -0
  26. package/src/components/core/UMenuButtonStd.vue +280 -0
  27. package/src/components/core/UMenuDropdown.vue +80 -0
  28. package/src/components/core/UMenuDropdownAdvancedSearch.vue +293 -0
  29. package/src/components/core/UMenuItem.vue +161 -0
  30. package/src/components/core/UMenuSearch.vue +69 -0
  31. package/src/components/core/UMultiSelectStd.vue +258 -54
  32. package/src/components/core/UPagination.vue +67 -27
  33. package/src/components/core/URadioBtn.vue +66 -43
  34. package/src/components/core/URadioStd.vue +19 -12
  35. package/src/components/core/USelectStd.vue +360 -80
  36. package/src/components/core/USheet.vue +349 -0
  37. package/src/components/core/UTabBtnStd.vue +87 -59
  38. package/src/components/core/UTable/UTable.vue +811 -42
  39. package/src/components/core/UTableStd.vue +875 -275
  40. package/src/components/core/UTabsStd.vue +57 -16
  41. package/src/components/core/UToggleStd.vue +43 -29
  42. package/src/components/core/UToolbar/UCustomMenuIcon.vue +58 -0
  43. package/src/components/core/UToolbar/UToolbar.vue +210 -0
  44. package/src/components/core/UTooltip.vue +31 -10
  45. package/src/components/core/UTypeahead.vue +830 -0
  46. package/src/components/core/UUploader.vue +535 -0
  47. package/src/components/index.js +61 -21
  48. package/src/composables/useNotify.js +16 -16
  49. package/src/composables/useOverlayLoader.js +23 -0
  50. package/src/composables/useScreenType.js +30 -0
  51. package/src/css/app.sass +168 -0
  52. package/src/css/colors.sass +103 -0
  53. package/src/css/media.sass +1 -0
  54. package/src/css/quasar.variables.sass +121 -0
  55. package/src/css/typography.sass +0 -0
  56. package/src/css/vars/colors.variables.sass +127 -0
  57. package/src/utils/data.ts +146 -0
@@ -0,0 +1,471 @@
1
+ <script setup>
2
+ import { computed, onMounted, ref, watch } from 'vue'
3
+ import UInputTextStd from './UInputTextStd.vue'
4
+ import UTooltip from './UTooltip.vue'
5
+
6
+ const emit = defineEmits(['onRightIconClick', 'onUpdate'])
7
+ const modelValue = defineModel()
8
+ defineOptions({
9
+ inheritAttrs: false,
10
+ })
11
+ const props = defineProps({
12
+ borderless: {
13
+ type: Boolean,
14
+ default: false,
15
+ },
16
+ dataTestId:{
17
+ type: String,
18
+ default: 'address-lookup'
19
+ },
20
+ disable: {
21
+ type: Boolean,
22
+ default: false,
23
+ },
24
+ error: {
25
+ type: Boolean,
26
+ },
27
+ errorMessage: {
28
+ type: String,
29
+ },
30
+ hintIcon: {
31
+ type: String,
32
+ },
33
+ hintText: {
34
+ type: String,
35
+ },
36
+ isRequired: {
37
+ type: Boolean,
38
+ default: false,
39
+ },
40
+ label: {
41
+ type: String,
42
+ },
43
+ leftBorderRadius: {
44
+ type: Boolean,
45
+ default: false,
46
+ },
47
+ leftIcon: {
48
+ type: String,
49
+ },
50
+ outlined: {
51
+ type: Boolean,
52
+ default: true,
53
+ },
54
+ parentClass: {
55
+ type: String,
56
+ },
57
+ placeholder: {
58
+ type: String,
59
+ },
60
+ readonly: {
61
+ type: Boolean,
62
+ default: false,
63
+ },
64
+ rightIcon: {
65
+ type: String,
66
+ },
67
+ rightIconAriaLabel: {
68
+ type: String,
69
+ },
70
+ size: {
71
+ type: String,
72
+ default: 'md',
73
+ validator: (val) => ['sm', 'md', 'lg'].includes(val),
74
+ },
75
+ toolTipText: {
76
+ type: String,
77
+ },
78
+ validationRules: {
79
+ type: Array,
80
+ }
81
+ })
82
+
83
+ let sessionToken, autocompleteSuggestion
84
+
85
+ const inputRef = ref(null)
86
+ const predictions = ref([])
87
+ const resultItem = ref({})
88
+ const resultsMenuRef = ref(null)
89
+ const resultsMenuShowing = ref(false)
90
+
91
+ const leftBorderRadius = computed(() => {
92
+ if (props.leftBorderRadius === true) {
93
+ return 'leftBorderRadius'
94
+ }
95
+ return ''
96
+ })
97
+
98
+ const handleClear = () => {
99
+ modelValue.value = ''
100
+ }
101
+
102
+ const parseAddressComponents = (addressComponents) => {
103
+ const address = {}
104
+ for (const component of addressComponents) {
105
+ const { types, longText, shortText } = component
106
+ if (types.includes('street_number')) address.street_number = longText
107
+ if (types.includes('route')) address.street = longText
108
+ if (types.includes('locality')) address.city = longText
109
+ if (types.includes('administrative_area_level_1')) address.state = shortText
110
+ if (types.includes('administrative_area_level_2')) address.county = longText
111
+ if (types.includes('country')) address.country = shortText
112
+ if (types.includes('postal_code')) address.postal_code = longText
113
+ if (types.includes('plus_code')) address.plus_code = longText
114
+ }
115
+ if (address.street && address.street_number)
116
+ address.street_address = `${address.street_number} ${address.street}`
117
+ if (address.street && !address.street_number)
118
+ address.street_address = address.street
119
+
120
+ return address
121
+ }
122
+
123
+ const handleUpdate = async (input) => {
124
+ // fetchAutocompleteSuggestions reference
125
+ // https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data#AutocompleteRequest
126
+ const payload = {
127
+ input,
128
+ sessionToken,
129
+ language: 'en-US',
130
+ // locationRestriction: {
131
+ // west: 0,
132
+ // north: 0,
133
+ // east: 0,
134
+ // south: 0,
135
+ // }
136
+ // origin: { lat: 0, lng: 0 }
137
+ // region: 'us',
138
+ }
139
+
140
+ const { suggestions } =
141
+ await autocompleteSuggestion.fetchAutocompleteSuggestions(payload)
142
+
143
+ const result = []
144
+ for (let suggestion of suggestions) {
145
+ let prediction = suggestion.placePrediction.toPlace()
146
+ await prediction.fetchFields({
147
+ fields: [
148
+ 'addressComponents',
149
+ 'adrFormatAddress',
150
+ 'displayName',
151
+ 'formattedAddress',
152
+ 'googleMapsURI',
153
+ 'internationalPhoneNumber',
154
+ 'location',
155
+ 'nationalPhoneNumber',
156
+ 'websiteURI',
157
+ ],
158
+ })
159
+
160
+ const {
161
+ addressComponents,
162
+ adrFormatAddress,
163
+ displayName,
164
+ formattedAddress,
165
+ googleMapsURI,
166
+ internationalPhoneNumber,
167
+ location,
168
+ nationalPhoneNumber,
169
+ websiteURI,
170
+ } = prediction
171
+
172
+ const parsedAddressComponents = parseAddressComponents(addressComponents)
173
+ const finalResult = {
174
+ ...parsedAddressComponents,
175
+ adrFormatAddress,
176
+ coordinates: {
177
+ lat: location.lat(),
178
+ lng: location.lng(),
179
+ },
180
+ displayName,
181
+ formattedAddress,
182
+ googleMapsURI,
183
+ internationalPhoneNumber,
184
+ nationalPhoneNumber,
185
+ websiteURI,
186
+ }
187
+ result.push(finalResult)
188
+ }
189
+
190
+ predictions.value = result
191
+ }
192
+
193
+ const onClick = (item) => {
194
+ resultItem.value = item
195
+ resultsMenuRef.value.hide()
196
+ emit('onUpdate', item)
197
+ }
198
+
199
+ onMounted(async () => {
200
+ const { AutocompleteSessionToken, AutocompleteSuggestion } =
201
+ await google.maps.importLibrary('places')
202
+
203
+ sessionToken = new AutocompleteSessionToken()
204
+ autocompleteSuggestion = AutocompleteSuggestion
205
+ })
206
+
207
+ watch(modelValue, async (value) => {
208
+ if (value) {
209
+ if (!resultsMenuShowing.value && resultsMenuRef.value)
210
+ resultsMenuRef.value.show()
211
+ await handleUpdate(value)
212
+ } else {
213
+ if (resultsMenuShowing.value && resultsMenuRef.value)
214
+ resultsMenuRef.value.hide()
215
+ predictions.value = []
216
+ resultItem.value = {}
217
+ emit('onUpdate', {})
218
+ }
219
+ })
220
+ </script>
221
+
222
+ <template>
223
+ <div
224
+ v-if="JSON.stringify(resultItem) === '{}'"
225
+ :class="`q-gutter-xs ${parentClass}`"
226
+ :dataTestId="dataTestId"
227
+ >
228
+ <label
229
+ v-if="label"
230
+ class="row items-center q-mb-xxs"
231
+ for="input"
232
+ role="label"
233
+ >
234
+ <div class="u-input-label text-body-sm">
235
+ <span>{{ label }}</span>
236
+ <span v-if="isRequired" class="text-red-5 text-body-sm q-mx-xs">
237
+ {{ '*' }}
238
+ </span>
239
+ </div>
240
+ <q-icon
241
+ v-if="toolTipText"
242
+ class="fa-kit-duotone fa-circle-info cursor-pointer"
243
+ :aria-label="toolTipText"
244
+ color="neutral-9"
245
+ size="1rem"
246
+ >
247
+ <UTooltip
248
+ anchor="top middle"
249
+ :description="toolTipText"
250
+ :offset="[0, 0]"
251
+ self="bottom middle"
252
+ />
253
+ </q-icon>
254
+ </label>
255
+ <q-input
256
+ v-bind="$attrs"
257
+ v-model="modelValue"
258
+ :class="`u-input field-${size} ${leftBorderRadius}`"
259
+ :borderless="borderless"
260
+ :bottom-slots="!!hintText"
261
+ :debounce="500"
262
+ :disable="disable"
263
+ :error="error"
264
+ hide-bottom-space
265
+ id="input"
266
+ name="input"
267
+ :outlined="outlined"
268
+ :placeholder="placeholder"
269
+ :readonly="readonly"
270
+ ref="inputRef"
271
+ :rules="validationRules"
272
+ :standout="!outlined"
273
+ type="text"
274
+ >
275
+ <q-menu
276
+ v-model="resultsMenuShowing"
277
+ no-focus
278
+ ref="resultsMenuRef"
279
+ @hide="resultsMenuShowing = false"
280
+ @show="resultsMenuShowing = true"
281
+ >
282
+ <q-list bordered>
283
+ <q-item
284
+ v-for="(p, i) of predictions"
285
+ clickable
286
+ :key="i"
287
+ @click="onClick(p)"
288
+ >
289
+ <q-item-section avatar>
290
+ <q-icon class="fa-kit-duotone fa-location-dot" color="primary" />
291
+ </q-item-section>
292
+ <q-item-section>
293
+ <q-item-label>{{ p.displayName }}</q-item-label>
294
+ <q-item-label caption>
295
+ <span class="text-caption">
296
+ {{ p.formattedAddress }}
297
+ </span>
298
+ </q-item-label>
299
+ </q-item-section>
300
+ </q-item>
301
+ </q-list>
302
+ </q-menu>
303
+
304
+ <template v-if="leftIcon" #prepend>
305
+ <slot name="prepend"></slot>
306
+ <q-icon
307
+ v-if="!$slots.prepend"
308
+ :class="`slot-icon-size-${size} ${leftIcon}`"
309
+ />
310
+ </template>
311
+
312
+ <template v-if="hintText" #hint>
313
+ <div class="row items-center text-neutral-9 no-wrap">
314
+ <q-icon
315
+ v-if="hintIcon"
316
+ :class="hintIcon"
317
+ :aria-label="hintText"
318
+ size="1rem"
319
+ />
320
+ <div class="q-ml-xxs text-body-xs">{{ hintText }}</div>
321
+ </div>
322
+ </template>
323
+
324
+ <template #append>
325
+ <slot name="append">
326
+ <q-icon
327
+ v-if="rightIcon"
328
+ :class="`slot-icon-size-${size} ${rightIcon}`"
329
+ :aria-label="
330
+ rightIcon && rightIconAriaLabel
331
+ ? rightIconAriaLabel
332
+ : 'right input icon '
333
+ "
334
+ :tabindex="0"
335
+ @click="handleRightIconClick"
336
+ />
337
+ </slot>
338
+ </template>
339
+
340
+ <template v-slot:error>
341
+ <div v-if="errorMessage" class="row items-center no-wrap">
342
+ <q-icon
343
+ class="fa-kit-duotone fa-warning-octagon"
344
+ :aria-label="errorMessage"
345
+ size="1rem"
346
+ />
347
+ <div class="q-ml-xxs text-body-xs" role="validation error">
348
+ {{ errorMessage }}
349
+ </div>
350
+ </div>
351
+ </template>
352
+ </q-input>
353
+ </div>
354
+
355
+ <UInputTextStd
356
+ v-if="JSON.stringify(resultItem) !== '{}'"
357
+ v-model="resultItem.formattedAddress"
358
+ :dataTestId="dataTestId"
359
+ :label="label"
360
+ readonly
361
+ rightIcon="fa-kit-duotone fa-circle-xmark"
362
+ :size="size"
363
+ @onRightIconClick="handleClear"
364
+ />
365
+ </template>
366
+
367
+ <style lang="sass">
368
+ .u-input
369
+ .q-field--with-bottom
370
+ padding-bottom: 0px
371
+ &.q-field--outlined.q-field--disabled .q-field__control
372
+ background: $neutral-3
373
+ &.leftBorderRadius
374
+ &.q-field--outlined .q-field__control
375
+ border-radius: 0px $xs $xs 0px
376
+ &.q-field--borderless
377
+ .q-field__control
378
+ border-radius: 0px $xs $xs 0px
379
+
380
+ .q-field__inner
381
+ border-radius: $xs
382
+
383
+ &.q-field--borderless
384
+ .q-field__control
385
+ padding: 0 $xs
386
+ background: $neutral-1
387
+ border-radius: $xs
388
+ &:hover
389
+ box-shadow : 0px 0px 0px 2px $primary-transparent
390
+
391
+ .q-field--standout .q-field__control
392
+ border-radius: $xs
393
+
394
+ .q-field__append.q-field__marginal.row.no-wrap.items-center.q-anchor--skip
395
+ display: none
396
+
397
+ .q-field__before,
398
+ .q-field__prepend
399
+ padding: 0 $xs
400
+ padding-left: 0
401
+
402
+ .q-field__after,
403
+ .q-field__append
404
+ padding-left: $xs
405
+
406
+ .q-icon
407
+ &.slot-icon-size-sm
408
+ font-size: $sm
409
+ &.slot-icon-size-md
410
+ font-size: $ba
411
+ &.slot-icon-size-lg
412
+ font-size: $ba
413
+
414
+ &.q-field--auto-height .q-field__control,
415
+ &.q-field--auto-height .q-field__native
416
+ min-height: $md
417
+
418
+ &.q-field--outlined .q-field__control
419
+ border-radius: $xs
420
+ padding: 0 $xs
421
+ background: $neutral-1
422
+
423
+ &::before
424
+ border:1.5px solid $neutral-4
425
+
426
+ &:hover::before
427
+ border:1.5px solid $primary
428
+
429
+ .q-field__control.relative-position.row.no-wrap.text-negative:focus-within
430
+ box-shadow: 0px 0px 0px 2px $accent-transparent
431
+
432
+ .q-field__control:focus-within
433
+ box-shadow : 0px 0px 0px 2px $primary-transparent
434
+
435
+ &.field-sm
436
+ .q-field__control,
437
+ .q-field__marginal
438
+ height: $md
439
+ &.q-field--outlined.q-field__control
440
+ padding: 0 $xs
441
+
442
+ &.q-field__prepend .q-field__marginal
443
+ padding: 0 $xs
444
+
445
+ &.field-md
446
+ .q-field__control,
447
+ .q-field__marginal
448
+ height: $lg
449
+ &.q-field--outlined.q-field__control
450
+ padding: 0 $xs
451
+
452
+ &.q-field__prepend.q-field__marginal
453
+ padding: 0 $xs
454
+ padding-left: 0
455
+
456
+ &.field-lg
457
+ .q-field__control,
458
+ .q-field__marginal
459
+ height: $xl
460
+ &.q-field--outlined .q-field__control
461
+ padding: 0 $sm
462
+ .q-field__prepend.q-field__marginal
463
+ padding-left: 0px
464
+
465
+ .q-field__bottom
466
+ padding: 0
467
+ align-items: center
468
+
469
+ .q-field__messages
470
+ margin-top: $xxs
471
+ </style>
@@ -1,14 +1,38 @@
1
1
  <script setup>
2
2
  import UInputTextStd from './UInputTextStd.vue'
3
3
 
4
+ const emit = defineEmits(['update-country'])
5
+ const modelValue = defineModel()
4
6
  const props = defineProps({
5
- hintText: {
7
+ ariaLabel: {
8
+ type: String,
9
+ required: true,
10
+ },
11
+ borderless: {
12
+ type: Boolean,
13
+ default: false,
14
+ },
15
+ dataTestId: {
16
+ type: String,
17
+ default: 'input-phone-std',
18
+ },
19
+ disable: {
20
+ type: Boolean,
21
+ default: false,
22
+ },
23
+ error: {
24
+ type: Boolean,
25
+ },
26
+ errorMessage: {
6
27
  type: String,
7
28
  },
8
29
  hintIcon: {
9
30
  type: String,
10
31
  default: 'fa-kit-duotone fa-circle-info',
11
32
  },
33
+ hintText: {
34
+ type: String,
35
+ },
12
36
  isRequired: {
13
37
  type: Boolean,
14
38
  default: false,
@@ -16,20 +40,30 @@ const props = defineProps({
16
40
  label: {
17
41
  type: String,
18
42
  },
19
- rightIcon: {
43
+ mask: {
20
44
  type: String,
45
+ default: '##########',
46
+ },
47
+ options: {
48
+ type: Array,
21
49
  },
22
50
  outlined: {
23
51
  type: Boolean,
24
52
  default: true,
25
53
  },
26
- borderless: {
54
+ placeholder: {
55
+ type: String,
56
+ default: 'Input Text',
57
+ },
58
+ readonly: {
27
59
  type: Boolean,
28
60
  default: false,
29
61
  },
30
- placeholder: {
62
+ rightIcon: {
31
63
  type: String,
32
- default: 'Input Text',
64
+ },
65
+ selectedCountry: {
66
+ type: Object,
33
67
  },
34
68
  size: {
35
69
  type: String,
@@ -43,110 +77,82 @@ const props = defineProps({
43
77
  type: Array,
44
78
  default: () => [(val) => val.length === 10],
45
79
  },
46
- readonly: {
47
- type: Boolean,
48
- default: false,
49
- },
50
- disable: {
51
- type: Boolean,
52
- default: false,
53
- },
54
- error: {
55
- type: Boolean,
56
- },
57
- errorMessage: {
58
- type: String,
59
- },
60
- options: {
61
- type: Array,
62
- },
63
- selectedCountry: {
64
- type: Object,
65
- },
66
- mask: {
67
- type: String,
68
- default: '##########',
69
- },
70
80
  })
71
81
 
72
- const modelValue = defineModel()
73
-
74
- const emit = defineEmits(['update-country'])
75
-
76
82
  const selectCountry = (country) => {
77
83
  emit('update-country', country)
78
84
  }
79
-
80
- const toLowerCase = (str) => str.toLowerCase()
85
+ const toLowerCase = (str) => str?.toLowerCase()
81
86
  </script>
82
87
 
83
88
  <template>
84
89
  <UInputTextStd
85
- class="phone-input"
86
- :label="label"
87
- :isRequired="isRequired"
88
90
  v-model="modelValue"
89
- :mask="mask"
90
- :validationRules="validationRules"
91
- leftIcon="true"
92
- :rightIcon="rightIcon"
93
- :hintText="hintText"
94
- :hintIcon="hintIcon"
95
- :toolTipText="toolTipText"
96
- :placeholder="placeholder"
97
- :size="size"
91
+ class="phone-input"
92
+ :borderless="borderless"
93
+ :dataTestId="'input-text-std'"
98
94
  :disable="disable"
99
- :readonly="readonly"
100
95
  :error="error"
101
96
  :error-message="errorMessage"
102
- :borderless="borderless"
97
+ :hintIcon="hintIcon"
98
+ :hintText="hintText"
99
+ :isRequired="isRequired"
100
+ :label="label"
101
+ leftIcon="true"
102
+ :mask="mask"
103
103
  :outlined="outlined"
104
+ :placeholder="placeholder"
105
+ :readonly="readonly"
106
+ :rightIcon="rightIcon"
107
+ :size="size"
108
+ :toolTipText="toolTipText"
109
+ :validationRules="validationRules"
104
110
  >
105
111
  <template v-slot:prepend>
106
112
  <q-btn-dropdown
107
- :disable="readonly"
108
- rounded
109
- flat
110
- class="u-phone-dropdown text-body-sm"
111
- :class="`btn-field-${size}`"
113
+ :class="['u-phone-dropdown', 'text-body-sm', 'btn-field-' + size]"
112
114
  content-class="u-dropdown-list"
115
+ :aria-label="ariaLabel"
116
+ :dataTestId="dataTestId"
117
+ :disable="disable"
118
+ flat
113
119
  menu-anchor="top right"
114
- menu-self="bottom middle"
115
120
  :menu-offset="[30, 5]"
116
- dropdown-icon="img:icons/caret-down.svg"
121
+ menu-self="bottom middle"
122
+ rounded
117
123
  >
118
124
  <template #label>
119
125
  <q-icon
120
- left
121
- :aria-label="selectedCountry.name"
122
126
  :class="`fi fi-${toLowerCase(
123
- selectedCountry.flag
127
+ selectedCountry?.flag
124
128
  )} flag-icon q-mr-xs`"
129
+ :aria-label="selectedCountry?.name"
130
+ left
125
131
  />
126
- <label class="selected-code"> {{ selectedCountry.code }}</label>
132
+ <label class="selected-code">{{ selectedCountry?.code }}</label>
127
133
  </template>
128
134
 
129
135
  <q-list class="u-list">
130
136
  <q-item
131
- v-for="country in options"
132
- :key="country.code"
133
- clickable
134
137
  v-close-popup
138
+ v-for="country in options"
135
139
  v-ripple
136
- @click="selectCountry(country)"
137
140
  class="q-my-xxs"
141
+ clickable
142
+ :key="country?.code"
143
+ @click="selectCountry(country)"
138
144
  >
139
145
  <q-item-section class="flag-section">
140
146
  <q-icon
141
- :aria-label="country.name"
147
+ :class="`fi fi-${toLowerCase(country?.flag)} flag-icon q-mr-xs`"
148
+ :aria-label="country?.name"
142
149
  left
143
- :class="`fi fi-${toLowerCase(country.flag)} flag-icon q-mr-xs`"
144
150
  size="1.25rem"
145
151
  />
146
152
  </q-item-section>
147
153
  <q-item-section>
148
154
  <q-item-label class="text-body-sm">
149
- {{ country.name }}
155
+ {{ country?.name }}
150
156
  </q-item-label>
151
157
  </q-item-section>
152
158
  </q-item>
@@ -232,7 +238,6 @@ const toLowerCase = (str) => str.toLowerCase()
232
238
  .phone-input
233
239
  .q-field__inner
234
240
  border-radius: $xs
235
- background: $neutral-1
236
241
  &.q-field--borderless
237
242
  .q-field__control
238
243
  padding: 0 $xs 0 0