js-kompo-utils 1.0.0
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/README.md +1 -0
- package/app.js +22 -0
- package/components/VlApexChart.vue +89 -0
- package/components/VlCKEditorTemplate.vue +52 -0
- package/components/VlCKEditorWithVars.vue +80 -0
- package/components/VlCollapsible.vue +91 -0
- package/components/VlCopyBox.vue +61 -0
- package/components/VlCreditCardInput.vue +104 -0
- package/components/VlDateMonthDay.vue +327 -0
- package/components/VlDateTextInput.vue +151 -0
- package/components/VlInternationalPhoneInput.vue +902 -0
- package/components/VlPartialDate.vue +283 -0
- package/components/VlPasswordInput.vue +358 -0
- package/components/VlQrCodeScanner.vue +91 -0
- package/components/VlSwipeableTab.vue +35 -0
- package/components/VlSwipeableTabs.vue +325 -0
- package/components/VlText.vue +72 -0
- package/components/VlTutorialStepBuilder.vue +671 -0
- package/components/VlValidatedInput.vue +262 -0
- package/components/data/countries.js +253 -0
- package/components/getAllDefaultComponents.js +12 -0
- package/docs/architecture.md +71 -0
- package/docs/tutorials.md +247 -0
- package/docs/usage.md +128 -0
- package/functions/index.js +7 -0
- package/functions/inputs.js +64 -0
- package/functions/loading.js +20 -0
- package/kompo-ckeditor-1.0.17/index.js +5 -0
- package/kompo-ckeditor-1.0.17/komponents/CKEditor.vue +36 -0
- package/kompo-ckeditor-1.0.17/komponents/CKEditorExtended.vue +66 -0
- package/kompo-ckeditor-1.0.17/komponents/EditableCKEditor.vue +42 -0
- package/kompo-ckeditor-1.0.17/komponents/TranslatableEditor.vue +28 -0
- package/kompo-ckeditor-1.0.17/mixins/CKEditor.js +291 -0
- package/kompo-ckeditor-1.0.17/mixins/CKEditorUtilities.js +52 -0
- package/kompo-ckeditor-1.0.17/mixins/CkUploadAdapter.js +95 -0
- package/kompo-ckeditor-1.0.17/mixins/translations/en.js +1 -0
- package/kompo-ckeditor-1.0.17/mixins/translations/fr.js +1 -0
- package/kompo-ckeditor-1.0.17/plugins/JsonBlockCommand.js +100 -0
- package/kompo-ckeditor-1.0.17/plugins/JsonBlockEditing.js +225 -0
- package/kompo-ckeditor-1.0.17/plugins/JsonBlockUi.js +21 -0
- package/kompo-ckeditor-1.0.17/plugins/MentionPlugin.js +118 -0
- package/orchestrator/KompoJsBuilder.js +333 -0
- package/package.json +25 -0
- package/raw_animations/count-up-animation.js +220 -0
- package/raw_animations/magic-poof.js +210 -0
- package/tutorials/TutorialConfig.js +34 -0
- package/tutorials/TutorialEngine.js +448 -0
- package/tutorials/index.js +2 -0
- package/tutorials/modules/AutoNext.js +86 -0
- package/tutorials/modules/Avatar.js +94 -0
- package/tutorials/modules/Bubble.js +617 -0
- package/tutorials/modules/Cursor.js +315 -0
- package/tutorials/modules/Highlight.js +282 -0
- package/tutorials/modules/HoverForcer.js +250 -0
- package/tutorials/modules/Mobile.js +148 -0
- package/tutorials/modules/Options.js +98 -0
- package/tutorials/modules/Overlay.js +142 -0
- package/tutorials/modules/Scroll.js +37 -0
- package/tutorials/modules/Typewriter.js +132 -0
- package/tutorials/step-builder/step-builder-bridge.js +436 -0
- package/tutorials/step-builder/utils/bezier-editor.js +379 -0
- package/tutorials/step-builder/utils/code-generator.js +127 -0
- package/tutorials/step-builder/utils/element-picker.js +125 -0
- package/tutorials/tutorial.scss +816 -0
- package/tutorials/utils/selectors.js +225 -0
- package/tutorials/utils/stability.js +76 -0
- package/tutorials/utils/svg.js +46 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<vl-form-field v-bind="$_wrapperAttributes">
|
|
3
|
+
<div class="vlInputGroup vlDateMonthDay">
|
|
4
|
+
<div class="vlInputPrepend" v-html="$_icon" />
|
|
5
|
+
|
|
6
|
+
<div class="vlDateMonthDay-selects">
|
|
7
|
+
<!-- First selector -->
|
|
8
|
+
<div class="vlDateMonthDay-select-wrapper">
|
|
9
|
+
<select
|
|
10
|
+
v-model="firstValue"
|
|
11
|
+
@change="updateValue"
|
|
12
|
+
class="vlDateMonthDay-select"
|
|
13
|
+
:disabled="$_readOnly"
|
|
14
|
+
>
|
|
15
|
+
<option value="" disabled>{{ firstPlaceholder }}</option>
|
|
16
|
+
<option v-for="opt in firstOptions" :key="opt.value" :value="opt.value">
|
|
17
|
+
{{ opt.label }}
|
|
18
|
+
</option>
|
|
19
|
+
</select>
|
|
20
|
+
<svg class="vlDateMonthDay-chevron" viewBox="0 0 20 20" fill="currentColor">
|
|
21
|
+
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
|
|
22
|
+
</svg>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<span class="vlDateMonthDay-separator">{{ $_separator }}</span>
|
|
26
|
+
|
|
27
|
+
<!-- Second selector -->
|
|
28
|
+
<div class="vlDateMonthDay-select-wrapper">
|
|
29
|
+
<select
|
|
30
|
+
v-model="secondValue"
|
|
31
|
+
@change="updateValue"
|
|
32
|
+
class="vlDateMonthDay-select"
|
|
33
|
+
:disabled="$_readOnly"
|
|
34
|
+
>
|
|
35
|
+
<option value="" disabled>{{ secondPlaceholder }}</option>
|
|
36
|
+
<option v-for="opt in secondOptions" :key="opt.value" :value="opt.value">
|
|
37
|
+
{{ opt.label }}
|
|
38
|
+
</option>
|
|
39
|
+
</select>
|
|
40
|
+
<svg class="vlDateMonthDay-chevron" viewBox="0 0 20 20" fill="currentColor">
|
|
41
|
+
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
|
|
42
|
+
</svg>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div class="vlInputAppend" v-if="!$_readOnly && hasValue">
|
|
47
|
+
<i class="icon-times cursor-pointer hover:text-red-500 transition-colors" @click.stop="clear" />
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</vl-form-field>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script>
|
|
54
|
+
import Field from 'vue-kompo/js/form/mixins/Field'
|
|
55
|
+
|
|
56
|
+
export default {
|
|
57
|
+
mixins: [Field],
|
|
58
|
+
data() {
|
|
59
|
+
return {
|
|
60
|
+
firstValue: '',
|
|
61
|
+
secondValue: ''
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
mounted() {
|
|
65
|
+
// Ensure component.value is empty string if nothing is selected initially
|
|
66
|
+
if (!this.component.value || this.component.value === 'null') {
|
|
67
|
+
this.component.value = '';
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
computed: {
|
|
71
|
+
$_mode() { return this.$_config('mode') || 'day-month' },
|
|
72
|
+
$_separator() { return this.$_config('separator') || '-' },
|
|
73
|
+
$_locale() { return this.$_config('kompo_locale') || 'en' },
|
|
74
|
+
$_yearStart() { return this.$_config('yearStart') || new Date().getFullYear() - 10 },
|
|
75
|
+
$_yearEnd() { return this.$_config('yearEnd') || new Date().getFullYear() + 10 },
|
|
76
|
+
|
|
77
|
+
hasValue() {
|
|
78
|
+
return this.firstValue && this.secondValue;
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
// Determine what the first and second selectors represent
|
|
82
|
+
firstType() {
|
|
83
|
+
const modes = {
|
|
84
|
+
'day-month': 'day',
|
|
85
|
+
'month-day': 'month',
|
|
86
|
+
'month-year': 'month',
|
|
87
|
+
'year-month': 'year'
|
|
88
|
+
};
|
|
89
|
+
return modes[this.$_mode] || 'day';
|
|
90
|
+
},
|
|
91
|
+
secondType() {
|
|
92
|
+
const modes = {
|
|
93
|
+
'day-month': 'month',
|
|
94
|
+
'month-day': 'day',
|
|
95
|
+
'month-year': 'year',
|
|
96
|
+
'year-month': 'month'
|
|
97
|
+
};
|
|
98
|
+
return modes[this.$_mode] || 'month';
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
// Placeholders
|
|
102
|
+
firstPlaceholder() {
|
|
103
|
+
return this.getPlaceholder(this.firstType);
|
|
104
|
+
},
|
|
105
|
+
secondPlaceholder() {
|
|
106
|
+
return this.getPlaceholder(this.secondType);
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
// Options for first selector
|
|
110
|
+
firstOptions() {
|
|
111
|
+
return this.getOptions(this.firstType);
|
|
112
|
+
},
|
|
113
|
+
// Options for second selector
|
|
114
|
+
secondOptions() {
|
|
115
|
+
return this.getOptions(this.secondType);
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// Days depend on selected month (if month is selected)
|
|
119
|
+
daysInMonth() {
|
|
120
|
+
let month = null;
|
|
121
|
+
if (this.firstType === 'month') month = this.firstValue;
|
|
122
|
+
if (this.secondType === 'month') month = this.secondValue;
|
|
123
|
+
|
|
124
|
+
if (month) {
|
|
125
|
+
return new Date(2024, month, 0).getDate(); // Use leap year for Feb
|
|
126
|
+
}
|
|
127
|
+
return 31;
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
months() {
|
|
131
|
+
const formatter = new Intl.DateTimeFormat(this.$_locale, { month: 'long' });
|
|
132
|
+
return Array.from({ length: 12 }, (_, i) => {
|
|
133
|
+
const date = new Date(2024, i, 1);
|
|
134
|
+
return {
|
|
135
|
+
value: i + 1,
|
|
136
|
+
label: formatter.format(date)
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
years() {
|
|
142
|
+
const years = [];
|
|
143
|
+
for (let y = this.$_yearStart; y <= this.$_yearEnd; y++) {
|
|
144
|
+
years.push({ value: y, label: String(y) });
|
|
145
|
+
}
|
|
146
|
+
return years;
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
days() {
|
|
150
|
+
return Array.from({ length: this.daysInMonth }, (_, i) => ({
|
|
151
|
+
value: i + 1,
|
|
152
|
+
label: this.padZero(i + 1)
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
watch: {
|
|
157
|
+
'component.value': {
|
|
158
|
+
immediate: true,
|
|
159
|
+
handler(value) {
|
|
160
|
+
this.parseValue(value);
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
// Adjust day if month changes and day exceeds days in month
|
|
164
|
+
secondValue(newVal) {
|
|
165
|
+
if (this.firstType === 'day' && this.secondType === 'month' && this.firstValue) {
|
|
166
|
+
const maxDays = new Date(2024, newVal, 0).getDate();
|
|
167
|
+
if (this.firstValue > maxDays) {
|
|
168
|
+
this.firstValue = maxDays;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
firstValue(newVal) {
|
|
173
|
+
if (this.firstType === 'month' && this.secondType === 'day' && this.secondValue) {
|
|
174
|
+
const maxDays = new Date(2024, newVal, 0).getDate();
|
|
175
|
+
if (this.secondValue > maxDays) {
|
|
176
|
+
this.secondValue = maxDays;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
methods: {
|
|
182
|
+
padZero(num) {
|
|
183
|
+
return String(num).padStart(2, '0');
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
getPlaceholder(type) {
|
|
187
|
+
const configKey = type + 'Placeholder';
|
|
188
|
+
const configured = this.$_config(configKey);
|
|
189
|
+
if (configured) return configured;
|
|
190
|
+
|
|
191
|
+
const defaults = {
|
|
192
|
+
day: 'DD',
|
|
193
|
+
month: 'MM',
|
|
194
|
+
year: 'YYYY'
|
|
195
|
+
};
|
|
196
|
+
return defaults[type] || '';
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
getOptions(type) {
|
|
200
|
+
switch (type) {
|
|
201
|
+
case 'day': return this.days;
|
|
202
|
+
case 'month': return this.months;
|
|
203
|
+
case 'year': return this.years;
|
|
204
|
+
default: return [];
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
parseValue(value) {
|
|
209
|
+
if (!value || value === '' || value === 'null') {
|
|
210
|
+
this.firstValue = '';
|
|
211
|
+
this.secondValue = '';
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const separator = this.$_separator;
|
|
216
|
+
const parts = value.split(separator);
|
|
217
|
+
|
|
218
|
+
if (parts.length === 2) {
|
|
219
|
+
this.firstValue = parseInt(parts[0], 10) || '';
|
|
220
|
+
this.secondValue = parseInt(parts[1], 10) || '';
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
formatValue(val, type) {
|
|
225
|
+
if (type === 'year') {
|
|
226
|
+
return String(val);
|
|
227
|
+
}
|
|
228
|
+
return this.padZero(val);
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
updateValue() {
|
|
232
|
+
if (this.firstValue && this.secondValue) {
|
|
233
|
+
const first = this.formatValue(this.firstValue, this.firstType);
|
|
234
|
+
const second = this.formatValue(this.secondValue, this.secondType);
|
|
235
|
+
this.component.value = `${first}${this.$_separator}${second}`;
|
|
236
|
+
} else if (!this.firstValue && !this.secondValue) {
|
|
237
|
+
this.component.value = '';
|
|
238
|
+
}
|
|
239
|
+
// Don't update if only one is selected (partial state)
|
|
240
|
+
|
|
241
|
+
this.$_changeAction();
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
clear() {
|
|
245
|
+
this.firstValue = '';
|
|
246
|
+
this.secondValue = '';
|
|
247
|
+
this.component.value = '';
|
|
248
|
+
this.$_changeAction();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
</script>
|
|
253
|
+
|
|
254
|
+
<style scoped>
|
|
255
|
+
.vlDateMonthDay {
|
|
256
|
+
display: flex;
|
|
257
|
+
align-items: center;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.vlDateMonthDay-selects {
|
|
261
|
+
display: flex;
|
|
262
|
+
align-items: center;
|
|
263
|
+
flex: 1;
|
|
264
|
+
gap: 0.25rem;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.vlDateMonthDay-select-wrapper {
|
|
268
|
+
position: relative;
|
|
269
|
+
flex: 1;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.vlDateMonthDay-select {
|
|
273
|
+
width: 100%;
|
|
274
|
+
appearance: none;
|
|
275
|
+
-webkit-appearance: none;
|
|
276
|
+
background-color: transparent;
|
|
277
|
+
border: none;
|
|
278
|
+
padding: 0.5rem 1.75rem 0.5rem 0.75rem;
|
|
279
|
+
font-size: 0.875rem;
|
|
280
|
+
cursor: pointer;
|
|
281
|
+
outline: none;
|
|
282
|
+
background-color: #f9fafb;
|
|
283
|
+
border-radius: 0.375rem;
|
|
284
|
+
transition: background-color 0.15s ease;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.vlDateMonthDay-select:hover:not(:disabled) {
|
|
288
|
+
background-color: #f3f4f6;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.vlDateMonthDay-select:focus {
|
|
292
|
+
background-color: #eff6ff;
|
|
293
|
+
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.vlDateMonthDay-select:disabled {
|
|
297
|
+
opacity: 0.6;
|
|
298
|
+
cursor: not-allowed;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.vlDateMonthDay-chevron {
|
|
302
|
+
position: absolute;
|
|
303
|
+
right: 0.5rem;
|
|
304
|
+
top: 50%;
|
|
305
|
+
transform: translateY(-50%);
|
|
306
|
+
width: 1rem;
|
|
307
|
+
height: 1rem;
|
|
308
|
+
color: #9ca3af;
|
|
309
|
+
pointer-events: none;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.vlDateMonthDay-separator {
|
|
313
|
+
color: #6b7280;
|
|
314
|
+
font-weight: 500;
|
|
315
|
+
padding: 0 0.25rem;
|
|
316
|
+
flex-shrink: 0;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* Style the options */
|
|
320
|
+
.vlDateMonthDay-select option {
|
|
321
|
+
padding: 0.5rem;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.vlDateMonthDay-select option:first-child {
|
|
325
|
+
color: #9ca3af;
|
|
326
|
+
}
|
|
327
|
+
</style>
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<vl-form-field v-bind="$_wrapperAttributes">
|
|
3
|
+
<div :class="'vlInputGroup rounded-lg ' + (showError ? invalidClass : '')">
|
|
4
|
+
<input
|
|
5
|
+
v-model="visualValue"
|
|
6
|
+
class="vlFormControl"
|
|
7
|
+
v-bind="$_attributes"
|
|
8
|
+
v-on="$_events"
|
|
9
|
+
:placeholder="formatDateStructure"
|
|
10
|
+
@input="onInputDateNumber"
|
|
11
|
+
@focus="onFocus"
|
|
12
|
+
@blur="focused = false"
|
|
13
|
+
ref="input"
|
|
14
|
+
/>
|
|
15
|
+
<div class="justify-center flex items-center px-4" v-if="showError">
|
|
16
|
+
<span class="invalid-icon">!</span>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</vl-form-field>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
import Field from 'vue-kompo/js/form/mixins/Field'
|
|
24
|
+
import HasInputAttributes from 'vue-kompo/js/form/mixins/HasInputAttributes'
|
|
25
|
+
|
|
26
|
+
export default {
|
|
27
|
+
mixins: [Field, HasInputAttributes],
|
|
28
|
+
data() {
|
|
29
|
+
return {
|
|
30
|
+
visualValue: this.component?.value || '',
|
|
31
|
+
focused: false,
|
|
32
|
+
dirty: false
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
computed: {
|
|
36
|
+
$_attributes() {
|
|
37
|
+
return {
|
|
38
|
+
...this.$_defaultFieldAttributes,
|
|
39
|
+
...this.$_defaultInputAttributes
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
focusOnLoad(){ return this.$_config('focusOnLoad') },
|
|
43
|
+
invalidClass() { return this.$_config('invalidClass')},
|
|
44
|
+
|
|
45
|
+
validateJustFuture() { return this.$_config('validateJustFuture') },
|
|
46
|
+
|
|
47
|
+
formatDateStructure() { return this.$_config('dateFormat') },
|
|
48
|
+
|
|
49
|
+
rawDateNumbers() { return this.visualValue.replace(/\D/g, '') },
|
|
50
|
+
|
|
51
|
+
quantityOfNumbersDate() { return this.formatDateStructure.replace(/[^a-zA-Z]/g, '').length },
|
|
52
|
+
|
|
53
|
+
formatedDate() {
|
|
54
|
+
return this.formatDate(this.rawDateNumbers);
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
rawDate() {
|
|
58
|
+
const rawDateNumbers = this.rawDateNumbers;
|
|
59
|
+
const formatParts = this.formatDateStructure.split(/[^a-zA-Z]+/);
|
|
60
|
+
const dateParts = [];
|
|
61
|
+
let index = 0;
|
|
62
|
+
|
|
63
|
+
formatParts.forEach(part => {
|
|
64
|
+
dateParts.push(rawDateNumbers.slice(index, index + part.length));
|
|
65
|
+
index += part.length;
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (!dateParts.length) return null;
|
|
69
|
+
|
|
70
|
+
const [day, month, year] = formatParts.length === 3 ? dateParts : [null, ...dateParts];
|
|
71
|
+
|
|
72
|
+
if (formatParts.length === 3) {
|
|
73
|
+
return new Date(`${month}-${day}-${year}`);
|
|
74
|
+
} else {
|
|
75
|
+
return new Date(`${month}-01-${year}`);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
showError() {
|
|
80
|
+
return !this.isValidDate && !this.focused && this.dirty;
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
isValidDate() {
|
|
84
|
+
const date = this.rawDate;
|
|
85
|
+
|
|
86
|
+
if (!date || date == 'Invalid Date') return false;
|
|
87
|
+
|
|
88
|
+
if (this.validateJustFuture) {
|
|
89
|
+
if (date < new Date()) return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
methods: {
|
|
96
|
+
focus(){
|
|
97
|
+
this.$refs.input.focus()
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
onInputDateNumber() {
|
|
101
|
+
this.visualValue = this.formatedDate;
|
|
102
|
+
this.component.value = this.isValidDate ? this.rawDate.toLocaleDateString() : null;
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
onFocus() {
|
|
106
|
+
this.focused = true;
|
|
107
|
+
this.dirty = true;
|
|
108
|
+
},
|
|
109
|
+
dateToRawNumbers(date) {
|
|
110
|
+
if (!date) return '';
|
|
111
|
+
|
|
112
|
+
return (new Date(date)).toLocaleDateString().replace(/\D/g, '');
|
|
113
|
+
},
|
|
114
|
+
formatDate(rawDateNumbers) {
|
|
115
|
+
let formatted = '';
|
|
116
|
+
let index = 0;
|
|
117
|
+
|
|
118
|
+
for (let char of this.formatDateStructure) {
|
|
119
|
+
if (!rawDateNumbers[index]) break;
|
|
120
|
+
|
|
121
|
+
if (/[^a-zA-Z]/.test(char)) {
|
|
122
|
+
formatted += char;
|
|
123
|
+
} else {
|
|
124
|
+
formatted += rawDateNumbers[index] || '';
|
|
125
|
+
index++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return formatted;
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
mounted(){
|
|
133
|
+
if(this.component.value) {
|
|
134
|
+
this.visualValue = this.component.value
|
|
135
|
+
this.onInputDateNumber()
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if(this.focusOnLoad)
|
|
139
|
+
this.focus()
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
</script>
|
|
143
|
+
|
|
144
|
+
<style scoped>
|
|
145
|
+
.invalid-icon {
|
|
146
|
+
color: red;
|
|
147
|
+
font-weight: bold;
|
|
148
|
+
margin-left: 8px;
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
}
|
|
151
|
+
</style>
|