PluginProbe
The Innovative Form Builder – IvyForms / 0.1.2
The Innovative Form Builder – IvyForms v0.1.2
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / input / IvyPhoneInput.vue

IvyPhoneInput.vue in The Innovative Form Builder – IvyForms 0.1.2, at frontend/src/views/_components/input/IvyPhoneInput.vue

417 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <MazPhoneNumberInput
3 v-model="localModelValue"
4 :class="['ivyforms-phone-input', { 'is-secondary': isSecondary }]"
5 v-bind="{ ...$props, ...$attrs }"
6 :fetch-country="fetchCountry"
7 label=""
8 show-code-on-list
9 :ignored-countries="['AC', 'GP', 'MF', 'CX', 'KN', 'WF', 'YT', 'RE', 'SH', 'PM']"
10 @blur="onBlur()"
11 >
12 <template #no-results>
13 <div
14 class="ivyforms-flex ivyforms-gap-8 ivyforms-flex-direction-column ivyforms-align-items-center ivyforms-px-16 ivyforms-py-8"
15 >
16 <span class="medium-14"> {{ getLabel('no_results_found_phone') }}</span>
17 <span class="regular-12 text-align-center">
18 {{ getLabel('adjusting_your_search_phone') }}
19 </span>
20 </div>
21 </template>
22 <template #selector-flag="{ countryCode: countryCode }">
23 <IvyIcon
24 class="selector__country-flag"
25 :category="'flags'"
26 size="d"
27 :name="getThreeLetterCode(countryCode)"
28 />
29 </template>
30 <template #country-list-flag="{ countryCode: countryCode }">
31 <IvyIcon
32 class="selector__country-flag"
33 :category="'flags'"
34 size="s"
35 :name="getThreeLetterCode(countryCode as string)"
36 />
37 </template>
38 </MazPhoneNumberInput>
39 </template>
40
41 <script setup lang="ts">
42 import MazPhoneNumberInput from 'maz-ui/components/MazPhoneNumberInput'
43 import { computed, inject, type StyleValue } from 'vue'
44 import 'maz-ui/styles'
45 import { countryMapper } from '@/constants/countries.ts'
46 import { useLabels } from '@/composables/useLabels'
47 const { getLabel } = useLabels()
48
49 interface Props {
50 modelValue?: string | undefined
51 fetchCountry?: boolean
52 noFlags?: boolean
53 style?: StyleValue
54 }
55
56 const props = withDefaults(defineProps<Props>(), {
57 fetchCountry: true,
58 modelValue: '',
59 style: null,
60 })
61
62 const emit = defineEmits(['update:modelValue', 'blur'])
63
64 const localModelValue = computed({
65 get() {
66 return props.modelValue
67 },
68 set(value) {
69 emit('update:modelValue', value)
70 },
71 })
72
73 const onBlur = () => {
74 emit('blur')
75 }
76
77 const getThreeLetterCode = (twoLetterCode: string) => {
78 return countryMapper[twoLetterCode.toUpperCase()] || null
79 }
80
81 const isSecondary = inject('isSecondary', false)
82 </script>
83
84 <style lang="scss">
85 // Phone Input
86 .ivyforms-phone-input {
87 // Moz Phone Number Input
88 &.m-phone-number-input {
89 flex-direction: row !important;
90 width: 100%;
91
92 // Hover
93 &:hover {
94 .m-phone-input,
95 .m-country-selector .m-select-input {
96 .m-input-wrapper {
97 border-color: var(--map-base-dusk-stroke-0) !important;
98 }
99 }
100 }
101
102 // Common Input (Country Selector & Phone Input)
103 .m-input {
104 height: 40px;
105
106 // Input Wrapper
107 .m-input-wrapper {
108 border-width: 1px;
109 border-color: var(--map-base-dusk-stroke--2);
110 border-radius: 8px;
111 background-color: var(--map-base-dusk-o05);
112
113 // Input Wrapper Input
114 .m-input-wrapper-input {
115 height: 38px;
116 input::placeholder {
117 color: var(--map-base-text-0);
118 opacity: 0.5;
119 }
120 // Native Input
121 input {
122 font-size: 16px;
123 font-style: normal;
124 font-weight: 400;
125 padding: 0 5px;
126 color: var(--map-base-text-0);
127 box-shadow: none;
128 outline: none;
129 }
130
131 // Input Label
132 .m-input-label {
133 display: none;
134 }
135 }
136 }
137
138 // Active & Focus
139 &.--is-active,
140 &.--is-focused,
141 &:focus-within {
142 .m-input-wrapper {
143 border-color: 1px solid var(--map-base-brand-fill-0) !important;
144 }
145
146 // Secondary
147 &.is-secondary {
148 .m-input-wrapper {
149 border: 1px solid var(--map-base-purple-stroke-0);
150 }
151 }
152 }
153
154 // Filled
155 &.--is-filled {
156 .m-input-wrapper {
157 border: 1px solid var(--map-base-dusk-stroke--2);
158 }
159 }
160 }
161
162 // Country Selector
163 .m-country-selector {
164 min-width: inherit !important;
165
166 // Select
167 .m-country-selector__select {
168 width: 54px !important;
169
170 // Input
171 .m-input {
172 // Select Input
173 &.m-select-input {
174 width: 64px;
175
176 // Input Wrapper
177 .m-input-wrapper {
178 border-bottom-left-radius: 8px;
179 border-top-left-radius: 8px;
180 border-right: none;
181
182 // Input Wrapper Input
183 .m-input-wrapper-input {
184 // Native Input
185 input {
186 width: 0;
187 padding: 0 !important;
188 }
189 }
190
191 // Arrow
192 .m-input-wrapper-right {
193 padding: 0;
194
195 // Button
196 button {
197 outline: none;
198 background: url('../../../assets/icons/arrows/line/chevron-down.svg') no-repeat
199 center;
200 background-size: contain;
201 width: 20px;
202 height: 20px;
203 cursor: pointer;
204 opacity: 1 !important;
205
206 svg {
207 display: none;
208 }
209 }
210 }
211 }
212 }
213
214 // Search Input
215 &.m-select-list__search-input {
216 padding: 0 8px 8px;
217 // Input Wrapper
218 .m-input-wrapper {
219 border-radius: 8px;
220
221 // Input Wrapper Left
222 .m-input-wrapper-left {
223 width: 24px;
224 box-sizing: content-box;
225 padding-left: 8px;
226
227 .maz-text-muted {
228 color: var(--map-base-text-0);
229 }
230
231 // Button
232 button {
233 outline: none;
234 background: url('../../../assets/icons/arrows/line/chevron-down.svg') no-repeat
235 center;
236 background-size: contain;
237 width: 20px;
238 height: 20px;
239 cursor: pointer;
240 opacity: 1 !important;
241 transform: rotate(180deg);
242
243 svg {
244 display: none;
245 }
246 }
247 }
248
249 // Input Wrapper Input
250 .m-input-wrapper-input {
251 height: 30px;
252
253 // Native Input
254 input {
255 cursor: text;
256 font-size: 16px;
257 font-style: normal;
258 font-weight: 400;
259
260 // Placeholder
261 &::placeholder {
262 color: var(--map-base-text--1);
263 }
264 }
265 }
266 }
267 }
268 }
269
270 // Open
271 &.--is-open {
272 // Arrow
273 .m-input-wrapper-right {
274 // Button
275 button {
276 transform: rotate(180deg);
277 }
278 }
279 }
280
281 // Popper
282 .m-select-list {
283 transform: translate(0, 4px) !important;
284 box-shadow: var(--shadow-100);
285 border-radius: 4px;
286 border: none;
287 background-color: var(--primitive-white);
288 min-width: 250px !important;
289 padding: 8px 0;
290
291 // Scroll Wrapper
292 .m-select-list__scroll-wrapper {
293 gap: 0;
294 margin-left: 4px;
295 @include scrollbar();
296
297 // Option
298 .m-select-list-item {
299 padding: 0 8px;
300 height: 36px;
301 overflow: hidden;
302 border-radius: 0;
303 cursor: pointer;
304 -webkit-tap-highlight-color: transparent;
305 color: var(--map-base-text-0);
306
307 // Hover & Keyboard Selected
308 &:hover,
309 &.--is-keyboard-selected {
310 background: var(--map-base-purple-o05) !important;
311 }
312
313 // Selected
314 &.--is-selected {
315 background: var(--map-base-purple-o05) !important;
316
317 // Item
318 .m-country-selector__select__item {
319 color: var(--map-base-purple-symbol-0) !important;
320
321 // Code
322 :nth-child(2) {
323 color: var(--map-base-purple-symbol-0) !important;
324 }
325 }
326 }
327
328 // Item
329 .m-country-selector__select__item {
330 gap: 8px;
331 font-size: 14px;
332 font-style: normal;
333 font-weight: 400;
334
335 // Code
336 :nth-child(2) {
337 order: 2;
338 text-align: right;
339 color: var(--map-base-text--2);
340 }
341
342 // Selected
343 .maz-font-semibold {
344 font-weight: 400;
345 }
346 }
347 }
348 }
349 }
350 }
351
352 // Flag
353 .m-country-selector__country-flag {
354 top: 50%;
355 transform: translateY(-50%);
356 bottom: unset;
357 height: 100%;
358 left: 0;
359 margin-left: 8px;
360 padding-right: 0;
361 max-height: 24px;
362 max-width: 24px;
363
364 // Icon
365 .ivyforms-icon {
366 pointer-events: none;
367 }
368 }
369 }
370
371 // Phone Input
372 .m-phone-input {
373 margin-top: 0 !important;
374 min-width: unset;
375 flex: 1 1 auto !important;
376 margin-left: 0;
377
378 // Input Wrapper
379 .m-input-wrapper {
380 width: 100%;
381 border-top-right-radius: 8px !important;
382 border-bottom-right-radius: 8px !important;
383 border-left: none;
384 }
385
386 // Focused
387 &.--is-focused:not(.--has-state) {
388 // Example
389 .m-input-label {
390 line-height: normal;
391 color: var(--map-base-text--1);
392 padding: 0;
393 transform: none;
394 display: flex;
395 font-size: 16px;
396 font-style: normal;
397 font-weight: 400;
398 left: 4px;
399 }
400 }
401 }
402
403 // Focus Within
404 &:focus-within {
405 // Phone Input & Country Selector Input
406 .m-phone-input,
407 .m-country-selector .m-select-input {
408 // Input Wrapper
409 .m-input-wrapper {
410 border-color: var(--map-base-dusk-stroke-0) !important;
411 }
412 }
413 }
414 }
415 }
416 </style>
417