@finema/core 1.3.22 → 1.3.24
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/module.d.mts +4 -4
- package/dist/module.d.ts +4 -4
- package/dist/module.json +1 -1
- package/dist/module.mjs +82 -4
- package/dist/runtime/components/Badge.vue +54 -0
- package/dist/runtime/components/Breadcrumb.vue +45 -0
- package/dist/runtime/components/Button/Group.vue +41 -25
- package/dist/runtime/components/Button/index.vue +55 -25
- package/dist/runtime/components/Card.vue +38 -0
- package/dist/runtime/components/Dropdown/index.vue +1 -0
- package/dist/runtime/components/Form/FieldWrapper.vue +7 -1
- package/dist/runtime/components/Form/types.d.ts +5 -13
- package/dist/runtime/components/Icon.vue +23 -11
- package/dist/runtime/components/Modal/index.vue +1 -0
- package/dist/runtime/components/Slideover/index.vue +1 -0
- package/dist/runtime/components/Table/index.vue +32 -6
- package/dist/runtime/components/Table/types.d.ts +1 -0
- package/dist/runtime/components/Tabs/index.vue +65 -0
- package/dist/runtime/composables/useForm.d.ts +1 -0
- package/dist/runtime/composables/useForm.mjs +2 -1
- package/dist/runtime/plugin.mjs +5 -5
- package/dist/runtime/types/config.d.ts +1 -1
- package/dist/runtime/types/utils.d.ts +29 -9
- package/dist/runtime/ui.config.d.ts +9 -0
- package/dist/runtime/ui.config.mjs +47 -1
- package/dist/runtime/utils/ObjectHelper.d.ts +1 -0
- package/dist/runtime/utils/ObjectHelper.mjs +6 -0
- package/package.json +2 -1
package/dist/module.d.mts
CHANGED
|
@@ -10,10 +10,10 @@ declare namespace config {
|
|
|
10
10
|
export { config_core as core };
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
type Strategy = 'merge' | 'override'
|
|
14
|
-
|
|
15
|
-
type DeepPartial<T> = Partial<{
|
|
16
|
-
[P in keyof T]: DeepPartial<T[P]> | Record<string, string>
|
|
13
|
+
type Strategy = 'merge' | 'override'
|
|
14
|
+
|
|
15
|
+
type DeepPartial<T> = Partial<{
|
|
16
|
+
[P in keyof T]: DeepPartial<T[P]> | Record<string, string>
|
|
17
17
|
}>
|
|
18
18
|
|
|
19
19
|
interface ModuleOptions {
|
package/dist/module.d.ts
CHANGED
|
@@ -10,10 +10,10 @@ declare namespace config {
|
|
|
10
10
|
export { config_core as core };
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
type Strategy = 'merge' | 'override'
|
|
14
|
-
|
|
15
|
-
type DeepPartial<T> = Partial<{
|
|
16
|
-
[P in keyof T]: DeepPartial<T[P]> | Record<string, string>
|
|
13
|
+
type Strategy = 'merge' | 'override'
|
|
14
|
+
|
|
15
|
+
type DeepPartial<T> = Partial<{
|
|
16
|
+
[P in keyof T]: DeepPartial<T[P]> | Record<string, string>
|
|
17
17
|
}>
|
|
18
18
|
|
|
19
19
|
interface ModuleOptions {
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { defineNuxtModule, createResolver, installModule, addPlugin, addComponen
|
|
|
2
2
|
import { merge } from 'lodash-es';
|
|
3
3
|
|
|
4
4
|
const name = "@finema/core";
|
|
5
|
-
const version = "1.3.
|
|
5
|
+
const version = "1.3.24";
|
|
6
6
|
|
|
7
7
|
const colors = {
|
|
8
8
|
black: "#20243E",
|
|
@@ -68,9 +68,86 @@ const colors = {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
const ui = {
|
|
71
|
+
strategy: "override",
|
|
71
72
|
safelistColors: ["secondary"],
|
|
72
73
|
icons: {
|
|
73
74
|
dynamic: true
|
|
75
|
+
},
|
|
76
|
+
pagination: {
|
|
77
|
+
wrapper: "flex items-center -space-x-px space-x-1",
|
|
78
|
+
default: {
|
|
79
|
+
activeButton: {
|
|
80
|
+
color: "primary",
|
|
81
|
+
class: "rounded-md px-3"
|
|
82
|
+
},
|
|
83
|
+
inactiveButton: {
|
|
84
|
+
color: "primary",
|
|
85
|
+
variant: "ghost",
|
|
86
|
+
class: "rounded-md px-3 text-gray-500 hover:bg-primary-500 hover:text-white"
|
|
87
|
+
},
|
|
88
|
+
firstButton: {
|
|
89
|
+
color: "primary",
|
|
90
|
+
variant: "ghost",
|
|
91
|
+
class: "rtl:[&_span:first-child]:rotate-180 rounded-md px-2 text-gray-500 hover:bg-primary-500 hover:text-white"
|
|
92
|
+
},
|
|
93
|
+
lastButton: {
|
|
94
|
+
color: "primary",
|
|
95
|
+
variant: "ghost",
|
|
96
|
+
class: "rtl:[&_span:last-child]:rotate-180 rounded-md px-2 text-gray-500 hover:bg-primary-500 hover:text-white"
|
|
97
|
+
},
|
|
98
|
+
prevButton: {
|
|
99
|
+
color: "primary",
|
|
100
|
+
variant: "ghost",
|
|
101
|
+
class: "rtl:[&_span:first-child]:rotate-180 rounded-md px-2 text-gray-500 hover:bg-primary-500 hover:text-white"
|
|
102
|
+
},
|
|
103
|
+
nextButton: {
|
|
104
|
+
color: "primary",
|
|
105
|
+
variant: "ghost",
|
|
106
|
+
class: "rtl:[&_span:last-child]:rotate-180 rounded-md px-2 text-gray-500 hover:bg-primary-500 hover:text-white"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
table: {
|
|
111
|
+
wrapper: "relative overflow-x-auto bg-white rounded-lg",
|
|
112
|
+
base: "min-w-full table-fixed",
|
|
113
|
+
divide: "divide-y divide-y-2 divide-gray-300 dark:divide-gray-700",
|
|
114
|
+
thead: "",
|
|
115
|
+
tbody: "divide-y divide-gray-200 dark:divide-gray-800",
|
|
116
|
+
tr: {
|
|
117
|
+
base: "even:bg-gray-50",
|
|
118
|
+
selected: "bg-gray-50 dark:bg-gray-800/50",
|
|
119
|
+
active: "hover:bg-gray-50 dark:hover:bg-gray-800/50 cursor-pointer"
|
|
120
|
+
},
|
|
121
|
+
th: {
|
|
122
|
+
base: "text-left rtl:text-right",
|
|
123
|
+
padding: "px-3 py-3.5",
|
|
124
|
+
color: "text-gray-700 dark:text-white",
|
|
125
|
+
font: "font-normal",
|
|
126
|
+
size: "text-sm"
|
|
127
|
+
},
|
|
128
|
+
td: {
|
|
129
|
+
base: "whitespace-nowrap",
|
|
130
|
+
padding: "px-3 py-4",
|
|
131
|
+
color: "text-gray-500 dark:text-gray-400",
|
|
132
|
+
font: "",
|
|
133
|
+
size: "text-sm"
|
|
134
|
+
},
|
|
135
|
+
default: {
|
|
136
|
+
sortButton: {
|
|
137
|
+
icon: "i-heroicons-arrows-up-down-20-solid",
|
|
138
|
+
trailing: true,
|
|
139
|
+
square: true,
|
|
140
|
+
color: "gray",
|
|
141
|
+
variant: "ghost",
|
|
142
|
+
class: "-m-1.5 text-gray-700 font-normal"
|
|
143
|
+
},
|
|
144
|
+
loadingState: {
|
|
145
|
+
label: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E42\u0E2B\u0E25\u0E14..."
|
|
146
|
+
},
|
|
147
|
+
emptyState: {
|
|
148
|
+
label: "\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
74
151
|
}
|
|
75
152
|
};
|
|
76
153
|
|
|
@@ -94,7 +171,7 @@ const module = defineNuxtModule({
|
|
|
94
171
|
nuxt.options.alias["#core"] = runtimeDir;
|
|
95
172
|
nuxt.options.css.push(resolve(runtimeDir, "ui.css"));
|
|
96
173
|
nuxt.options.appConfig.app = {
|
|
97
|
-
strategy: "
|
|
174
|
+
strategy: "override"
|
|
98
175
|
};
|
|
99
176
|
nuxt.hook("tailwindcss:config", (tailwindConfig) => {
|
|
100
177
|
tailwindConfig.content = {
|
|
@@ -102,7 +179,8 @@ const module = defineNuxtModule({
|
|
|
102
179
|
files: [
|
|
103
180
|
...tailwindConfig.content.files,
|
|
104
181
|
resolve(runtimeDir, "components/**/*.{vue,mjs,ts}"),
|
|
105
|
-
resolve(runtimeDir, "*.{mjs,js,ts}")
|
|
182
|
+
resolve(runtimeDir, "*.{mjs,js,ts}"),
|
|
183
|
+
resolve("./ui.ts")
|
|
106
184
|
]
|
|
107
185
|
};
|
|
108
186
|
tailwindConfig.theme.extend.colors = {
|
|
@@ -110,8 +188,8 @@ const module = defineNuxtModule({
|
|
|
110
188
|
...colors
|
|
111
189
|
};
|
|
112
190
|
});
|
|
113
|
-
nuxt.options.appConfig.ui = _merge(ui, nuxt.options.appConfig.ui);
|
|
114
191
|
await installModule("@nuxt/ui");
|
|
192
|
+
nuxt.options.appConfig.ui = _merge(ui, nuxt.options.appConfig.ui);
|
|
115
193
|
await installModule("@pinia/nuxt");
|
|
116
194
|
await installModule("@vee-validate/nuxt", {
|
|
117
195
|
// disable or enable auto imports
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UBadge
|
|
3
|
+
v-bind="attrs"
|
|
4
|
+
:class="$props.class"
|
|
5
|
+
:label="label"
|
|
6
|
+
:size="size"
|
|
7
|
+
:color="color"
|
|
8
|
+
:variant="variant"
|
|
9
|
+
:ui="ui"
|
|
10
|
+
>
|
|
11
|
+
<slot />
|
|
12
|
+
</UBadge>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup lang="ts">
|
|
16
|
+
import { useUiConfig, type PropType, useUI, toRef } from '#imports'
|
|
17
|
+
import { type BadgeSize, type BadgeColor, type BadgeVariant } from '#ui/types'
|
|
18
|
+
import { badge } from '#core/ui.config'
|
|
19
|
+
import type { Strategy } from '#core/types/utils'
|
|
20
|
+
|
|
21
|
+
const config = useUiConfig<typeof badge>(badge, 'badge')
|
|
22
|
+
|
|
23
|
+
const props = defineProps({
|
|
24
|
+
size: {
|
|
25
|
+
type: String as PropType<BadgeSize>,
|
|
26
|
+
default: () => badge.default.size,
|
|
27
|
+
validator(value: string) {
|
|
28
|
+
return Object.keys(badge.size).includes(value)
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
color: {
|
|
32
|
+
type: String as PropType<BadgeColor>,
|
|
33
|
+
default: () => badge.default.color,
|
|
34
|
+
},
|
|
35
|
+
variant: {
|
|
36
|
+
type: String as PropType<BadgeVariant>,
|
|
37
|
+
default: () => badge.default.variant,
|
|
38
|
+
},
|
|
39
|
+
label: {
|
|
40
|
+
type: [String, Number],
|
|
41
|
+
default: null,
|
|
42
|
+
},
|
|
43
|
+
class: {
|
|
44
|
+
type: [String, Object, Array] as PropType<any>,
|
|
45
|
+
default: () => '',
|
|
46
|
+
},
|
|
47
|
+
ui: {
|
|
48
|
+
type: Object as PropType<Partial<typeof config> & { strategy?: Strategy }>,
|
|
49
|
+
default: () => ({}),
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const { ui, attrs } = useUI('badge', toRef(props, 'ui'), config, toRef(props, 'class'))
|
|
54
|
+
</script>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UBreadcrumb v-bind="attrs" :class="$props.class" :links="links" :divider="divider" :ui="ui">
|
|
3
|
+
<template #default="{ link, isActive, index }">
|
|
4
|
+
<slot name="default" :link="link" :is-active="isActive" :index="index" />
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<template #icon="{ link, index, isActive }">
|
|
8
|
+
<slot name="icon" :link="link" :is-active="isActive" :index="index" />
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<template #divider>
|
|
12
|
+
<slot name="divider" />
|
|
13
|
+
</template>
|
|
14
|
+
</UBreadcrumb>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
import { useUiConfig, type PropType, useUI, toRef } from '#imports'
|
|
19
|
+
import { type BreadcrumbLink } from '#ui/types'
|
|
20
|
+
import type { Strategy } from '#core/types/utils'
|
|
21
|
+
import { breadcrumb } from '#core/ui.config'
|
|
22
|
+
|
|
23
|
+
const config = useUiConfig<typeof breadcrumb>(breadcrumb, 'breadcrumb')
|
|
24
|
+
|
|
25
|
+
const props = defineProps({
|
|
26
|
+
links: {
|
|
27
|
+
type: Array as PropType<BreadcrumbLink[]>,
|
|
28
|
+
default: () => [],
|
|
29
|
+
},
|
|
30
|
+
divider: {
|
|
31
|
+
type: String,
|
|
32
|
+
default: () => breadcrumb.default.divider,
|
|
33
|
+
},
|
|
34
|
+
class: {
|
|
35
|
+
type: [String, Object, Array] as PropType<any>,
|
|
36
|
+
default: () => '',
|
|
37
|
+
},
|
|
38
|
+
ui: {
|
|
39
|
+
type: Object as PropType<Partial<typeof config> & { strategy?: Strategy }>,
|
|
40
|
+
default: () => ({}),
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const { ui, attrs } = useUI('breadcrumb', toRef(props, 'ui'), config, toRef(props, 'class'))
|
|
45
|
+
</script>
|
|
@@ -1,31 +1,47 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
stroke="currentColor"
|
|
12
|
-
class="h-3 w-3"
|
|
13
|
-
>
|
|
14
|
-
<path
|
|
15
|
-
stroke-linecap="round"
|
|
16
|
-
stroke-linejoin="round"
|
|
17
|
-
d="M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3"
|
|
18
|
-
/>
|
|
19
|
-
</svg>
|
|
20
|
-
</Button>
|
|
21
|
-
</UButtonGroup>
|
|
22
|
-
</div>
|
|
2
|
+
<UButtonGroup
|
|
3
|
+
v-bind="attrs"
|
|
4
|
+
:class="$props.class"
|
|
5
|
+
:size="size"
|
|
6
|
+
:orientation="orientation"
|
|
7
|
+
:ui="ui"
|
|
8
|
+
>
|
|
9
|
+
<slot />
|
|
10
|
+
</UButtonGroup>
|
|
23
11
|
</template>
|
|
24
12
|
|
|
25
13
|
<script lang="ts" setup>
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
import { type PropType, useUiConfig, useUI, toRef } from '#imports'
|
|
15
|
+
import { button, buttonGroup } from '#core/ui.config'
|
|
16
|
+
import { type ButtonSize } from '#ui/types/button'
|
|
17
|
+
import { type Strategy } from '#core/types/utils'
|
|
18
|
+
|
|
19
|
+
const config = useUiConfig<typeof buttonGroup>(buttonGroup, 'buttonGroup')
|
|
20
|
+
|
|
21
|
+
const props = defineProps({
|
|
22
|
+
size: {
|
|
23
|
+
type: String as PropType<ButtonSize>,
|
|
24
|
+
default: () => button.default.size,
|
|
25
|
+
validator(value: string) {
|
|
26
|
+
return Object.keys(button.size).includes(value)
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
orientation: {
|
|
30
|
+
type: String as PropType<'horizontal' | 'vertical'>,
|
|
31
|
+
default: 'horizontal',
|
|
32
|
+
validator(value: string) {
|
|
33
|
+
return ['horizontal', 'vertical'].includes(value)
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
class: {
|
|
37
|
+
type: [String, Object, Array] as PropType<any>,
|
|
38
|
+
default: undefined,
|
|
39
|
+
},
|
|
40
|
+
ui: {
|
|
41
|
+
type: Object as PropType<Partial<typeof config> & { strategy?: Strategy }>,
|
|
42
|
+
default: undefined,
|
|
43
|
+
},
|
|
28
44
|
})
|
|
29
|
-
</script>
|
|
30
45
|
|
|
31
|
-
|
|
46
|
+
const { ui, attrs } = useUI('buttonGroup', toRef(props, 'ui'), config, toRef(props, 'class'))
|
|
47
|
+
</script>
|
|
@@ -1,36 +1,58 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<UButton
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<UButton
|
|
3
|
+
v-bind="attrs"
|
|
4
|
+
:class="$props.class"
|
|
5
|
+
:label="label"
|
|
6
|
+
:type="type"
|
|
7
|
+
:block="block"
|
|
8
|
+
:loading="loading"
|
|
9
|
+
:disabled="disabled"
|
|
10
|
+
:padded="padded"
|
|
11
|
+
:size="size"
|
|
12
|
+
:color="color"
|
|
13
|
+
:variant="variant"
|
|
14
|
+
:icon="icon"
|
|
15
|
+
:loading-icon="loadingIcon"
|
|
16
|
+
:leading-icon="leadingIcon"
|
|
17
|
+
:trailing-icon="trailingIcon"
|
|
18
|
+
:trailing="trailing"
|
|
19
|
+
:leading="leading"
|
|
20
|
+
:square="square"
|
|
21
|
+
:truncate="truncate"
|
|
22
|
+
:ui="ui"
|
|
23
|
+
>
|
|
24
|
+
<template #leading><slot name="leading" /></template>
|
|
7
25
|
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
</template>
|
|
26
|
+
<slot />
|
|
27
|
+
<template #trailing><slot name="trailing" /></template>
|
|
11
28
|
</UButton>
|
|
12
29
|
</template>
|
|
30
|
+
|
|
13
31
|
<script lang="ts" setup>
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
32
|
+
import { useUiConfig, toRef, type PropType, useUI } from '#imports'
|
|
33
|
+
import { button } from '#core/ui.config'
|
|
34
|
+
import { type ButtonSize, type ButtonColor, type ButtonVariant } from '#ui/types/button'
|
|
35
|
+
import { type Strategy } from '#core/types/utils'
|
|
36
|
+
|
|
37
|
+
const config = useUiConfig<typeof button>(button, 'button')
|
|
16
38
|
|
|
17
39
|
defineOptions({
|
|
18
40
|
inheritAttrs: true,
|
|
19
41
|
})
|
|
20
42
|
|
|
21
|
-
defineProps({
|
|
22
|
-
|
|
43
|
+
const props = defineProps({
|
|
44
|
+
label: {
|
|
23
45
|
type: String,
|
|
46
|
+
default: '',
|
|
47
|
+
},
|
|
48
|
+
type: {
|
|
49
|
+
type: String as PropType<'button' | 'submit' | 'reset'>,
|
|
24
50
|
default: 'button',
|
|
25
51
|
},
|
|
26
52
|
block: {
|
|
27
53
|
type: Boolean,
|
|
28
54
|
default: false,
|
|
29
55
|
},
|
|
30
|
-
label: {
|
|
31
|
-
type: String,
|
|
32
|
-
default: null,
|
|
33
|
-
},
|
|
34
56
|
loading: {
|
|
35
57
|
type: Boolean,
|
|
36
58
|
default: false,
|
|
@@ -44,24 +66,28 @@ defineProps({
|
|
|
44
66
|
default: true,
|
|
45
67
|
},
|
|
46
68
|
size: {
|
|
47
|
-
type: String
|
|
48
|
-
|
|
49
|
-
|
|
69
|
+
type: String as PropType<ButtonSize>,
|
|
70
|
+
default: () => button.default.size,
|
|
71
|
+
validator(value: string) {
|
|
72
|
+
return Object.keys(button.size).includes(value)
|
|
50
73
|
},
|
|
51
74
|
},
|
|
52
75
|
color: {
|
|
53
|
-
type: String
|
|
76
|
+
type: String as PropType<ButtonColor>,
|
|
77
|
+
default: () => button.default.color,
|
|
54
78
|
},
|
|
55
79
|
variant: {
|
|
80
|
+
type: String as PropType<ButtonVariant>,
|
|
81
|
+
default: () => button.default.variant,
|
|
82
|
+
},
|
|
83
|
+
loadingIcon: {
|
|
56
84
|
type: String,
|
|
85
|
+
default: () => button.default.loadingIcon,
|
|
57
86
|
},
|
|
58
87
|
icon: {
|
|
59
88
|
type: String,
|
|
60
89
|
default: null,
|
|
61
90
|
},
|
|
62
|
-
loadingIcon: {
|
|
63
|
-
type: String,
|
|
64
|
-
},
|
|
65
91
|
leadingIcon: {
|
|
66
92
|
type: String,
|
|
67
93
|
default: null,
|
|
@@ -87,10 +113,14 @@ defineProps({
|
|
|
87
113
|
default: false,
|
|
88
114
|
},
|
|
89
115
|
class: {
|
|
90
|
-
type: [String,
|
|
116
|
+
type: [String, Array, Object] as PropType<any>,
|
|
117
|
+
default: undefined,
|
|
91
118
|
},
|
|
92
119
|
ui: {
|
|
93
|
-
type: Object
|
|
120
|
+
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
|
|
121
|
+
default: undefined,
|
|
94
122
|
},
|
|
95
123
|
})
|
|
124
|
+
|
|
125
|
+
const { ui, attrs } = useUI('button', toRef(props, 'ui'), config, toRef(props, 'class'))
|
|
96
126
|
</script>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UCard v-bind="attrs" :class="$props.class" :as="as" :ui="ui">
|
|
3
|
+
<template #header>
|
|
4
|
+
<slot name="header" />
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<slot />
|
|
8
|
+
|
|
9
|
+
<template #footer>
|
|
10
|
+
<slot name="footer" />
|
|
11
|
+
</template>
|
|
12
|
+
</UCard>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup lang="ts">
|
|
16
|
+
import { useUiConfig, type PropType, useUI, toRef } from '#imports'
|
|
17
|
+
import type { Strategy } from '#core/types/utils'
|
|
18
|
+
import { card } from '#core/ui.config'
|
|
19
|
+
|
|
20
|
+
const config = useUiConfig<typeof card>(card, 'card')
|
|
21
|
+
|
|
22
|
+
const props = defineProps({
|
|
23
|
+
as: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: 'div',
|
|
26
|
+
},
|
|
27
|
+
class: {
|
|
28
|
+
type: [String, Object, Array] as PropType<any>,
|
|
29
|
+
default: () => '',
|
|
30
|
+
},
|
|
31
|
+
ui: {
|
|
32
|
+
type: Object as PropType<Partial<typeof config> & { strategy?: Strategy }>,
|
|
33
|
+
default: () => ({}),
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const { ui, attrs } = useUI('card', toRef(props, 'ui'), config, toRef(props, 'class'))
|
|
38
|
+
</script>
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<UFormGroup
|
|
2
|
+
<UFormGroup
|
|
3
|
+
:label="label"
|
|
4
|
+
:name="name"
|
|
5
|
+
:help="help"
|
|
6
|
+
:error="errorMessage"
|
|
7
|
+
:required="!!isRequired"
|
|
8
|
+
>
|
|
3
9
|
<slot />
|
|
4
10
|
</UFormGroup>
|
|
5
11
|
</template>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Component } from '@nuxt/schema';
|
|
2
|
-
import { type FormContext
|
|
2
|
+
import { type FormContext } from 'vee-validate';
|
|
3
3
|
import { type ITextField } from '#core/components/Form/InputText/types';
|
|
4
4
|
import { type IStaticField } from '#core/components/Form/InputStatic/types';
|
|
5
5
|
import { type ICheckboxField } from '#core/components/Form/InputCheckbox/types';
|
|
@@ -21,19 +21,11 @@ export declare const enum INPUT_TYPES {
|
|
|
21
21
|
DATE_TIME = "DATE_TIME",
|
|
22
22
|
DATE = "DATE"
|
|
23
23
|
}
|
|
24
|
-
export interface IOption {
|
|
25
|
-
label: string;
|
|
26
|
-
value: any;
|
|
27
|
-
}
|
|
28
|
-
export interface IRadioOption {
|
|
29
|
-
label: string | any;
|
|
30
|
-
value: any;
|
|
31
|
-
}
|
|
32
24
|
export interface IFieldProps {
|
|
33
25
|
form?: FormContext;
|
|
34
26
|
name: string;
|
|
35
27
|
label?: string | any;
|
|
36
|
-
rules?:
|
|
28
|
+
rules?: any;
|
|
37
29
|
autoFocus?: boolean;
|
|
38
30
|
class?: any;
|
|
39
31
|
classInner?: any;
|
|
@@ -48,12 +40,12 @@ export interface IFieldProps {
|
|
|
48
40
|
transform?: (value: any, oldValue: any, e: InputEvent) => any;
|
|
49
41
|
getInstance?: (el: HTMLElement) => void;
|
|
50
42
|
}
|
|
51
|
-
export interface IFormFieldBase<I extends INPUT_TYPES, P
|
|
52
|
-
type: I
|
|
43
|
+
export interface IFormFieldBase<I extends INPUT_TYPES, P, O> {
|
|
44
|
+
type: I;
|
|
53
45
|
component?: Component;
|
|
54
46
|
class?: any;
|
|
55
47
|
isHide?: boolean;
|
|
56
|
-
props:
|
|
48
|
+
props: P;
|
|
57
49
|
on?: O;
|
|
58
50
|
}
|
|
59
51
|
export type IFormField = ITextField | IStaticField | ICheckboxField | IRadioField | ISelectField | IToggleField | ITextareaField | IDateTimeField;
|
|
@@ -1,11 +1,23 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<UIcon :name="name" />
|
|
3
|
-
</template>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<UIcon :name="name" :dynamic="dynamicValue" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script lang="ts" setup>
|
|
6
|
+
import { computed, useUiConfig } from '#imports'
|
|
7
|
+
import { icon } from '#core/ui.config'
|
|
8
|
+
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
name: {
|
|
11
|
+
type: String,
|
|
12
|
+
required: true,
|
|
13
|
+
},
|
|
14
|
+
dynamic: {
|
|
15
|
+
type: Boolean,
|
|
16
|
+
default: false,
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const config = useUiConfig<typeof icon>(icon, 'icon')
|
|
21
|
+
|
|
22
|
+
const dynamicValue = computed(() => props.dynamic || config.dynamic)
|
|
23
|
+
</script>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
3
|
<div
|
|
4
|
-
v-if="
|
|
5
|
-
class="flex border-b border-gray-200
|
|
4
|
+
v-if="options.isEnabledSearch"
|
|
5
|
+
class="flex border-b border-gray-200 py-3.5 dark:border-gray-700"
|
|
6
6
|
>
|
|
7
7
|
<UInput v-model="q" placeholder="Search..." />
|
|
8
8
|
</div>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
>
|
|
15
15
|
<template #empty-state>
|
|
16
16
|
<div class="flex flex-col items-center justify-center gap-3 py-6">
|
|
17
|
-
<span class="text-sm italic"
|
|
17
|
+
<span class="text-sm italic">ไม่พบข้อมูล!</span>
|
|
18
18
|
</div>
|
|
19
19
|
</template>
|
|
20
20
|
<template
|
|
@@ -42,7 +42,10 @@
|
|
|
42
42
|
<slot :name="slot" v-bind="scope" />
|
|
43
43
|
</template>
|
|
44
44
|
</UTable>
|
|
45
|
-
<div class="mt-4 flex justify-
|
|
45
|
+
<div class="mt-4 flex justify-between">
|
|
46
|
+
<p class="text-xs text-gray-500">
|
|
47
|
+
ผลลัพธ์ {{ pageBetween }} ของ {{ totalCountWithComma }} รายการ
|
|
48
|
+
</p>
|
|
46
49
|
<UPagination
|
|
47
50
|
v-model="page"
|
|
48
51
|
:page-count="options.pageOptions.totalPage"
|
|
@@ -52,9 +55,9 @@
|
|
|
52
55
|
</div>
|
|
53
56
|
</template>
|
|
54
57
|
<script lang="ts" setup>
|
|
55
|
-
import { type PropType } from 'vue'
|
|
58
|
+
import { computed, type PropType } from 'vue'
|
|
56
59
|
import { COLUMN_TYPES, type ITableOptions } from '#core/components/Table/types'
|
|
57
|
-
import { _debounce, ref, watch } from '#imports'
|
|
60
|
+
import { _debounce, ref, StringHelper, watch } from '#imports'
|
|
58
61
|
import ColumnNumber from '#core/components/Table/ColumnNumber.vue'
|
|
59
62
|
import ColumnImage from '#core/components/Table/ColumnImage.vue'
|
|
60
63
|
|
|
@@ -65,6 +68,10 @@ const emits = defineEmits<{
|
|
|
65
68
|
|
|
66
69
|
const props = defineProps({
|
|
67
70
|
options: { type: Object as PropType<ITableOptions>, required: true },
|
|
71
|
+
class: {
|
|
72
|
+
type: [String, Array, Object] as PropType<any>,
|
|
73
|
+
default: undefined,
|
|
74
|
+
},
|
|
68
75
|
})
|
|
69
76
|
|
|
70
77
|
const q = ref(props.options?.pageOptions.search ?? '')
|
|
@@ -81,4 +88,23 @@ watch(
|
|
|
81
88
|
watch(page, () => {
|
|
82
89
|
emits('pageChange', page.value)
|
|
83
90
|
})
|
|
91
|
+
|
|
92
|
+
const pageBetween = computed((): string => {
|
|
93
|
+
const length = props.options?.rawData?.length
|
|
94
|
+
|
|
95
|
+
if (length === 0) {
|
|
96
|
+
return '0'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const start = (props.options.pageOptions.currentPage - 1) * props.options.pageOptions.limit + 1
|
|
100
|
+
const end = start + length - 1
|
|
101
|
+
|
|
102
|
+
return `${start} - ${end}`
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const totalCountWithComma = computed((): string => {
|
|
106
|
+
return !props.options.pageOptions.totalCount
|
|
107
|
+
? '0'
|
|
108
|
+
: StringHelper.withComma(props.options.pageOptions.totalCount)
|
|
109
|
+
})
|
|
84
110
|
</script>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UTabs
|
|
3
|
+
v-bind="attrs"
|
|
4
|
+
:model-value="modelValue"
|
|
5
|
+
:class="$props.class"
|
|
6
|
+
:items="items"
|
|
7
|
+
:orientation="orientation"
|
|
8
|
+
:default-index="defaultIndex"
|
|
9
|
+
:ui="ui"
|
|
10
|
+
@change="change"
|
|
11
|
+
>
|
|
12
|
+
<template #default="{ item, index, selected }">
|
|
13
|
+
<slot name="default" :item="item" :index="index" :selected="selected" />
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<template #item="{ item, index, selected }">
|
|
17
|
+
<slot name="item" :item="item" :index="index" :selected="selected" />
|
|
18
|
+
</template>
|
|
19
|
+
</UTabs>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script setup lang="ts">
|
|
23
|
+
import { useUiConfig, type PropType, useUI, toRef } from '#imports'
|
|
24
|
+
import { type TabItem } from '#ui/types'
|
|
25
|
+
import type { Strategy } from '#core/types/utils'
|
|
26
|
+
import { tabs } from '#core/ui.config'
|
|
27
|
+
|
|
28
|
+
const config = useUiConfig<typeof tabs>(tabs, 'tabs')
|
|
29
|
+
|
|
30
|
+
const props = defineProps({
|
|
31
|
+
modelValue: {
|
|
32
|
+
type: Number,
|
|
33
|
+
default: undefined,
|
|
34
|
+
},
|
|
35
|
+
items: {
|
|
36
|
+
type: Array as PropType<TabItem[]>,
|
|
37
|
+
default: () => [],
|
|
38
|
+
},
|
|
39
|
+
orientation: {
|
|
40
|
+
type: String as PropType<'horizontal' | 'vertical'>,
|
|
41
|
+
default: 'horizontal',
|
|
42
|
+
validator: (value: string) => ['horizontal', 'vertical'].includes(value),
|
|
43
|
+
},
|
|
44
|
+
defaultIndex: {
|
|
45
|
+
type: Number,
|
|
46
|
+
default: 0,
|
|
47
|
+
},
|
|
48
|
+
class: {
|
|
49
|
+
type: [String, Object, Array] as PropType<any>,
|
|
50
|
+
default: () => '',
|
|
51
|
+
},
|
|
52
|
+
ui: {
|
|
53
|
+
type: Object as PropType<Partial<typeof config> & { strategy?: Strategy }>,
|
|
54
|
+
default: () => ({}),
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const emits = defineEmits(['update:modelValue', 'change'])
|
|
59
|
+
|
|
60
|
+
const change = (index: number) => {
|
|
61
|
+
emits('change', index)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const { ui, attrs } = useUI('tabs', toRef(props, 'ui'), config, toRef(props, 'class'))
|
|
65
|
+
</script>
|
|
@@ -36,7 +36,8 @@ export const useFieldHOC = (newFormProps, opts) => {
|
|
|
36
36
|
isRequired: newFormProps.isRequired,
|
|
37
37
|
isHideLabel: newFormProps.isHideLabel,
|
|
38
38
|
customErrorMessage: newFormProps.customErrorMessage,
|
|
39
|
-
name: newFormProps.name
|
|
39
|
+
name: newFormProps.name,
|
|
40
|
+
help: newFormProps.help
|
|
40
41
|
}))
|
|
41
42
|
};
|
|
42
43
|
};
|
package/dist/runtime/plugin.mjs
CHANGED
|
@@ -25,12 +25,12 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
25
25
|
not_multiple_of: "\u0E08\u0E33\u0E40\u0E1B\u0E47\u0E19\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19\u0E2D\u0E22\u0E39\u0E48\u0E43\u0E19\u0E04\u0E48\u0E32\u0E02\u0E2D\u0E07 {{multipleOf}}",
|
|
26
26
|
not_finite: "\u0E15\u0E31\u0E27\u0E40\u0E25\u0E02\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19\u0E08\u0E33\u0E19\u0E27\u0E19\u0E08\u0E23\u0E34\u0E07",
|
|
27
27
|
invalid_string: {
|
|
28
|
-
email: "\u0E2D\u0E35\u0E40\u0E21\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07
|
|
29
|
-
url: "URL \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07
|
|
30
|
-
uuid: "UUID \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07
|
|
31
|
-
cuid: "CUID \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07
|
|
28
|
+
email: "\u0E2D\u0E35\u0E40\u0E21\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
29
|
+
url: "URL \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
30
|
+
uuid: "UUID \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
31
|
+
cuid: "CUID \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
32
32
|
regex: "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
33
|
-
datetime: "\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E41\u0E25\u0E30\u0E40\u0E27\u0E25\u0E32\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07
|
|
33
|
+
datetime: "\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E41\u0E25\u0E30\u0E40\u0E27\u0E25\u0E32\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
34
34
|
startsWith: '\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E08\u0E30\u0E15\u0E49\u0E2D\u0E07\u0E02\u0E36\u0E49\u0E19\u0E15\u0E49\u0E19\u0E14\u0E49\u0E27\u0E22 "{{startsWith}}"',
|
|
35
35
|
endsWith: '\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E08\u0E30\u0E15\u0E49\u0E2D\u0E07\u0E25\u0E07\u0E17\u0E49\u0E32\u0E22\u0E14\u0E49\u0E27\u0E22 "{{endsWith}}"'
|
|
36
36
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type UIComponentList = 'modal' | 'slideover' | 'dropdown';
|
|
1
|
+
export type UIComponentList = 'modal' | 'slideover' | 'dropdown' | 'icon' | 'button' | 'buttonGroup' | 'tabs' | 'card' | 'breadcrumb' | 'badge';
|
|
@@ -1,9 +1,29 @@
|
|
|
1
|
-
export type Strategy = 'merge' | 'override'
|
|
2
|
-
|
|
3
|
-
export type NestedKeyOf<ObjectType extends object> = {
|
|
4
|
-
[Key in keyof ObjectType]: ObjectType[Key] extends object ? NestedKeyOf<ObjectType[Key]> : Key
|
|
5
|
-
}[keyof ObjectType]
|
|
6
|
-
|
|
7
|
-
export type DeepPartial<T> = Partial<{
|
|
8
|
-
[P in keyof T]: DeepPartial<T[P]> | Record<string, string>
|
|
9
|
-
}>
|
|
1
|
+
export type Strategy = 'merge' | 'override'
|
|
2
|
+
|
|
3
|
+
export type NestedKeyOf<ObjectType extends object> = {
|
|
4
|
+
[Key in keyof ObjectType]: ObjectType[Key] extends object ? NestedKeyOf<ObjectType[Key]> : Key
|
|
5
|
+
}[keyof ObjectType]
|
|
6
|
+
|
|
7
|
+
export type DeepPartial<T> = Partial<{
|
|
8
|
+
[P in keyof T]: DeepPartial<T[P]> | Record<string, string>
|
|
9
|
+
}>
|
|
10
|
+
|
|
11
|
+
type DeepKey<T, Keys extends string[]> = Keys extends [infer First, ...infer Rest]
|
|
12
|
+
? First extends keyof T
|
|
13
|
+
? Rest extends string[]
|
|
14
|
+
? DeepKey<T[First], Rest>
|
|
15
|
+
: never
|
|
16
|
+
: never
|
|
17
|
+
: T
|
|
18
|
+
|
|
19
|
+
export type ExtractDeepKey<T, Path extends string[]> = DeepKey<T, Path> extends infer Result
|
|
20
|
+
? Result extends Record<string, any>
|
|
21
|
+
? keyof Result
|
|
22
|
+
: never
|
|
23
|
+
: never
|
|
24
|
+
|
|
25
|
+
export type ExtractDeepObject<T, Path extends string[]> = DeepKey<T, Path> extends infer Result
|
|
26
|
+
? Result extends Record<string, any>
|
|
27
|
+
? Result
|
|
28
|
+
: never
|
|
29
|
+
: never
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
+
export declare const icon: {
|
|
2
|
+
dynamic: boolean;
|
|
3
|
+
};
|
|
4
|
+
export declare const card: any;
|
|
5
|
+
export declare const breadcrumb: any;
|
|
6
|
+
export declare const buttonGroup: any;
|
|
7
|
+
export declare const button: any;
|
|
1
8
|
export declare const modal: any;
|
|
2
9
|
export declare const slideover: any;
|
|
10
|
+
export declare const tabs: any;
|
|
11
|
+
export declare const badge: any;
|
|
@@ -1,4 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
modal as inheritModal,
|
|
3
|
+
slideover as inheritSlideover,
|
|
4
|
+
button as inheritButton,
|
|
5
|
+
buttonGroup as inheritButtonGroup,
|
|
6
|
+
tabs as inheritTabs,
|
|
7
|
+
card as inheritCard,
|
|
8
|
+
breadcrumb as inheritBreadcrumb,
|
|
9
|
+
badge as inheritBadge
|
|
10
|
+
} from "#ui/ui.config";
|
|
11
|
+
export const icon = {
|
|
12
|
+
dynamic: false
|
|
13
|
+
};
|
|
14
|
+
export const card = { ...inheritCard };
|
|
15
|
+
export const breadcrumb = {
|
|
16
|
+
...inheritBreadcrumb,
|
|
17
|
+
default: {
|
|
18
|
+
divider: "i-heroicons-chevron-right-20-solid rtl:i-heroicons-chevron-left-20-solid"
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export const buttonGroup = {
|
|
22
|
+
...inheritButtonGroup,
|
|
23
|
+
default: {
|
|
24
|
+
size: "md",
|
|
25
|
+
orientation: "horizontal"
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
export const button = {
|
|
29
|
+
...inheritButton,
|
|
30
|
+
default: {
|
|
31
|
+
size: "md",
|
|
32
|
+
variant: "solid",
|
|
33
|
+
color: "primary",
|
|
34
|
+
loadingIcon: "i-heroicons-arrow-path-20-solid"
|
|
35
|
+
}
|
|
36
|
+
};
|
|
2
37
|
export const modal = {
|
|
3
38
|
...inheritModal,
|
|
4
39
|
header: "px-4 py-2 border-b",
|
|
@@ -42,3 +77,14 @@ export const slideover = {
|
|
|
42
77
|
size: "md"
|
|
43
78
|
}
|
|
44
79
|
};
|
|
80
|
+
export const tabs = {
|
|
81
|
+
...inheritTabs
|
|
82
|
+
};
|
|
83
|
+
export const badge = {
|
|
84
|
+
...inheritBadge,
|
|
85
|
+
default: {
|
|
86
|
+
size: "sm",
|
|
87
|
+
variant: "solid",
|
|
88
|
+
color: "primary"
|
|
89
|
+
}
|
|
90
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finema/core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.24",
|
|
4
4
|
"repository": "https://gitlab.finema.co/finema/ui-kit",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Finema Development Team",
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"nuxt": "^3.7.4",
|
|
70
70
|
"prettier": "^3.0.3",
|
|
71
71
|
"release-it": "^16.2.1",
|
|
72
|
+
"sass": "^1.69.5",
|
|
72
73
|
"stylelint": "^15.10.3",
|
|
73
74
|
"stylelint-config-prettier-scss": "^1.0.0",
|
|
74
75
|
"stylelint-config-standard-scss": "^11.0.0",
|