sprintify-ui 0.0.195 → 0.0.196
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/sprintify-ui.es.js +7952 -7925
- package/dist/types/src/components/BaseAddressForm.vue.d.ts +2 -2
- package/dist/types/src/components/BaseAutocomplete.vue.d.ts +5 -5
- package/dist/types/src/components/BaseAutocompleteDrawer.vue.d.ts +2 -2
- package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +5 -5
- package/dist/types/src/components/BaseBelongsTo.vue.d.ts +3 -3
- package/dist/types/src/components/BaseButtonGroup.vue.d.ts +2 -2
- package/dist/types/src/components/BaseCharacterCounter.vue.d.ts +1 -1
- package/dist/types/src/components/BaseColor.vue.d.ts +2 -2
- package/dist/types/src/components/BaseDatePicker.vue.d.ts +1 -1
- package/dist/types/src/components/BaseDropdownAutocomplete.vue.d.ts +4 -4
- package/dist/types/src/components/BaseFieldI18n.vue.d.ts +2 -2
- package/dist/types/src/components/BaseFilePicker.vue.d.ts +1 -1
- package/dist/types/src/components/BaseFileUploader.vue.d.ts +2 -2
- package/dist/types/src/components/BaseForm.vue.d.ts +1 -1
- package/dist/types/src/components/BaseHasMany.vue.d.ts +2 -2
- package/dist/types/src/components/BaseInput.vue.d.ts +5 -5
- package/dist/types/src/components/BaseInputPercent.vue.d.ts +4 -4
- package/dist/types/src/components/BaseLoadingCover.vue.d.ts +2 -2
- package/dist/types/src/components/BaseMediaLibrary.vue.d.ts +4 -4
- package/dist/types/src/components/BaseModalCenter.vue.d.ts +1 -1
- package/dist/types/src/components/BaseModalSide.vue.d.ts +1 -1
- package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +1 -1
- package/dist/types/src/components/BaseNavbarSideItemContent.vue.d.ts +1 -1
- package/dist/types/src/components/BaseNumber.vue.d.ts +16 -7
- package/dist/types/src/components/BasePassword.vue.d.ts +2 -2
- package/dist/types/src/components/BaseRadioGroup.vue.d.ts +1 -1
- package/dist/types/src/components/BaseRichText.vue.d.ts +2 -2
- package/dist/types/src/components/BaseSelect.vue.d.ts +3 -3
- package/dist/types/src/components/BaseSwitch.vue.d.ts +1 -1
- package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +4 -4
- package/dist/types/src/components/BaseTagAutocompleteFetch.vue.d.ts +2 -2
- package/dist/types/src/components/BaseTextarea.vue.d.ts +3 -3
- package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +2 -2
- package/package.json +1 -1
- package/src/components/BaseForm.stories.js +48 -0
- package/src/components/BaseForm.vue +10 -5
- package/src/components/BaseNumber.stories.js +19 -3
- package/src/components/BaseNumber.vue +57 -4
- package/src/composables/field.ts +11 -4
|
@@ -112,7 +112,6 @@ const emit = defineEmits(['error', 'success']);
|
|
|
112
112
|
|
|
113
113
|
const form = ref<null | HTMLFormElement>(null);
|
|
114
114
|
const loading = ref(false);
|
|
115
|
-
const disabled = ref(false);
|
|
116
115
|
const errors = ref<Record<string, string[]>>({});
|
|
117
116
|
|
|
118
117
|
const httpClient = computed((): AxiosInstance => {
|
|
@@ -291,14 +290,20 @@ function clearErrors(name = null): void {
|
|
|
291
290
|
}
|
|
292
291
|
}
|
|
293
292
|
|
|
294
|
-
|
|
295
|
-
|
|
293
|
+
const disablingFields = reactive(new Set<string>());
|
|
294
|
+
|
|
295
|
+
function disabledForm(uuid: string) {
|
|
296
|
+
disablingFields.add(uuid);
|
|
296
297
|
}
|
|
297
298
|
|
|
298
|
-
function enableForm() {
|
|
299
|
-
|
|
299
|
+
function enableForm(uuid: string) {
|
|
300
|
+
disablingFields.delete(uuid);
|
|
300
301
|
}
|
|
301
302
|
|
|
303
|
+
const disabled = computed((): boolean => {
|
|
304
|
+
return disablingFields.size > 0;
|
|
305
|
+
});
|
|
306
|
+
|
|
302
307
|
provide('form:errors', readonly(errors));
|
|
303
308
|
provide('form:getErrorMessageByName', getErrorMessageByName);
|
|
304
309
|
provide('form:clearErrors', clearErrors);
|
|
@@ -8,8 +8,6 @@ export default {
|
|
|
8
8
|
args: {
|
|
9
9
|
placeholder: 'Enter number',
|
|
10
10
|
step: 0.1,
|
|
11
|
-
min: 0,
|
|
12
|
-
max: 100,
|
|
13
11
|
},
|
|
14
12
|
};
|
|
15
13
|
|
|
@@ -19,7 +17,7 @@ const Template = (args) => ({
|
|
|
19
17
|
BaseNumber,
|
|
20
18
|
},
|
|
21
19
|
setup() {
|
|
22
|
-
const value = ref(
|
|
20
|
+
const value = ref(null);
|
|
23
21
|
return { args, value };
|
|
24
22
|
},
|
|
25
23
|
template: `
|
|
@@ -33,6 +31,24 @@ const Template = (args) => ({
|
|
|
33
31
|
export const Demo = Template.bind({});
|
|
34
32
|
Demo.args = {};
|
|
35
33
|
|
|
34
|
+
export const Min = Template.bind({});
|
|
35
|
+
Min.args = {
|
|
36
|
+
min: 10000,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const Max = Template.bind({});
|
|
40
|
+
Max.args = {
|
|
41
|
+
max: 10000,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const AutoFix = Template.bind({});
|
|
45
|
+
AutoFix.args = {
|
|
46
|
+
autoFix: true,
|
|
47
|
+
min: 10,
|
|
48
|
+
max: 20,
|
|
49
|
+
step: 0.01,
|
|
50
|
+
};
|
|
51
|
+
|
|
36
52
|
export const Disabled = Template.bind({});
|
|
37
53
|
Disabled.args = {
|
|
38
54
|
disabled: true,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
leave-from-class="transform scale-100 opacity-100"
|
|
9
9
|
leave-to-class="transform scale-90 opacity-0"
|
|
10
10
|
>
|
|
11
|
-
<div v-if="
|
|
11
|
+
<div v-if="showInvalidInput" class="absolute left-0 top-full z-[1]">
|
|
12
12
|
<div
|
|
13
13
|
class="mt-1 ml-1 rounded bg-red-500 px-2 py-1 text-xs font-medium text-white"
|
|
14
14
|
>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
:max="max"
|
|
37
37
|
:class="[
|
|
38
38
|
['full', 'left'].includes(rounded) ? 'rounded-l' : '',
|
|
39
|
-
|
|
39
|
+
showInvalidInput ? 'focus:ring-red-400' : 'focus:ring-primary-500',
|
|
40
40
|
]"
|
|
41
41
|
class="w-full border-none focus:z-[1] focus:border-none focus:border-transparent focus:shadow-none focus:outline-none focus:ring-2 focus:ring-offset-1 disabled:cursor-not-allowed disabled:text-slate-300"
|
|
42
42
|
type="text"
|
|
@@ -73,8 +73,10 @@
|
|
|
73
73
|
import { useField } from '@/composables/field';
|
|
74
74
|
import { isNumber, round } from 'lodash';
|
|
75
75
|
import { PropType } from 'vue';
|
|
76
|
+
import { BaseIcon } from '.';
|
|
76
77
|
|
|
77
78
|
const AUTO_CORRECT_TIMEOUT = 2000;
|
|
79
|
+
const SHOW_INVALID_INPUT_TIMEOUT = 500;
|
|
78
80
|
|
|
79
81
|
const props = defineProps({
|
|
80
82
|
modelValue: {
|
|
@@ -124,17 +126,23 @@ const props = defineProps({
|
|
|
124
126
|
default: 'full',
|
|
125
127
|
type: String as PropType<'full' | 'left' | 'right' | 'none'>,
|
|
126
128
|
},
|
|
129
|
+
autoFix: {
|
|
130
|
+
default: false,
|
|
131
|
+
type: Boolean,
|
|
132
|
+
},
|
|
127
133
|
});
|
|
128
134
|
|
|
129
135
|
const emit = defineEmits(['update:modelValue', 'focus', 'blur', 'keydown']);
|
|
130
136
|
|
|
131
|
-
const { hasErrorInternal, emitUpdate } = useField({
|
|
137
|
+
const { hasErrorInternal, emitUpdate, enableForm, disableForm } = useField({
|
|
132
138
|
name: computed(() => props.name),
|
|
133
139
|
required: computed(() => props.required),
|
|
134
140
|
hasError: computed(() => props.hasError),
|
|
135
141
|
emit: emit,
|
|
136
142
|
});
|
|
137
143
|
|
|
144
|
+
const showInvalidInput = ref(false);
|
|
145
|
+
|
|
138
146
|
const stepNormalized = computed<number>(() => {
|
|
139
147
|
if (props.step === undefined) return 1;
|
|
140
148
|
if (props.step === 0) return 1;
|
|
@@ -170,9 +178,11 @@ function convertToNumber(
|
|
|
170
178
|
}
|
|
171
179
|
|
|
172
180
|
const valueInternal = ref<null | string | number>(null);
|
|
181
|
+
|
|
173
182
|
const realValueInternal = computed<number | null>(() => {
|
|
174
183
|
return convertToNumber(valueInternal.value);
|
|
175
184
|
});
|
|
185
|
+
|
|
176
186
|
const invalidInput = computed(() => {
|
|
177
187
|
if (realValueInternal.value == null && valueInternal.value == '') {
|
|
178
188
|
return false;
|
|
@@ -180,10 +190,12 @@ const invalidInput = computed(() => {
|
|
|
180
190
|
|
|
181
191
|
return realValueInternal.value != valueInternal.value;
|
|
182
192
|
});
|
|
193
|
+
|
|
183
194
|
const tooBig = computed(() => {
|
|
184
195
|
if (valueInternal.value === null) return false;
|
|
185
196
|
return hasMax.value && valueInternal.value > (props.max as number);
|
|
186
197
|
});
|
|
198
|
+
|
|
187
199
|
const tooSmall = computed(() => {
|
|
188
200
|
if (valueInternal.value === null) return false;
|
|
189
201
|
return hasMin.value && valueInternal.value < (props.min as number);
|
|
@@ -214,13 +226,37 @@ function onInput(event: any) {
|
|
|
214
226
|
|
|
215
227
|
emitUpdate(realValueInternal.value);
|
|
216
228
|
|
|
229
|
+
nextTick(() => {
|
|
230
|
+
showHideInvalidOnInput();
|
|
231
|
+
});
|
|
232
|
+
|
|
217
233
|
timeoutId = setTimeout(() => {
|
|
218
234
|
updateInternalValueToRealValue();
|
|
219
235
|
}, AUTO_CORRECT_TIMEOUT);
|
|
220
236
|
}
|
|
221
237
|
|
|
238
|
+
let showInvalidInputTimeoutId = undefined as undefined | number;
|
|
239
|
+
|
|
240
|
+
function showHideInvalidOnInput() {
|
|
241
|
+
clearTimeout(showInvalidInputTimeoutId);
|
|
242
|
+
|
|
243
|
+
if (!invalidInput.value) {
|
|
244
|
+
showInvalidInput.value = false;
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
showInvalidInputTimeoutId = setTimeout(() => {
|
|
249
|
+
showInvalidInput.value = true;
|
|
250
|
+
}, SHOW_INVALID_INPUT_TIMEOUT);
|
|
251
|
+
}
|
|
252
|
+
|
|
222
253
|
function onBlur(e: Event) {
|
|
223
254
|
emit('blur', e);
|
|
255
|
+
|
|
256
|
+
if (invalidInput.value) {
|
|
257
|
+
showInvalidInput.value = true;
|
|
258
|
+
}
|
|
259
|
+
|
|
224
260
|
updateInternalValueToRealValue();
|
|
225
261
|
}
|
|
226
262
|
|
|
@@ -244,6 +280,9 @@ const defaultValue = computed<number>(() => {
|
|
|
244
280
|
});
|
|
245
281
|
|
|
246
282
|
function updateInternalValueToRealValue() {
|
|
283
|
+
if (!props.autoFix) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
247
286
|
if (realValueInternal.value === null) {
|
|
248
287
|
valueInternal.value = '';
|
|
249
288
|
return;
|
|
@@ -287,7 +326,21 @@ function decrement() {
|
|
|
287
326
|
}
|
|
288
327
|
|
|
289
328
|
const borderColor = computed(() => {
|
|
290
|
-
if (hasErrorInternal.value) return 'border-red-500';
|
|
329
|
+
if (hasErrorInternal.value || invalidInput.value) return 'border-red-500';
|
|
291
330
|
return 'border-slate-300';
|
|
292
331
|
});
|
|
332
|
+
|
|
333
|
+
/** Disable form */
|
|
334
|
+
|
|
335
|
+
watch(
|
|
336
|
+
() => invalidInput.value,
|
|
337
|
+
() => {
|
|
338
|
+
if (invalidInput.value) {
|
|
339
|
+
disableForm();
|
|
340
|
+
} else {
|
|
341
|
+
enableForm();
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
{ immediate: true }
|
|
345
|
+
);
|
|
293
346
|
</script>
|
package/src/composables/field.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { uniqueId } from 'lodash';
|
|
1
2
|
import { Ref } from 'vue';
|
|
2
3
|
|
|
3
4
|
interface Config {
|
|
@@ -10,6 +11,7 @@ interface Config {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export function useField(config: Config) {
|
|
14
|
+
const uuid = uniqueId();
|
|
13
15
|
const name = config.name;
|
|
14
16
|
const required = config.required;
|
|
15
17
|
const hasError = config.hasError;
|
|
@@ -60,11 +62,15 @@ export function useField(config: Config) {
|
|
|
60
62
|
|
|
61
63
|
const disableForm = inject('form:disable', () => {
|
|
62
64
|
return;
|
|
63
|
-
}) as () => void;
|
|
65
|
+
}) as (uuid: string) => void;
|
|
64
66
|
|
|
65
67
|
const enableForm = inject('form:enable', () => {
|
|
66
68
|
return;
|
|
67
|
-
}) as () => void;
|
|
69
|
+
}) as (uuid: string) => void;
|
|
70
|
+
|
|
71
|
+
onBeforeUnmount(() => {
|
|
72
|
+
enableForm(uuid);
|
|
73
|
+
});
|
|
68
74
|
|
|
69
75
|
const requiredInternal = computed((): boolean => {
|
|
70
76
|
if (required.value) {
|
|
@@ -98,13 +104,14 @@ export function useField(config: Config) {
|
|
|
98
104
|
emit('update:modelValue', value);
|
|
99
105
|
fieldOnUpdate();
|
|
100
106
|
}
|
|
107
|
+
|
|
101
108
|
return {
|
|
102
109
|
requiredInternal,
|
|
103
110
|
nameInternal,
|
|
104
111
|
hasErrorInternal,
|
|
105
112
|
errorMessageInternal,
|
|
106
113
|
emitUpdate,
|
|
107
|
-
enableForm,
|
|
108
|
-
disableForm,
|
|
114
|
+
enableForm: () => enableForm(uuid),
|
|
115
|
+
disableForm: () => disableForm(uuid),
|
|
109
116
|
};
|
|
110
117
|
}
|