@winchsa/ui 0.1.12 → 0.1.14
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/components/IconBtn.vue +10 -4
- package/dist/components/IconBtn.vue.d.ts +9 -9
- package/dist/components/cards/AppCardActions.vue +1 -1
- package/dist/components/cards/AppCardActions.vue.d.ts +4 -4
- package/dist/components/cards/InputCard.vue +1 -1
- package/dist/components/cards/InputCard.vue.d.ts +2 -2
- package/dist/components/forms/AppBarSearch.vue +1 -1
- package/dist/components/forms/AppBarSearch.vue.d.ts +16 -16
- package/dist/components/forms/AppSearchHeader.vue +1 -1
- package/dist/components/forms/AutocompleteInput.vue +1 -1
- package/dist/components/forms/LicensePlateInput.vue +34 -16
- package/dist/components/forms/LicensePlateInput.vue.d.ts +0 -1
- package/dist/components/forms/ManualDate.vue +8 -8
- package/dist/components/forms/ManualDate.vue.d.ts +1 -0
- package/dist/components/table/EditableDataTable.vue.d.ts +1 -1
- package/dist/components/table/EditableDataTableRow.vue +3 -1
- package/dist/types.d.ts +1 -1
- package/dist/utils/hijriDate.js +2 -2
- package/dist/utils/hijriDate.mjs +2 -2
- package/dist/utils/ruleValidator.d.ts +6 -0
- package/dist/utils/ruleValidator.js +16 -1
- package/dist/utils/ruleValidator.mjs +16 -1
- package/package.json +4 -3
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { VBtn } from "vuetify/components";
|
|
3
3
|
const props = defineProps({
|
|
4
|
-
color: { type:
|
|
5
|
-
variant: { type:
|
|
6
|
-
density: { type:
|
|
4
|
+
color: { type: String, required: false, default: "default" },
|
|
5
|
+
variant: { type: String, required: false, default: "text" },
|
|
6
|
+
density: { type: String, required: false, default: "comfortable" }
|
|
7
7
|
});
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<template>
|
|
11
|
-
<VBtn
|
|
11
|
+
<VBtn
|
|
12
|
+
:icon="true"
|
|
13
|
+
:color="props.color"
|
|
14
|
+
:variant="props.variant"
|
|
15
|
+
:density="props.density"
|
|
16
|
+
v-bind="$attrs"
|
|
17
|
+
>
|
|
12
18
|
<slot />
|
|
13
19
|
</VBtn>
|
|
14
20
|
</template>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { VBtn } from 'vuetify/components';
|
|
2
2
|
type __VLS_Props = {
|
|
3
|
-
color?:
|
|
4
|
-
variant?:
|
|
5
|
-
density?:
|
|
3
|
+
color?: string;
|
|
4
|
+
variant?: 'text' | 'flat' | 'outlined' | 'elevated' | 'tonal' | 'plain';
|
|
5
|
+
density?: 'default' | 'comfortable' | 'compact';
|
|
6
6
|
};
|
|
7
7
|
declare const __VLS_ctx: InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>;
|
|
8
8
|
declare var __VLS_6: {};
|
|
@@ -12,14 +12,14 @@ type __VLS_Slots = __VLS_PrettifyGlobal<__VLS_OmitStringIndex<typeof __VLS_ctx.$
|
|
|
12
12
|
declare const __VLS_self: import("vue").DefineComponent<__VLS_Props, {
|
|
13
13
|
VBtn: typeof VBtn;
|
|
14
14
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
15
|
-
color:
|
|
16
|
-
density:
|
|
17
|
-
variant:
|
|
15
|
+
color: string;
|
|
16
|
+
density: "default" | "comfortable" | "compact";
|
|
17
|
+
variant: "text" | "flat" | "outlined" | "elevated" | "tonal" | "plain";
|
|
18
18
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
19
|
declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
20
|
-
color:
|
|
21
|
-
density:
|
|
22
|
-
variant:
|
|
20
|
+
color: string;
|
|
21
|
+
density: "default" | "comfortable" | "compact";
|
|
22
|
+
variant: "text" | "flat" | "outlined" | "elevated" | "tonal" | "plain";
|
|
23
23
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
24
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
25
25
|
export default _default;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref } from "vue";
|
|
3
|
-
import { VCard, VCardItem, VIcon, VOverlay, VExpandTransition, VProgressCircular, VCardTitle
|
|
3
|
+
import { VCard, VCardItem, VIcon, VOverlay, VExpandTransition, VProgressCircular, VCardTitle } from "vuetify/components";
|
|
4
4
|
import IconBtn from "../IconBtn.vue";
|
|
5
5
|
const props = defineProps({
|
|
6
6
|
collapsed: { type: Boolean, required: false, default: false },
|
|
@@ -39,12 +39,12 @@ declare const __VLS_self: import("vue").DefineComponent<__VLS_Props, {
|
|
|
39
39
|
triggerRefresh: typeof triggerRefresh;
|
|
40
40
|
triggeredRemove: typeof triggeredRemove;
|
|
41
41
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
42
|
-
refresh: (hideOverlay: () => void) => any;
|
|
43
42
|
collapsed: (isContentCollapsed: boolean) => any;
|
|
43
|
+
refresh: (hideOverlay: () => void) => any;
|
|
44
44
|
trash: () => any;
|
|
45
45
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
46
|
-
onRefresh?: ((hideOverlay: () => void) => any) | undefined;
|
|
47
46
|
onCollapsed?: ((isContentCollapsed: boolean) => any) | undefined;
|
|
47
|
+
onRefresh?: ((hideOverlay: () => void) => any) | undefined;
|
|
48
48
|
onTrash?: (() => any) | undefined;
|
|
49
49
|
}>, {
|
|
50
50
|
title: string;
|
|
@@ -55,12 +55,12 @@ declare const __VLS_self: import("vue").DefineComponent<__VLS_Props, {
|
|
|
55
55
|
actionRemove: boolean;
|
|
56
56
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
57
57
|
declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
58
|
-
refresh: (hideOverlay: () => void) => any;
|
|
59
58
|
collapsed: (isContentCollapsed: boolean) => any;
|
|
59
|
+
refresh: (hideOverlay: () => void) => any;
|
|
60
60
|
trash: () => any;
|
|
61
61
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
62
|
-
onRefresh?: ((hideOverlay: () => void) => any) | undefined;
|
|
63
62
|
onCollapsed?: ((isContentCollapsed: boolean) => any) | undefined;
|
|
63
|
+
onRefresh?: ((hideOverlay: () => void) => any) | undefined;
|
|
64
64
|
onTrash?: (() => any) | undefined;
|
|
65
65
|
}>, {
|
|
66
66
|
title: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed } from "vue";
|
|
3
3
|
import { VLabel } from "vuetify/components";
|
|
4
|
-
import AppCard from "./AppCard.vue";
|
|
5
4
|
import AppLink from "../forms/AppLink.vue";
|
|
5
|
+
import AppCard from "./AppCard.vue";
|
|
6
6
|
const props = defineProps({
|
|
7
7
|
title: { type: String, required: false, default: "" },
|
|
8
8
|
text: { type: [String, Number], required: false, default: "" },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VLabel } from 'vuetify/components';
|
|
2
|
-
import AppCard from './AppCard.vue';
|
|
3
2
|
import AppLink from '../forms/AppLink.vue';
|
|
3
|
+
import AppCard from './AppCard.vue';
|
|
4
4
|
type __VLS_Props = {
|
|
5
5
|
title?: string;
|
|
6
6
|
text?: string | number;
|
|
@@ -17,8 +17,8 @@ type __VLS_Slots = __VLS_PrettifyGlobal<__VLS_OmitStringIndex<typeof __VLS_ctx.$
|
|
|
17
17
|
}>;
|
|
18
18
|
declare const __VLS_self: import("vue").DefineComponent<__VLS_Props, {
|
|
19
19
|
VLabel: typeof VLabel;
|
|
20
|
-
AppCard: typeof AppCard;
|
|
21
20
|
AppLink: typeof AppLink;
|
|
21
|
+
AppCard: typeof AppCard;
|
|
22
22
|
colorStyle: typeof colorStyle;
|
|
23
23
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
24
24
|
color: string;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { PerfectScrollbar } from "vue3-perfect-scrollbar";
|
|
3
3
|
import { useMagicKeys } from "@vueuse/core";
|
|
4
4
|
import { ref, toRaw, watch, watchEffect } from "vue";
|
|
5
|
-
import { VList, VListItem, VListSubheader, VListItemTitle, VCardText, VDialog, VIcon, VDivider, VCol, VRow, VTextField
|
|
5
|
+
import { VList, VListItem, VListSubheader, VListItemTitle, VCardText, VDialog, VIcon, VDivider, VCol, VRow, VTextField } from "vuetify/components";
|
|
6
6
|
import IconBtn from "../IconBtn.vue";
|
|
7
7
|
import AppCard from "../cards/AppCard.vue";
|
|
8
8
|
const props = defineProps({
|
|
@@ -550,7 +550,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
550
550
|
} & {
|
|
551
551
|
item: unknown;
|
|
552
552
|
}) => import("vue").VNodeChild) | undefined;
|
|
553
|
-
|
|
553
|
+
append?: ((arg: {
|
|
554
554
|
isActive: boolean;
|
|
555
555
|
isSelected: boolean;
|
|
556
556
|
isIndeterminate: boolean;
|
|
@@ -558,7 +558,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
558
558
|
} & {
|
|
559
559
|
item: unknown;
|
|
560
560
|
}) => import("vue").VNodeChild) | undefined;
|
|
561
|
-
|
|
561
|
+
prepend?: ((arg: {
|
|
562
562
|
isActive: boolean;
|
|
563
563
|
isSelected: boolean;
|
|
564
564
|
isIndeterminate: boolean;
|
|
@@ -607,7 +607,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
607
607
|
} & {
|
|
608
608
|
item: unknown;
|
|
609
609
|
}) => import("vue").VNodeChild) | undefined;
|
|
610
|
-
|
|
610
|
+
append?: false | ((arg: {
|
|
611
611
|
isActive: boolean;
|
|
612
612
|
isSelected: boolean;
|
|
613
613
|
isIndeterminate: boolean;
|
|
@@ -615,7 +615,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
615
615
|
} & {
|
|
616
616
|
item: unknown;
|
|
617
617
|
}) => import("vue").VNodeChild) | undefined;
|
|
618
|
-
|
|
618
|
+
prepend?: false | ((arg: {
|
|
619
619
|
isActive: boolean;
|
|
620
620
|
isSelected: boolean;
|
|
621
621
|
isIndeterminate: boolean;
|
|
@@ -664,7 +664,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
664
664
|
} & {
|
|
665
665
|
item: unknown;
|
|
666
666
|
}) => import("vue").VNodeChild) | undefined;
|
|
667
|
-
"v-slot:
|
|
667
|
+
"v-slot:append"?: false | ((arg: {
|
|
668
668
|
isActive: boolean;
|
|
669
669
|
isSelected: boolean;
|
|
670
670
|
isIndeterminate: boolean;
|
|
@@ -672,7 +672,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
672
672
|
} & {
|
|
673
673
|
item: unknown;
|
|
674
674
|
}) => import("vue").VNodeChild) | undefined;
|
|
675
|
-
"v-slot:
|
|
675
|
+
"v-slot:prepend"?: false | ((arg: {
|
|
676
676
|
isActive: boolean;
|
|
677
677
|
isSelected: boolean;
|
|
678
678
|
isIndeterminate: boolean;
|
|
@@ -721,7 +721,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
721
721
|
} & {
|
|
722
722
|
item: unknown;
|
|
723
723
|
}) => import("vue").VNode[];
|
|
724
|
-
|
|
724
|
+
append: (arg: {
|
|
725
725
|
isActive: boolean;
|
|
726
726
|
isSelected: boolean;
|
|
727
727
|
isIndeterminate: boolean;
|
|
@@ -729,7 +729,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
729
729
|
} & {
|
|
730
730
|
item: unknown;
|
|
731
731
|
}) => import("vue").VNode[];
|
|
732
|
-
|
|
732
|
+
prepend: (arg: {
|
|
733
733
|
isActive: boolean;
|
|
734
734
|
isSelected: boolean;
|
|
735
735
|
isIndeterminate: boolean;
|
|
@@ -1299,7 +1299,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
1299
1299
|
} & {
|
|
1300
1300
|
item: unknown;
|
|
1301
1301
|
}) => import("vue").VNodeChild) | undefined;
|
|
1302
|
-
|
|
1302
|
+
append?: ((arg: {
|
|
1303
1303
|
isActive: boolean;
|
|
1304
1304
|
isSelected: boolean;
|
|
1305
1305
|
isIndeterminate: boolean;
|
|
@@ -1307,7 +1307,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
1307
1307
|
} & {
|
|
1308
1308
|
item: unknown;
|
|
1309
1309
|
}) => import("vue").VNodeChild) | undefined;
|
|
1310
|
-
|
|
1310
|
+
prepend?: ((arg: {
|
|
1311
1311
|
isActive: boolean;
|
|
1312
1312
|
isSelected: boolean;
|
|
1313
1313
|
isIndeterminate: boolean;
|
|
@@ -1356,7 +1356,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
1356
1356
|
} & {
|
|
1357
1357
|
item: unknown;
|
|
1358
1358
|
}) => import("vue").VNodeChild) | undefined;
|
|
1359
|
-
|
|
1359
|
+
append?: false | ((arg: {
|
|
1360
1360
|
isActive: boolean;
|
|
1361
1361
|
isSelected: boolean;
|
|
1362
1362
|
isIndeterminate: boolean;
|
|
@@ -1364,7 +1364,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
1364
1364
|
} & {
|
|
1365
1365
|
item: unknown;
|
|
1366
1366
|
}) => import("vue").VNodeChild) | undefined;
|
|
1367
|
-
|
|
1367
|
+
prepend?: false | ((arg: {
|
|
1368
1368
|
isActive: boolean;
|
|
1369
1369
|
isSelected: boolean;
|
|
1370
1370
|
isIndeterminate: boolean;
|
|
@@ -1413,7 +1413,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
1413
1413
|
} & {
|
|
1414
1414
|
item: unknown;
|
|
1415
1415
|
}) => import("vue").VNodeChild) | undefined;
|
|
1416
|
-
"v-slot:
|
|
1416
|
+
"v-slot:append"?: false | ((arg: {
|
|
1417
1417
|
isActive: boolean;
|
|
1418
1418
|
isSelected: boolean;
|
|
1419
1419
|
isIndeterminate: boolean;
|
|
@@ -1421,7 +1421,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
1421
1421
|
} & {
|
|
1422
1422
|
item: unknown;
|
|
1423
1423
|
}) => import("vue").VNodeChild) | undefined;
|
|
1424
|
-
"v-slot:
|
|
1424
|
+
"v-slot:prepend"?: false | ((arg: {
|
|
1425
1425
|
isActive: boolean;
|
|
1426
1426
|
isSelected: boolean;
|
|
1427
1427
|
isIndeterminate: boolean;
|
|
@@ -1470,7 +1470,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
1470
1470
|
} & {
|
|
1471
1471
|
item: unknown;
|
|
1472
1472
|
}) => import("vue").VNode[];
|
|
1473
|
-
|
|
1473
|
+
append: (arg: {
|
|
1474
1474
|
isActive: boolean;
|
|
1475
1475
|
isSelected: boolean;
|
|
1476
1476
|
isIndeterminate: boolean;
|
|
@@ -1478,7 +1478,7 @@ declare const refSearchList: import("vue").Ref<({
|
|
|
1478
1478
|
} & {
|
|
1479
1479
|
item: unknown;
|
|
1480
1480
|
}) => import("vue").VNode[];
|
|
1481
|
-
|
|
1481
|
+
prepend: (arg: {
|
|
1482
1482
|
isActive: boolean;
|
|
1483
1483
|
isSelected: boolean;
|
|
1484
1484
|
isIndeterminate: boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { VCardText, VIcon } from "vuetify/components";
|
|
3
3
|
import AppSearchHeaderBg from "../../images/avatar.png";
|
|
4
|
-
import AppTextField from "./AppTextField.vue";
|
|
5
4
|
import AppCard from "../cards/AppCard.vue";
|
|
5
|
+
import AppTextField from "./AppTextField.vue";
|
|
6
6
|
defineProps({
|
|
7
7
|
title: { type: String, required: false },
|
|
8
8
|
subtitle: { type: String, required: false },
|
|
@@ -436,7 +436,7 @@ defineExpose({
|
|
|
436
436
|
|
|
437
437
|
<template #clear>
|
|
438
438
|
<div
|
|
439
|
-
v-if="
|
|
439
|
+
v-if="(Array.isArray(value) && value?.length > 0 || value) && value && !disabled"
|
|
440
440
|
class="multiselect-clear cursor-pointer"
|
|
441
441
|
@mousedown.prevent.stop="value = null"
|
|
442
442
|
>
|
|
@@ -7,51 +7,68 @@ const props = defineProps({
|
|
|
7
7
|
hideDetails: { type: Boolean, required: false },
|
|
8
8
|
label: { type: String, required: false },
|
|
9
9
|
customId: { type: String, required: false },
|
|
10
|
-
errorMessages: { type: [Array, String], required: false }
|
|
11
|
-
error: { type: Boolean, required: false }
|
|
10
|
+
errorMessages: { type: [Array, String], required: false }
|
|
12
11
|
});
|
|
13
12
|
const model = defineModel({ type: [Array, null], ...{ default: ["", "", "", ""] } });
|
|
14
13
|
const LangLabel = computed(() => props.label ? t(props.label) : "");
|
|
14
|
+
const allowedLetters = ["A", "B", "J", "D", "R", "S", "X", "T", "E", "G", "K", "L", "Z", "N", "H", "U", "V"];
|
|
15
|
+
const allowedArabicLetters = ["\u0623", "\u0627", "\u0628", "\u062D", "\u062F", "\u0631", "\u0633", "\u0635", "\u0637", "\u0639", "\u0642", "\u0643", "\u0644", "\u0645", "\u0646", "\u0647", "\u0648", "\u064A"];
|
|
16
|
+
const normalizeInput = (input) => {
|
|
17
|
+
const arabicCasting = {
|
|
18
|
+
"\u0627": "\u0623",
|
|
19
|
+
"\u0622": "\u0623",
|
|
20
|
+
"\u0625": "\u0623",
|
|
21
|
+
"\u0649": "\u064A"
|
|
22
|
+
};
|
|
23
|
+
return input.split("").map((char) => arabicCasting[char] || char.toUpperCase()).join("");
|
|
24
|
+
};
|
|
25
|
+
const updateModelAt = (index, value) => {
|
|
26
|
+
const newModel = [...model.value ?? ["", "", "", ""]];
|
|
27
|
+
newModel[index] = value;
|
|
28
|
+
model.value = newModel;
|
|
29
|
+
};
|
|
15
30
|
const handleInput = (e, index) => {
|
|
16
31
|
const input = e.target;
|
|
17
|
-
|
|
32
|
+
let value = input.value;
|
|
18
33
|
if (!model.value) {
|
|
19
34
|
model.value = ["", "", "", ""];
|
|
20
35
|
}
|
|
21
36
|
if (e.inputType === "deleteContentBackward") {
|
|
22
|
-
|
|
37
|
+
updateModelAt(index, "");
|
|
23
38
|
if (index > 0) {
|
|
24
39
|
document.getElementById(`license-${props.customId || ""}-${index - 1}`)?.focus();
|
|
25
40
|
}
|
|
26
41
|
return;
|
|
27
42
|
}
|
|
28
43
|
if (index < 3) {
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
value = normalizeInput(value);
|
|
45
|
+
if (!allowedLetters.includes(value) && !allowedArabicLetters.includes(value)) {
|
|
46
|
+
updateModelAt(index, "");
|
|
31
47
|
input.value = "";
|
|
32
48
|
return;
|
|
33
49
|
}
|
|
34
|
-
|
|
50
|
+
updateModelAt(index, value);
|
|
35
51
|
if (value) {
|
|
36
52
|
document.getElementById(`license-${props.customId || ""}-${index + 1}`)?.focus();
|
|
37
53
|
}
|
|
38
54
|
} else {
|
|
39
55
|
if (/\D/.test(value)) {
|
|
40
|
-
|
|
56
|
+
updateModelAt(index, "");
|
|
41
57
|
input.value = "";
|
|
42
58
|
return;
|
|
43
59
|
}
|
|
44
|
-
|
|
60
|
+
updateModelAt(index, value);
|
|
45
61
|
}
|
|
46
62
|
};
|
|
47
63
|
const clear = () => {
|
|
48
64
|
model.value = null;
|
|
49
65
|
};
|
|
50
|
-
const requiredRule =
|
|
51
|
-
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
|
|
66
|
+
const requiredRule = (value) => {
|
|
67
|
+
if (value.length !== 4 || !value.every((item) => item !== "")) {
|
|
68
|
+
return t("validation.required");
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
};
|
|
55
72
|
watch(() => model.value, (newVal) => {
|
|
56
73
|
if (Array.isArray(newVal)) {
|
|
57
74
|
model.value = newVal;
|
|
@@ -79,7 +96,7 @@ watch(() => model.value, (newVal) => {
|
|
|
79
96
|
class="app-license-plate-input position-relative"
|
|
80
97
|
style="min-height: 45px;"
|
|
81
98
|
:class="{
|
|
82
|
-
'app-license-plate-input--error': isValid.value
|
|
99
|
+
'app-license-plate-input--error': !isValid.value && validationErrors.value?.length > 0
|
|
83
100
|
}"
|
|
84
101
|
>
|
|
85
102
|
<input
|
|
@@ -89,6 +106,7 @@ watch(() => model.value, (newVal) => {
|
|
|
89
106
|
:value="model?.[index] ?? ''"
|
|
90
107
|
class="app-license-plate-input-cell"
|
|
91
108
|
type="text"
|
|
109
|
+
autocomplete="off"
|
|
92
110
|
:maxlength="index === 3 ? 4 : 1"
|
|
93
111
|
:placeholder="index === 3 ? t('inputs.numbers') : t('inputs.character')"
|
|
94
112
|
@input="handleInput($event, index)"
|
|
@@ -132,7 +150,7 @@ watch(() => model.value, (newVal) => {
|
|
|
132
150
|
box-sizing: border-box;
|
|
133
151
|
}
|
|
134
152
|
.app-license-plate-input.app-license-plate-input--error {
|
|
135
|
-
border-color: rgba(var(--v-theme-error), 1);
|
|
153
|
+
border-color: rgba(var(--v-theme-error), 1) !important;
|
|
136
154
|
}
|
|
137
155
|
.app-license-plate-input:hover {
|
|
138
156
|
transition: all 0.3s;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { HijriJS } from "../../utils/hijriDate";
|
|
3
2
|
import { computed, ref, watch } from "vue";
|
|
4
3
|
import { useI18n } from "vue-i18n";
|
|
5
4
|
import { VLabel, VIcon, VValidation, VMessages } from "vuetify/components";
|
|
6
|
-
import {
|
|
5
|
+
import { HijriJS } from "../../utils/hijriDate";
|
|
7
6
|
const { t } = useI18n();
|
|
8
7
|
const props = defineProps({
|
|
9
8
|
hideDetails: { type: Boolean, required: false },
|
|
@@ -12,10 +11,10 @@ const props = defineProps({
|
|
|
12
11
|
modelValue: { type: String, required: false },
|
|
13
12
|
errorMessages: { type: [Array, String], required: false },
|
|
14
13
|
type: { type: null, required: false },
|
|
15
|
-
disabled: { type: Boolean, required: false }
|
|
14
|
+
disabled: { type: Boolean, required: false },
|
|
15
|
+
rules: { type: Array, required: false }
|
|
16
16
|
});
|
|
17
17
|
const emit = defineEmits(["update:model-value"]);
|
|
18
|
-
const { requiredValidator } = ruleValidator();
|
|
19
18
|
const date = ref({
|
|
20
19
|
year: "",
|
|
21
20
|
month: "",
|
|
@@ -143,7 +142,8 @@ watch(() => props.modelValue, (val) => {
|
|
|
143
142
|
<VValidation
|
|
144
143
|
v-slot="{ errorMessages: validationErrors, isValid }"
|
|
145
144
|
v-model="date"
|
|
146
|
-
:rules="
|
|
145
|
+
:rules="rules"
|
|
146
|
+
validate-on="input lazy"
|
|
147
147
|
>
|
|
148
148
|
<div class="d-flex flex-column">
|
|
149
149
|
<VLabel
|
|
@@ -152,7 +152,7 @@ watch(() => props.modelValue, (val) => {
|
|
|
152
152
|
:text="LangLabel"
|
|
153
153
|
/>
|
|
154
154
|
<div class="app-date-input position-relative" style="min-height: 45px;" :class="{
|
|
155
|
-
'app-date-input--error': !isValid || yearIsInvalid,
|
|
155
|
+
'app-date-input--error': !isValid.value || yearIsInvalid,
|
|
156
156
|
'app-date-input--disabled': disabled
|
|
157
157
|
}">
|
|
158
158
|
<input
|
|
@@ -224,13 +224,13 @@ watch(() => props.modelValue, (val) => {
|
|
|
224
224
|
min-height: 40px;
|
|
225
225
|
height: 100%;
|
|
226
226
|
align-items: center;
|
|
227
|
-
border: 1px solid rgba(var(--v-border-color), 0.29);
|
|
227
|
+
border: 1px solid rgba(var(--v-border-color), 0.29) !important;
|
|
228
228
|
border-radius: 6px;
|
|
229
229
|
transition: all 0.5s;
|
|
230
230
|
box-sizing: border-box;
|
|
231
231
|
}
|
|
232
232
|
.app-date-input.app-date-input--error {
|
|
233
|
-
border-color: rgba(var(--v-theme-error), 1);
|
|
233
|
+
border-color: rgba(var(--v-theme-error), 1) !important;
|
|
234
234
|
}
|
|
235
235
|
.app-date-input.app-date-input--disabled {
|
|
236
236
|
border-color: rgba(var(--v-border-color), var(--v-border-opacity)) !important;
|
|
@@ -6,6 +6,7 @@ type __VLS_Props = {
|
|
|
6
6
|
errorMessages?: string[] | string;
|
|
7
7
|
type?: 'gregorian' | 'hijri' | string | undefined;
|
|
8
8
|
disabled?: boolean;
|
|
9
|
+
rules?: ((value: unknown) => string)[];
|
|
9
10
|
};
|
|
10
11
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
11
12
|
"update:model-value": (value: string) => any;
|
|
@@ -20,7 +20,7 @@ declare const headers: import("vue").ComputedRef<{
|
|
|
20
20
|
placeholder?: string;
|
|
21
21
|
type?: import("../../types").EditableDataTableItemType;
|
|
22
22
|
required?: boolean;
|
|
23
|
-
rules?: ((value: unknown) =>
|
|
23
|
+
rules?: ((value: unknown) => string)[];
|
|
24
24
|
renderDataOnMounted?: boolean;
|
|
25
25
|
renderDataOnBeforeMount?: boolean;
|
|
26
26
|
showDescription?: boolean;
|
|
@@ -161,6 +161,7 @@ const placeholder = (header) => {
|
|
|
161
161
|
:disable-if-empty="header.disableIfEmpty"
|
|
162
162
|
teleported
|
|
163
163
|
hide-details
|
|
164
|
+
:clearable="header.clearable"
|
|
164
165
|
/>
|
|
165
166
|
|
|
166
167
|
<AutocompleteInput
|
|
@@ -187,6 +188,7 @@ const placeholder = (header) => {
|
|
|
187
188
|
grouped
|
|
188
189
|
teleported
|
|
189
190
|
hide-details
|
|
191
|
+
:clearable="header.clearable"
|
|
190
192
|
/>
|
|
191
193
|
|
|
192
194
|
<DatePicker
|
|
@@ -226,7 +228,6 @@ const placeholder = (header) => {
|
|
|
226
228
|
class="pa-0 h-100 app-flex-1 app-max-w-150px app-input-outline"
|
|
227
229
|
:custom-id="`field.${index}.${header.key}`"
|
|
228
230
|
:error-messages="errorMessages"
|
|
229
|
-
:error="error"
|
|
230
231
|
hide-details
|
|
231
232
|
/>
|
|
232
233
|
|
|
@@ -235,6 +236,7 @@ const placeholder = (header) => {
|
|
|
235
236
|
v-model="item[header.key]"
|
|
236
237
|
class="pa-0 h-100 app-flex-1 app-input-outline"
|
|
237
238
|
:custom-id="`field.${index}.${header.key}`"
|
|
239
|
+
:rules="header.rules"
|
|
238
240
|
:type="item[header.dependsOn]"
|
|
239
241
|
:disabled="isDisabled"
|
|
240
242
|
:error-messages="errorMessages"
|
package/dist/types.d.ts
CHANGED
|
@@ -116,7 +116,7 @@ export type EditableDataTableItem = {
|
|
|
116
116
|
placeholder?: string
|
|
117
117
|
type?: EditableDataTableItemType
|
|
118
118
|
required?: boolean
|
|
119
|
-
rules?: ((value: unknown) =>
|
|
119
|
+
rules?: ((value: unknown) => string)[];
|
|
120
120
|
renderDataOnMounted?: boolean
|
|
121
121
|
renderDataOnBeforeMount?: boolean
|
|
122
122
|
showDescription?: boolean
|
package/dist/utils/hijriDate.js
CHANGED
|
@@ -60,7 +60,7 @@ class HDateClass {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
exports.HDateClass = HDateClass;
|
|
63
|
-
|
|
63
|
+
const currentLanguage = "en";
|
|
64
64
|
function vlidateHijri(year, month, day) {
|
|
65
65
|
if (month < 1 || month > 12) return false;
|
|
66
66
|
if (day < 1 || day > 30) return false;
|
|
@@ -121,7 +121,7 @@ function gregorianToHijri(pYear, pMonth, pDay) {
|
|
|
121
121
|
const c = Math.floor((b - 122.1) / 365.25);
|
|
122
122
|
const d = Math.floor(365.25 * c);
|
|
123
123
|
let monthResult = Math.floor((b - d) / 30.6001);
|
|
124
|
-
|
|
124
|
+
const dayResult = b - d - Math.floor(30.6001 * monthResult);
|
|
125
125
|
if (monthResult > 13) {
|
|
126
126
|
monthResult -= 12;
|
|
127
127
|
}
|
package/dist/utils/hijriDate.mjs
CHANGED
|
@@ -1824,7 +1824,7 @@ class HDateClass {
|
|
|
1824
1824
|
return "";
|
|
1825
1825
|
}
|
|
1826
1826
|
}
|
|
1827
|
-
|
|
1827
|
+
const currentLanguage = "en";
|
|
1828
1828
|
function vlidateHijri(year, month, day) {
|
|
1829
1829
|
if (month < 1 || month > 12)
|
|
1830
1830
|
return false;
|
|
@@ -1890,7 +1890,7 @@ function gregorianToHijri(pYear, pMonth, pDay) {
|
|
|
1890
1890
|
const c = Math.floor((b - 122.1) / 365.25);
|
|
1891
1891
|
const d = Math.floor(365.25 * c);
|
|
1892
1892
|
let monthResult = Math.floor((b - d) / 30.6001);
|
|
1893
|
-
|
|
1893
|
+
const dayResult = b - d - Math.floor(30.6001 * monthResult);
|
|
1894
1894
|
if (monthResult > 13) {
|
|
1895
1895
|
monthResult -= 12;
|
|
1896
1896
|
}
|
|
@@ -26,6 +26,12 @@ export declare const ruleValidator: () => {
|
|
|
26
26
|
ibanValidator: (value: unknown) => string | true;
|
|
27
27
|
dateValidator: (value: unknown) => string | true;
|
|
28
28
|
regexValidator: (value: string, regex: RegExp, message?: string) => string | true;
|
|
29
|
+
idNumberValidator: (value: string | number | null) => string | undefined;
|
|
30
|
+
requiredManualDateValidator: (value: {
|
|
31
|
+
year?: string;
|
|
32
|
+
month?: string;
|
|
33
|
+
day?: string;
|
|
34
|
+
}) => string | true;
|
|
29
35
|
};
|
|
30
36
|
export declare const useFormValidation: () => {
|
|
31
37
|
validateAndScroll: (refVForm: VForm | undefined) => Promise<boolean>;
|
|
@@ -36,6 +36,19 @@ const ruleValidator = () => {
|
|
|
36
36
|
}
|
|
37
37
|
return !!String(value).trim().length || t("validation.iban");
|
|
38
38
|
};
|
|
39
|
+
const idNumberValidator = value => {
|
|
40
|
+
const str = value?.toString() || "";
|
|
41
|
+
const validStarts = ["1", "2", "3", "4"];
|
|
42
|
+
if (str.length !== 10 || !validStarts.includes(str[0])) {
|
|
43
|
+
return t("validation.invalid");
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const requiredManualDateValidator = value => {
|
|
47
|
+
if ((0, _utils.isEmpty)(value?.day) || (0, _utils.isEmpty)(value?.month) || (0, _utils.isEmpty)(value?.year)) {
|
|
48
|
+
return t("validation.required");
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
};
|
|
39
52
|
const emailValidator = value => {
|
|
40
53
|
if ((0, _utils.isEmpty)(value)) {
|
|
41
54
|
return true;
|
|
@@ -153,7 +166,9 @@ const ruleValidator = () => {
|
|
|
153
166
|
lengthValidator,
|
|
154
167
|
ibanValidator,
|
|
155
168
|
dateValidator,
|
|
156
|
-
regexValidator
|
|
169
|
+
regexValidator,
|
|
170
|
+
idNumberValidator,
|
|
171
|
+
requiredManualDateValidator
|
|
157
172
|
};
|
|
158
173
|
};
|
|
159
174
|
exports.ruleValidator = ruleValidator;
|
|
@@ -28,6 +28,19 @@ export const ruleValidator = () => {
|
|
|
28
28
|
}
|
|
29
29
|
return !!String(value).trim().length || t("validation.iban");
|
|
30
30
|
};
|
|
31
|
+
const idNumberValidator = (value) => {
|
|
32
|
+
const str = value?.toString() || "";
|
|
33
|
+
const validStarts = ["1", "2", "3", "4"];
|
|
34
|
+
if (str.length !== 10 || !validStarts.includes(str[0])) {
|
|
35
|
+
return t("validation.invalid");
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const requiredManualDateValidator = (value) => {
|
|
39
|
+
if (isEmpty(value?.day) || isEmpty(value?.month) || isEmpty(value?.year)) {
|
|
40
|
+
return t("validation.required");
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
};
|
|
31
44
|
const emailValidator = (value) => {
|
|
32
45
|
if (isEmpty(value)) {
|
|
33
46
|
return true;
|
|
@@ -140,7 +153,9 @@ export const ruleValidator = () => {
|
|
|
140
153
|
lengthValidator,
|
|
141
154
|
ibanValidator,
|
|
142
155
|
dateValidator,
|
|
143
|
-
regexValidator
|
|
156
|
+
regexValidator,
|
|
157
|
+
idNumberValidator,
|
|
158
|
+
requiredManualDateValidator
|
|
144
159
|
};
|
|
145
160
|
};
|
|
146
161
|
export const useFormValidation = () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@winchsa/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@tanstack/eslint-plugin-query": "^5.73.3",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
48
49
|
"@types/node": "20.17.27",
|
|
49
50
|
"@vitejs/plugin-vue": "^4.6.2",
|
|
50
51
|
"eslint": "^8.57.1",
|
|
@@ -62,8 +63,8 @@
|
|
|
62
63
|
"scripts": {
|
|
63
64
|
"dev": "vite",
|
|
64
65
|
"build": "unbuild",
|
|
65
|
-
"lint": "eslint \"**/*.{ts,vue,mjs
|
|
66
|
-
"lint:fix": "eslint \"**/*.{ts,vue,mjs
|
|
66
|
+
"lint": "eslint \"**/*.{ts,vue,mjs}\"",
|
|
67
|
+
"lint:fix": "eslint \"**/*.{ts,vue,mjs}\" --fix",
|
|
67
68
|
"bump": "pnpm version patch && pnpm run build && git add . && git commit -m \"chore: release v$(node -p \"require('./package.json').version\")\""
|
|
68
69
|
}
|
|
69
70
|
}
|