@citizenplane/pimp 9.7.1 → 9.7.2
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/dist/pimp.es.js +11116 -7375
- package/dist/pimp.umd.js +22 -18
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CpTelInput.vue +102 -12
- package/src/components/index.ts +3 -0
package/package.json
CHANGED
|
@@ -6,19 +6,24 @@
|
|
|
6
6
|
<div class="cpTelInput__container">
|
|
7
7
|
<vue-tel-input
|
|
8
8
|
ref="telInputRef"
|
|
9
|
-
v-model="
|
|
9
|
+
v-model="inputModel"
|
|
10
10
|
class="cpTelInput__wrapper"
|
|
11
11
|
:class="wrapperDynamicClasses"
|
|
12
12
|
:disabled
|
|
13
|
+
:dropdown-options
|
|
13
14
|
:input-options
|
|
14
15
|
mode="international"
|
|
15
16
|
placeholder="Enter your phone number"
|
|
16
17
|
valid-characters-only
|
|
17
|
-
@
|
|
18
|
+
@close="focusOnInput"
|
|
19
|
+
@open="handleDropdownOpen"
|
|
18
20
|
>
|
|
19
21
|
<template #arrow-icon>
|
|
20
22
|
<cp-icon class="cpTelInput__arrow" size="20" type="chevron-down" />
|
|
21
23
|
</template>
|
|
24
|
+
<template #search-icon>
|
|
25
|
+
<cp-icon class="cpTelInput__searchIcon" size="20" type="search" />
|
|
26
|
+
</template>
|
|
22
27
|
</vue-tel-input>
|
|
23
28
|
</div>
|
|
24
29
|
<transition-expand mode="out-in">
|
|
@@ -33,7 +38,7 @@
|
|
|
33
38
|
</template>
|
|
34
39
|
|
|
35
40
|
<script setup lang="ts">
|
|
36
|
-
import { useAttrs, ref, useId, computed,
|
|
41
|
+
import { useAttrs, ref, useId, computed, nextTick } from 'vue'
|
|
37
42
|
|
|
38
43
|
import BaseInputLabel from '@/components/BaseInputLabel.vue'
|
|
39
44
|
|
|
@@ -44,8 +49,10 @@ interface Props {
|
|
|
44
49
|
disabled?: boolean
|
|
45
50
|
errorMessage?: string
|
|
46
51
|
help?: string
|
|
52
|
+
hideSearch?: boolean
|
|
47
53
|
isInvalid?: boolean
|
|
48
54
|
label?: string
|
|
55
|
+
name?: string
|
|
49
56
|
placeholder?: string
|
|
50
57
|
required?: boolean
|
|
51
58
|
size?: Sizes
|
|
@@ -61,10 +68,13 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
61
68
|
isInvalid: false,
|
|
62
69
|
required: false,
|
|
63
70
|
tooltip: '',
|
|
71
|
+
name: '',
|
|
72
|
+
hideSearch: false,
|
|
64
73
|
size: Sizes.MD,
|
|
65
74
|
})
|
|
66
75
|
|
|
67
|
-
const
|
|
76
|
+
const inputModel = defineModel<string>()
|
|
77
|
+
const telInputRef = ref<HTMLInputElement | null>(null)
|
|
68
78
|
|
|
69
79
|
const helpMessageId = useId()
|
|
70
80
|
const errorMessageId = useId()
|
|
@@ -78,9 +88,17 @@ const wrapperDynamicClasses = computed(() => ({
|
|
|
78
88
|
'cpTelInput__wrapper--isDisabled': props.disabled,
|
|
79
89
|
}))
|
|
80
90
|
|
|
91
|
+
const dropdownOptions = computed(() => ({
|
|
92
|
+
showSearchBox: !props.hideSearch,
|
|
93
|
+
showFlags: true,
|
|
94
|
+
tabindex: 0,
|
|
95
|
+
searchBoxPlaceholder: 'Search country...',
|
|
96
|
+
}))
|
|
97
|
+
|
|
81
98
|
const inputOptions = computed(() => ({
|
|
82
99
|
autofocus: true,
|
|
83
100
|
placeholder: props.placeholder,
|
|
101
|
+
name: props.name,
|
|
84
102
|
styleClasses: {
|
|
85
103
|
cpTelInput__input: true,
|
|
86
104
|
'cpTelInput__input--isInvalid': props.isInvalid,
|
|
@@ -88,8 +106,6 @@ const inputOptions = computed(() => ({
|
|
|
88
106
|
},
|
|
89
107
|
}))
|
|
90
108
|
|
|
91
|
-
const telModel = defineModel<string>('telModel')
|
|
92
|
-
|
|
93
109
|
const inputIdentifier = ref<string>((attrs.id as string | undefined) || useId())
|
|
94
110
|
|
|
95
111
|
const capitalizedLabel = computed(() => capitalizeFirstLetter(props.label))
|
|
@@ -98,9 +114,19 @@ const displayErrorMessage = computed(() => props.isInvalid && props.errorMessage
|
|
|
98
114
|
|
|
99
115
|
const displayHelp = computed(() => props.help?.length && !displayErrorMessage.value)
|
|
100
116
|
|
|
101
|
-
const focusOnInput = () => {
|
|
117
|
+
const focusOnInput = async () => {
|
|
118
|
+
if (!telInputRef.value) return
|
|
119
|
+
setTimeout(() => telInputRef.value?.focus(), 1)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const handleDropdownOpen = async () => {
|
|
102
123
|
if (!telInputRef.value) return
|
|
103
|
-
|
|
124
|
+
await nextTick()
|
|
125
|
+
|
|
126
|
+
const searchBox = telInputRef.value?.$el?.querySelector('input.vti__search_box')
|
|
127
|
+
if (!searchBox) return
|
|
128
|
+
|
|
129
|
+
setTimeout(() => searchBox.focus(), 1)
|
|
104
130
|
}
|
|
105
131
|
</script>
|
|
106
132
|
|
|
@@ -115,7 +141,7 @@ const focusOnInput = () => {
|
|
|
115
141
|
}
|
|
116
142
|
|
|
117
143
|
&__container {
|
|
118
|
-
z-index:
|
|
144
|
+
z-index: 9;
|
|
119
145
|
position: relative;
|
|
120
146
|
display: flex;
|
|
121
147
|
}
|
|
@@ -183,7 +209,8 @@ const focusOnInput = () => {
|
|
|
183
209
|
}
|
|
184
210
|
}
|
|
185
211
|
|
|
186
|
-
&__arrow
|
|
212
|
+
&__arrow,
|
|
213
|
+
&__searchIcon {
|
|
187
214
|
color: colors.$neutral-dark-1;
|
|
188
215
|
transition: transform 150ms ease;
|
|
189
216
|
}
|
|
@@ -199,6 +226,7 @@ const focusOnInput = () => {
|
|
|
199
226
|
|
|
200
227
|
&:focus,
|
|
201
228
|
&:focus-within {
|
|
229
|
+
z-index: 2;
|
|
202
230
|
outline: fn.px-to-rem(2) solid colors.$primary-color;
|
|
203
231
|
}
|
|
204
232
|
}
|
|
@@ -239,21 +267,74 @@ const focusOnInput = () => {
|
|
|
239
267
|
border-top-left-radius: fn.px-to-rem(10);
|
|
240
268
|
}
|
|
241
269
|
|
|
242
|
-
.
|
|
270
|
+
.vti__search_box_container {
|
|
271
|
+
position: sticky;
|
|
272
|
+
top: 0;
|
|
273
|
+
display: flex;
|
|
274
|
+
margin-bottom: sp.$space-sm;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.vti__search_box {
|
|
278
|
+
box-shadow: 0 0 0 fn.px-to-rem(1) colors.$border-color;
|
|
279
|
+
appearance: none;
|
|
280
|
+
border-radius: fn.px-to-rem(6);
|
|
243
281
|
width: 100%;
|
|
282
|
+
color: inherit;
|
|
283
|
+
padding: sp.$space-sm sp.$space-sm sp.$space-sm sp.$space;
|
|
284
|
+
line-height: fn.px-to-rem(24);
|
|
285
|
+
font-size: fn.px-to-rem(14);
|
|
286
|
+
text-indent: fn.px-to-rem(28);
|
|
287
|
+
border: none;
|
|
288
|
+
|
|
289
|
+
&:hover {
|
|
290
|
+
box-shadow: 0 0 0 fn.px-to-rem(1) colors.$primary-color;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
&:focus {
|
|
294
|
+
outline: fn.px-to-rem(2) solid colors.$primary-color;
|
|
295
|
+
background-color: colors.$neutral-light;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
&::placeholder {
|
|
299
|
+
color: colors.$neutral-dark-1;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
&__searchIcon {
|
|
304
|
+
@include mx.square-sizing(16);
|
|
305
|
+
|
|
306
|
+
position: absolute;
|
|
307
|
+
top: 50%;
|
|
308
|
+
transform: translateY(-50%);
|
|
309
|
+
left: fn.px-to-rem(12);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.vti__dropdown-list {
|
|
313
|
+
clip-path: inset(0 round fn.px-to-rem(10));
|
|
314
|
+
max-height: fn.px-to-rem(130);
|
|
315
|
+
width: calc(100% + fn.px-to-rem(2));
|
|
244
316
|
padding: sp.$space-sm;
|
|
245
317
|
border-radius: fn.px-to-rem(10);
|
|
318
|
+
border: fn.px-to-rem(1) solid colors.$border-color;
|
|
319
|
+
|
|
320
|
+
&:has(.vti__search_box) {
|
|
321
|
+
max-height: fn.px-to-rem(170);
|
|
322
|
+
}
|
|
246
323
|
|
|
247
324
|
&.below {
|
|
248
325
|
top: fn.px-to-rem(40) + sp.$space;
|
|
249
326
|
}
|
|
327
|
+
|
|
328
|
+
&.above {
|
|
329
|
+
bottom: calc(100% + fn.px-to-rem(8));
|
|
330
|
+
}
|
|
250
331
|
}
|
|
251
332
|
|
|
252
333
|
.vti__dropdown-item {
|
|
253
334
|
padding: sp.$space-md sp.$space-lg sp.$space-md sp.$space-md;
|
|
254
335
|
display: flex;
|
|
255
336
|
align-items: flex-start;
|
|
256
|
-
border-radius: fn.px-to-rem(
|
|
337
|
+
border-radius: fn.px-to-rem(6);
|
|
257
338
|
font-size: fn.px-to-rem(14);
|
|
258
339
|
line-height: fn.px-to-rem(24);
|
|
259
340
|
|
|
@@ -287,6 +368,15 @@ const focusOnInput = () => {
|
|
|
287
368
|
padding: sp.$space-md sp.$space sp.$space-md sp.$space-md;
|
|
288
369
|
}
|
|
289
370
|
|
|
371
|
+
.vti__search_box {
|
|
372
|
+
padding: sp.$space sp.$space-lg;
|
|
373
|
+
text-indent: fn.px-to-rem(24);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.cpTelInput__searchIcon {
|
|
377
|
+
left: fn.px-to-rem(16);
|
|
378
|
+
}
|
|
379
|
+
|
|
290
380
|
.vti__dropdown-list.below {
|
|
291
381
|
top: fn.px-to-rem(48) + sp.$space;
|
|
292
382
|
}
|
package/src/components/index.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { vMaska } from 'maska/vue'
|
|
|
3
3
|
import PrimeVue from 'primevue/config'
|
|
4
4
|
import { App } from 'vue'
|
|
5
5
|
import { BindOnceDirective } from 'vue-bind-once'
|
|
6
|
+
import VueTelInput from 'vue-tel-input'
|
|
7
|
+
import 'vue-tel-input/vue-tel-input.css'
|
|
6
8
|
|
|
7
9
|
import ClickOutside from '../directives/ClickOutside'
|
|
8
10
|
import CpCoreDatepicker from '../libs/CoreDatepicker.vue'
|
|
@@ -93,6 +95,7 @@ const Components = {
|
|
|
93
95
|
const Pimp = {
|
|
94
96
|
install(app: App, options: Record<string, unknown>) {
|
|
95
97
|
app.use(PrimeVue, { unstyled: true })
|
|
98
|
+
app.use(VueTelInput)
|
|
96
99
|
|
|
97
100
|
Object.keys(Components).forEach((name) => {
|
|
98
101
|
app.component(name, Components[name as keyof typeof Components])
|