@sbc-connect/nuxt-forms 0.1.8 → 0.1.10
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/.env.example +10 -0
- package/CHANGELOG.md +20 -0
- package/app/components/Connect/ButtonControl/Buttons.vue +19 -0
- package/app/components/Connect/ButtonControl/Index.vue +59 -0
- package/app/components/Connect/ButtonControl/Wrapper.vue +10 -0
- package/app/components/Connect/Fieldset.vue +41 -0
- package/app/components/Connect/Form/Address/City.vue +20 -0
- package/app/components/Connect/Form/Address/Country.vue +94 -0
- package/app/components/Connect/Form/Address/DeliveryInstructions.vue +21 -0
- package/app/components/Connect/Form/Address/PostalCode.vue +37 -0
- package/app/components/Connect/Form/Address/Region.vue +107 -0
- package/app/components/Connect/Form/Address/Street.vue +52 -0
- package/app/components/Connect/Form/Address/StreetAdditional.vue +19 -0
- package/app/components/Connect/Form/Address/index.vue +112 -0
- package/app/components/Connect/Form/Input.vue +39 -0
- package/app/components/Connect/Form/Textarea.vue +38 -0
- package/app/components/Connect/Layout/Form.vue +22 -0
- package/app/components/HelloWorld/Forms.vue +2 -2
- package/app/composables/useButtonControl.ts +72 -0
- package/app/interfaces/connect-button-control.ts +17 -0
- package/app/layouts/ConnectForm.vue +5 -0
- package/app/types/forms-page-meta.d.ts +7 -0
- package/app/utils/isoCountriesList.ts +2036 -0
- package/i18n/locales/en-CA.ts +38 -0
- package/i18n/locales/fr-CA.ts +3 -0
- package/modules/form-assets/index.ts +15 -0
- package/modules/form-assets/runtime/assets/connect-form-tw.css +2 -0
- package/nuxt.config.ts +23 -2
- package/package.json +6 -6
- package/app/assets/css/tw-forms.css +0 -2
package/.env.example
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
+
# Web Urls
|
|
1
2
|
NUXT_PUBLIC_BASE_URL="http://localhost:3000/"
|
|
3
|
+
NUXT_PUBLIC_REGISTRY_HOME_URL="https://dev.bcregistry.gov.bc.ca/"
|
|
4
|
+
|
|
5
|
+
# API Urls
|
|
6
|
+
# Status API
|
|
7
|
+
NUXT_PUBLIC_STATUS_API_URL="https://status-api-dev.apps.gold.devops.gov.bc.ca"
|
|
8
|
+
NUXT_PUBLIC_STATUS_API_VERSION="/api/v1"
|
|
9
|
+
|
|
10
|
+
# LaunchDarkly
|
|
11
|
+
NUXT_PUBLIC_LD_CLIENT_ID=""
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @sbc-connect/nuxt-forms
|
|
2
2
|
|
|
3
|
+
## 0.1.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#43](https://github.com/bcgov/connect-nuxt/pull/43) [`3b521b7`](https://github.com/bcgov/connect-nuxt/commit/3b521b70bf1a0cc5a0feea63a825ef5544347aa8) Thanks [@deetz99](https://github.com/deetz99)! - Form components and new lint rules
|
|
8
|
+
|
|
9
|
+
- Forms layer address components
|
|
10
|
+
- Lint rules and fixes to prevent rule collision and promote best practices
|
|
11
|
+
|
|
12
|
+
issue: bcgov/entity#29338
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [[`3b521b7`](https://github.com/bcgov/connect-nuxt/commit/3b521b70bf1a0cc5a0feea63a825ef5544347aa8)]:
|
|
15
|
+
- @sbc-connect/nuxt-base@0.1.9
|
|
16
|
+
|
|
17
|
+
## 0.1.9
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#37](https://github.com/bcgov/connect-nuxt/pull/37) [`216dff5`](https://github.com/bcgov/connect-nuxt/commit/216dff5eea1cf8459fc516dc8a1985f922e84533) Thanks [@kialj876](https://github.com/kialj876)! - Button Control Component and Form Layout bcgov/entity/29338
|
|
22
|
+
|
|
3
23
|
## 0.1.8
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
defineProps<{ buttons: ConnectButton[], position: 'left' | 'right' }>()
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div
|
|
7
|
+
v-for="(button, i) in buttons"
|
|
8
|
+
:key="`${position}-button-` + i"
|
|
9
|
+
data-testid="button-wrapper"
|
|
10
|
+
>
|
|
11
|
+
<UButton
|
|
12
|
+
class="max-w-fit px-7 py-3 mb-1"
|
|
13
|
+
v-bind="button"
|
|
14
|
+
/>
|
|
15
|
+
<p :class="['text-center', !button.removeAlertSpacing ? 'h-[1.25rem]' : '']">
|
|
16
|
+
<span v-if="button.alertText" class="text-error">{{ button.alertText }}</span>
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const buttonControl = computed(() => useRoute().meta.buttonControl as ConnectButtonControl)
|
|
3
|
+
const leftGroup = computed(() => buttonControl.value?.leftGroup || [])
|
|
4
|
+
const rightGroup = computed(() => buttonControl.value?.rightGroup || [])
|
|
5
|
+
const leftAlertText = computed(() => buttonControl.value?.leftGroup.alertText || undefined)
|
|
6
|
+
const rightAlertText = computed(() => buttonControl.value?.rightGroup.alertText || undefined)
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div
|
|
11
|
+
class="@container"
|
|
12
|
+
data-testid="connect-button-control"
|
|
13
|
+
>
|
|
14
|
+
<div class="grid grid-cols-1 gap-4 @3xl:grid-cols-2">
|
|
15
|
+
<div>
|
|
16
|
+
<div
|
|
17
|
+
class="flex justify-center @3xl:justify-start"
|
|
18
|
+
data-testid="left-buttons"
|
|
19
|
+
>
|
|
20
|
+
<div
|
|
21
|
+
class="relative flex flex-col flex-wrap gap-4 justify-center"
|
|
22
|
+
:class="leftGroup.stacked ? '' : 'flex-row'"
|
|
23
|
+
>
|
|
24
|
+
<div
|
|
25
|
+
v-if="leftAlertText"
|
|
26
|
+
class="absolute flex flex-wrap justify-start bottom-1/3 right-[-13rem] w-[12rem]"
|
|
27
|
+
>
|
|
28
|
+
<p class="text-error" role="alert">
|
|
29
|
+
{{ leftAlertText }}
|
|
30
|
+
</p>
|
|
31
|
+
</div>
|
|
32
|
+
<ConnectButtonControlButtons :buttons="leftGroup.buttons" :position="'left'" />
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div>
|
|
37
|
+
<div
|
|
38
|
+
class="flex justify-center @3xl:justify-end"
|
|
39
|
+
data-testid="right-buttons"
|
|
40
|
+
>
|
|
41
|
+
<div
|
|
42
|
+
class="relative flex flex-col flex-wrap gap-4 justify-center"
|
|
43
|
+
:class="rightGroup.stacked ? '' : 'flex-row'"
|
|
44
|
+
>
|
|
45
|
+
<div
|
|
46
|
+
v-if="rightAlertText"
|
|
47
|
+
class="absolute flex flex-wrap justify-end bottom-1/3 left-[-13rem] w-[12rem]"
|
|
48
|
+
>
|
|
49
|
+
<p class="text-error" role="alert">
|
|
50
|
+
{{ rightAlertText }}
|
|
51
|
+
</p>
|
|
52
|
+
</div>
|
|
53
|
+
<ConnectButtonControlButtons :buttons="rightGroup.buttons" :position="'right'" />
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</template>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { FormError } from '@nuxt/ui'
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
orientation = 'vertical'
|
|
6
|
+
} = defineProps<{
|
|
7
|
+
label: string
|
|
8
|
+
error?: FormError
|
|
9
|
+
showErrorMsg?: boolean
|
|
10
|
+
orientation?: 'vertical' | 'horizontal'
|
|
11
|
+
}>()
|
|
12
|
+
// TODO: figure out why text-error doesnt work on the legend text
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<fieldset
|
|
17
|
+
class="flex"
|
|
18
|
+
:class="[orientation === 'horizontal' ? 'flex-col gap-6 sm:flex-row sm:gap-4' : 'flex-col gap-6']"
|
|
19
|
+
>
|
|
20
|
+
<div :class="{ 'w-full sm:w-1/4': orientation === 'horizontal' }">
|
|
21
|
+
<legend
|
|
22
|
+
class="text-base text-neutral-highlighted font-bold"
|
|
23
|
+
:class="{ 'text-red-600': !!error }"
|
|
24
|
+
>
|
|
25
|
+
<div class="flex flex-wrap gap-4">
|
|
26
|
+
<span>{{ label }}</span>
|
|
27
|
+
<span
|
|
28
|
+
v-if="!!error && showErrorMsg"
|
|
29
|
+
class="font-normal"
|
|
30
|
+
>
|
|
31
|
+
{{ error.message }}
|
|
32
|
+
</span>
|
|
33
|
+
</div>
|
|
34
|
+
</legend>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="flex-1">
|
|
38
|
+
<slot />
|
|
39
|
+
</div>
|
|
40
|
+
</fieldset>
|
|
41
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
id: string
|
|
4
|
+
schemaPrefix: string
|
|
5
|
+
}>()
|
|
6
|
+
|
|
7
|
+
const model = defineModel<string>({ default: '' })
|
|
8
|
+
|
|
9
|
+
const inputId = props.id + '-city'
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<ConnectFormInput
|
|
14
|
+
v-model="model"
|
|
15
|
+
:name="schemaPrefix + '.city'"
|
|
16
|
+
:input-id="inputId"
|
|
17
|
+
required
|
|
18
|
+
:label="$t('connect.label.city')"
|
|
19
|
+
/>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { iscCountriesListSortedByName as countries } from '#forms/app/utils/isoCountriesList'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
id: string
|
|
6
|
+
schemaPrefix: string
|
|
7
|
+
disabled?: boolean
|
|
8
|
+
}>()
|
|
9
|
+
|
|
10
|
+
defineEmits<{
|
|
11
|
+
change: []
|
|
12
|
+
}>()
|
|
13
|
+
|
|
14
|
+
const model = defineModel<string>({ default: '' })
|
|
15
|
+
|
|
16
|
+
const inputId = props.id + '-country'
|
|
17
|
+
|
|
18
|
+
const displayedCountryName = computed(() => {
|
|
19
|
+
if (model.value) {
|
|
20
|
+
const found = countries.find(c => c.alpha_2 === model.value)?.name
|
|
21
|
+
return found ?? ''
|
|
22
|
+
}
|
|
23
|
+
return ''
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const options = [
|
|
27
|
+
countries.find(c => c.alpha_2 === 'CA')!,
|
|
28
|
+
countries.find(c => c.alpha_2 === 'US')!,
|
|
29
|
+
...countries
|
|
30
|
+
]
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<UFormField
|
|
35
|
+
:name="schemaPrefix + '.country'"
|
|
36
|
+
class="grow"
|
|
37
|
+
>
|
|
38
|
+
<template #default="{ error }">
|
|
39
|
+
<USelect
|
|
40
|
+
:id="inputId"
|
|
41
|
+
v-model="model"
|
|
42
|
+
:data-testid="inputId"
|
|
43
|
+
:items="options"
|
|
44
|
+
value-key="alpha_2"
|
|
45
|
+
label-key="name"
|
|
46
|
+
class="w-full"
|
|
47
|
+
:class="error ? 'shadow-input-error ring-0' : ''"
|
|
48
|
+
:disabled
|
|
49
|
+
:aria-label="$t('connect.label.country')"
|
|
50
|
+
:aria-required="true"
|
|
51
|
+
:ui="{
|
|
52
|
+
base: error
|
|
53
|
+
? 'shadow-input-error focus:shadow-input-error data-[state=open]:shadow-input-error'
|
|
54
|
+
: '',
|
|
55
|
+
item: 'nth-2:border-b nth-2:border-gray-200',
|
|
56
|
+
itemTrailingIcon: 'hidden',
|
|
57
|
+
}"
|
|
58
|
+
@change="$emit('change')"
|
|
59
|
+
>
|
|
60
|
+
<template #default="{ modelValue }">
|
|
61
|
+
<div class="relative px-2.5 pb-2 pt-6 w-full">
|
|
62
|
+
<span
|
|
63
|
+
aria-hidden="true"
|
|
64
|
+
:class="[
|
|
65
|
+
!modelValue
|
|
66
|
+
? 'top-1/2 -translate-y-1/2'
|
|
67
|
+
: 'top-1 -translate-y-none text-xs',
|
|
68
|
+
error
|
|
69
|
+
? 'text-red-600'
|
|
70
|
+
: '',
|
|
71
|
+
'absolute left-0 px-2.5 text-sm transition-all',
|
|
72
|
+
'group-data-[state=open]:text-primary group-focus:text-primary',
|
|
73
|
+
]"
|
|
74
|
+
>
|
|
75
|
+
{{ $t('connect.label.country') }}
|
|
76
|
+
</span>
|
|
77
|
+
<div class="h-6">
|
|
78
|
+
<span
|
|
79
|
+
v-if="modelValue"
|
|
80
|
+
class="line-clamp-1 text-left"
|
|
81
|
+
>
|
|
82
|
+
{{ displayedCountryName }}
|
|
83
|
+
</span>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</template>
|
|
87
|
+
</USelect>
|
|
88
|
+
<div
|
|
89
|
+
v-if="!$slots.help && !error"
|
|
90
|
+
class="h-4 mt-1"
|
|
91
|
+
/>
|
|
92
|
+
</template>
|
|
93
|
+
</UFormField>
|
|
94
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
id: string
|
|
4
|
+
schemaPrefix: string
|
|
5
|
+
disabled?: boolean
|
|
6
|
+
}>()
|
|
7
|
+
|
|
8
|
+
const model = defineModel<string>({ default: '' })
|
|
9
|
+
|
|
10
|
+
const inputId = props.id + '-locationDescription'
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<ConnectFormTextarea
|
|
15
|
+
v-model="model"
|
|
16
|
+
:input-id="inputId"
|
|
17
|
+
:name="schemaPrefix + '.locationDescription'"
|
|
18
|
+
:disabled
|
|
19
|
+
:label="$t('connect.label.deliveryInstructionsOpt')"
|
|
20
|
+
/>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
id: string
|
|
4
|
+
schemaPrefix: string
|
|
5
|
+
disabled?: boolean
|
|
6
|
+
country?: string
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const model = defineModel({
|
|
10
|
+
set(value) {
|
|
11
|
+
return value.toUpperCase()
|
|
12
|
+
},
|
|
13
|
+
type: String,
|
|
14
|
+
default: ''
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const inputId = props.id + '-postalCode'
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<ConnectFormInput
|
|
22
|
+
v-model="model"
|
|
23
|
+
:name="schemaPrefix + '.postalCode'"
|
|
24
|
+
:input-id="inputId"
|
|
25
|
+
:disabled
|
|
26
|
+
required
|
|
27
|
+
:label="country === 'US'
|
|
28
|
+
? $t('connect.label.zipCode')
|
|
29
|
+
: $t('connect.label.postalCode')
|
|
30
|
+
"
|
|
31
|
+
:mask="country === 'CA'
|
|
32
|
+
? 'V#@ #@#'
|
|
33
|
+
: country === 'US'
|
|
34
|
+
? '#####-####'
|
|
35
|
+
: undefined"
|
|
36
|
+
/>
|
|
37
|
+
</template>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const {
|
|
3
|
+
maxlength = '1000',
|
|
4
|
+
country,
|
|
5
|
+
id
|
|
6
|
+
} = defineProps<{
|
|
7
|
+
id: string
|
|
8
|
+
country?: string
|
|
9
|
+
schemaPrefix: string
|
|
10
|
+
disabled?: boolean
|
|
11
|
+
maxlength?: string
|
|
12
|
+
help?: string
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const model = defineModel<string>({ default: '' })
|
|
16
|
+
|
|
17
|
+
const regions = computed(() => {
|
|
18
|
+
switch (country) {
|
|
19
|
+
case 'US':
|
|
20
|
+
return countrySubdivisions.us
|
|
21
|
+
case 'CA':
|
|
22
|
+
return countrySubdivisions.ca
|
|
23
|
+
default:
|
|
24
|
+
return []
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const displayedRegionName = computed(() => {
|
|
29
|
+
if (model.value) {
|
|
30
|
+
const found = regions.value.find(r => r.code === model.value)?.name
|
|
31
|
+
return found ?? ''
|
|
32
|
+
}
|
|
33
|
+
return ''
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const inputId = id + '-region'
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<UFormField
|
|
41
|
+
:name="schemaPrefix + '.region'"
|
|
42
|
+
class="grow flex-1"
|
|
43
|
+
>
|
|
44
|
+
<template #default="{ error }">
|
|
45
|
+
<USelect
|
|
46
|
+
v-if="country === 'US' || country === 'CA'"
|
|
47
|
+
:id="inputId"
|
|
48
|
+
v-model="model"
|
|
49
|
+
:data-testid="inputId"
|
|
50
|
+
:items="regions"
|
|
51
|
+
:aria-label="country === 'CA' ? $t('connect.label.province') : $t('connect.label.state')"
|
|
52
|
+
value-key="code"
|
|
53
|
+
label-key="name"
|
|
54
|
+
:aria-required="true"
|
|
55
|
+
:disabled
|
|
56
|
+
class="w-full grow ring-0"
|
|
57
|
+
:ui="{
|
|
58
|
+
base: error
|
|
59
|
+
? 'shadow-input-error focus:shadow-input-error data-[state=open]:shadow-input-error'
|
|
60
|
+
: '',
|
|
61
|
+
}"
|
|
62
|
+
>
|
|
63
|
+
<template #default="{ modelValue }">
|
|
64
|
+
<div class="relative px-2.5 pb-2 pt-6 w-full">
|
|
65
|
+
<span
|
|
66
|
+
aria-hidden="true"
|
|
67
|
+
class="absolute left-0 px-2.5 text-sm transition-all"
|
|
68
|
+
:class="[
|
|
69
|
+
!modelValue
|
|
70
|
+
? 'top-1/2 -translate-y-1/2'
|
|
71
|
+
: 'top-1 -translate-y-none text-xs',
|
|
72
|
+
error
|
|
73
|
+
? 'text-error'
|
|
74
|
+
: '',
|
|
75
|
+
'absolute left-0 px-2.5 text-sm transition-all',
|
|
76
|
+
'group-data-[state=open]:text-primary group-focus:text-primary',
|
|
77
|
+
]"
|
|
78
|
+
>
|
|
79
|
+
{{ country === 'CA' ? $t('connect.label.province') : $t('connect.label.state') }}
|
|
80
|
+
</span>
|
|
81
|
+
<div class="h-6">
|
|
82
|
+
<span
|
|
83
|
+
v-if="modelValue"
|
|
84
|
+
class="line-clamp-1 text-left"
|
|
85
|
+
>
|
|
86
|
+
{{ displayedRegionName }}
|
|
87
|
+
</span>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</template>
|
|
91
|
+
</USelect>
|
|
92
|
+
<ConnectInput
|
|
93
|
+
v-else
|
|
94
|
+
:id="inputId"
|
|
95
|
+
v-model="model"
|
|
96
|
+
:invalid="!!error"
|
|
97
|
+
:disabled
|
|
98
|
+
:label="$t('connect.label.regionOpt')"
|
|
99
|
+
:maxlength
|
|
100
|
+
/>
|
|
101
|
+
<div
|
|
102
|
+
v-if="!help && !error"
|
|
103
|
+
class="h-4 mt-1"
|
|
104
|
+
/>
|
|
105
|
+
</template>
|
|
106
|
+
</UFormField>
|
|
107
|
+
</template>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const {
|
|
3
|
+
id,
|
|
4
|
+
schemaPrefix,
|
|
5
|
+
helpText = 'none'
|
|
6
|
+
} = defineProps<{
|
|
7
|
+
id: string
|
|
8
|
+
// country?: string
|
|
9
|
+
schemaPrefix: string
|
|
10
|
+
// disableAddressComplete?: boolean
|
|
11
|
+
helpText?: 'allow-po' | 'no-po' | 'none'
|
|
12
|
+
}>()
|
|
13
|
+
|
|
14
|
+
const model = defineModel<string>({ default: '' })
|
|
15
|
+
|
|
16
|
+
// TODO: add address complete, and address complete disable options
|
|
17
|
+
// const emit = defineEmits<{
|
|
18
|
+
// addressComplete: [value: ConnectAddress]
|
|
19
|
+
// }>()
|
|
20
|
+
|
|
21
|
+
const inputId = id + '-street'
|
|
22
|
+
|
|
23
|
+
// const { address: canadaPostAddress, enableAddressComplete } = useCanadaPost()
|
|
24
|
+
|
|
25
|
+
// const addressComplete = (id: string) => {
|
|
26
|
+
// if (props.country && props.country.trim() !== '') {
|
|
27
|
+
// enableAddressComplete(id, props.country, props.disableAddressComplete)
|
|
28
|
+
// }
|
|
29
|
+
// }
|
|
30
|
+
|
|
31
|
+
// watch(canadaPostAddress, (newAddress) => {
|
|
32
|
+
// emit('addressComplete', newAddress)
|
|
33
|
+
// })
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<template>
|
|
37
|
+
<ConnectFormInput
|
|
38
|
+
v-model="model"
|
|
39
|
+
:input-id="inputId"
|
|
40
|
+
:name="schemaPrefix + '.street'"
|
|
41
|
+
:help="helpText === 'none'
|
|
42
|
+
? undefined
|
|
43
|
+
: helpText === 'no-po'
|
|
44
|
+
? $t('connect.text.addressCannotBePOBox')
|
|
45
|
+
: $t('connect.text.addressCanBePOBox')
|
|
46
|
+
"
|
|
47
|
+
:label="$t('connect.label.street')"
|
|
48
|
+
required
|
|
49
|
+
/>
|
|
50
|
+
<!-- @keypress.once="addressComplete(inputId)"
|
|
51
|
+
@click="addressComplete(inputId)" -->
|
|
52
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
id: string
|
|
4
|
+
schemaPrefix: string
|
|
5
|
+
}>()
|
|
6
|
+
|
|
7
|
+
const model = defineModel<string>({ default: '' })
|
|
8
|
+
|
|
9
|
+
const inputId = props.id + '-streetAdditional'
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<ConnectFormInput
|
|
14
|
+
v-model="model"
|
|
15
|
+
:name="schemaPrefix + '.streetAdditional'"
|
|
16
|
+
:input-id="inputId"
|
|
17
|
+
:label="$t('connect.label.streetAdditional')"
|
|
18
|
+
/>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const {
|
|
3
|
+
disabledFields,
|
|
4
|
+
excludedFields = ['streetName', 'streetNumber', 'unitNumber'],
|
|
5
|
+
schemaPrefix,
|
|
6
|
+
streetHelpText = 'none'
|
|
7
|
+
} = defineProps<{
|
|
8
|
+
id: string
|
|
9
|
+
schemaPrefix: string
|
|
10
|
+
disabledFields?: Array<keyof ConnectAddress>
|
|
11
|
+
excludedFields?: Array<keyof ConnectAddress>
|
|
12
|
+
disableAddressComplete?: boolean
|
|
13
|
+
streetHelpText?: 'allow-po' | 'no-po' | 'none'
|
|
14
|
+
}>()
|
|
15
|
+
|
|
16
|
+
const emit = defineEmits<{
|
|
17
|
+
shouldValidate: [keys: Array<keyof ConnectAddress>]
|
|
18
|
+
}>()
|
|
19
|
+
|
|
20
|
+
const state = defineModel<Partial<ConnectAddress>>({ required: true })
|
|
21
|
+
|
|
22
|
+
async function populateAddressComplete(e: ConnectAddress) {
|
|
23
|
+
// get disabled/excluded fields
|
|
24
|
+
const disabledSet = new Set(disabledFields)
|
|
25
|
+
const excludedSet = new Set(excludedFields)
|
|
26
|
+
|
|
27
|
+
// get array of valid keys
|
|
28
|
+
const validKeys = (Object.keys(e) as Array<keyof ConnectAddress>).filter(key =>
|
|
29
|
+
!disabledSet.has(key) && !excludedSet.has(key)
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
// set state for each valid key
|
|
33
|
+
validKeys.forEach((key) => {
|
|
34
|
+
state.value[key] = e[key]
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// wait for dom to populate inputs
|
|
38
|
+
await nextTick()
|
|
39
|
+
|
|
40
|
+
// emit valid keys to be validated by parent UForm
|
|
41
|
+
emit('shouldValidate', validKeys.map(k => schemaPrefix + k) as Array<keyof ConnectAddress>)
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<div class="space-y-2" :data-testid="id">
|
|
47
|
+
<ConnectFormAddressCountry
|
|
48
|
+
v-if="!excludedFields.includes('country')"
|
|
49
|
+
:id
|
|
50
|
+
v-model="state.country"
|
|
51
|
+
:schema-prefix="schemaPrefix"
|
|
52
|
+
:disabled="disabledFields?.includes('country')"
|
|
53
|
+
@change="state.region = ''"
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
<ConnectFormAddressStreet
|
|
57
|
+
v-if="!excludedFields.includes('street')"
|
|
58
|
+
:id
|
|
59
|
+
v-model="state.street"
|
|
60
|
+
:schema-prefix="schemaPrefix"
|
|
61
|
+
:country="state.country"
|
|
62
|
+
:disable-address-complete="disableAddressComplete"
|
|
63
|
+
:disabled="disabledFields?.includes('street')"
|
|
64
|
+
:help-text="streetHelpText"
|
|
65
|
+
@address-complete="populateAddressComplete"
|
|
66
|
+
/>
|
|
67
|
+
|
|
68
|
+
<ConnectFormAddressStreetAdditional
|
|
69
|
+
v-if="!excludedFields.includes('streetAdditional')"
|
|
70
|
+
:id
|
|
71
|
+
v-model="state.streetAdditional"
|
|
72
|
+
:schema-prefix="schemaPrefix"
|
|
73
|
+
:disabled="disabledFields?.includes('streetAdditional')"
|
|
74
|
+
/>
|
|
75
|
+
|
|
76
|
+
<div class="flex flex-col gap-2 sm:gap-4 sm:flex-row">
|
|
77
|
+
<ConnectFormAddressCity
|
|
78
|
+
v-if="!excludedFields.includes('city')"
|
|
79
|
+
:id
|
|
80
|
+
v-model="state.city"
|
|
81
|
+
:schema-prefix="schemaPrefix"
|
|
82
|
+
:disabled="disabledFields?.includes('city')"
|
|
83
|
+
/>
|
|
84
|
+
|
|
85
|
+
<ConnectFormAddressRegion
|
|
86
|
+
v-if="!excludedFields.includes('region')"
|
|
87
|
+
:id
|
|
88
|
+
v-model="state.region"
|
|
89
|
+
:schema-prefix="schemaPrefix"
|
|
90
|
+
:country="state.country"
|
|
91
|
+
:disabled="disabledFields?.includes('region')"
|
|
92
|
+
/>
|
|
93
|
+
|
|
94
|
+
<ConnectFormAddressPostalCode
|
|
95
|
+
v-if="!excludedFields.includes('postalCode')"
|
|
96
|
+
:id
|
|
97
|
+
v-model="state.postalCode"
|
|
98
|
+
:schema-prefix="schemaPrefix"
|
|
99
|
+
:country="state.country"
|
|
100
|
+
:disabled="disabledFields?.includes('postalCode')"
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<ConnectFormAddressDeliveryInstructions
|
|
105
|
+
v-if="!excludedFields.includes('locationDescription')"
|
|
106
|
+
:id
|
|
107
|
+
v-model="state.locationDescription"
|
|
108
|
+
:schema-prefix="schemaPrefix"
|
|
109
|
+
:disabled="disabledFields?.includes('locationDescription')"
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
</template>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
defineProps<{
|
|
3
|
+
name: string
|
|
4
|
+
label: string
|
|
5
|
+
help?: string
|
|
6
|
+
inputId: string
|
|
7
|
+
required?: boolean
|
|
8
|
+
autofocus?: boolean
|
|
9
|
+
mask?: string
|
|
10
|
+
disabled?: boolean
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
const model = defineModel<string>({ required: true })
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<UFormField
|
|
18
|
+
:name
|
|
19
|
+
:help
|
|
20
|
+
class="grow flex-1"
|
|
21
|
+
>
|
|
22
|
+
<template #default="{ error }">
|
|
23
|
+
<ConnectInput
|
|
24
|
+
:id="inputId"
|
|
25
|
+
v-model="model"
|
|
26
|
+
:mask
|
|
27
|
+
:required
|
|
28
|
+
:invalid="!!error"
|
|
29
|
+
:label
|
|
30
|
+
:autofocus
|
|
31
|
+
:disabled
|
|
32
|
+
/>
|
|
33
|
+
<div
|
|
34
|
+
v-if="!help && !error"
|
|
35
|
+
class="h-4 mt-1"
|
|
36
|
+
/>
|
|
37
|
+
</template>
|
|
38
|
+
</UFormField>
|
|
39
|
+
</template>
|