@finema/core 1.4.115 → 1.4.117

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.
Files changed (74) hide show
  1. package/README.md +60 -60
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +1 -1
  4. package/dist/runtime/components/Alert.vue +48 -48
  5. package/dist/runtime/components/Avatar.vue +27 -27
  6. package/dist/runtime/components/Badge.vue +11 -11
  7. package/dist/runtime/components/Breadcrumb.vue +44 -44
  8. package/dist/runtime/components/Button/Group.vue +37 -37
  9. package/dist/runtime/components/Button/index.vue +75 -75
  10. package/dist/runtime/components/Card.vue +38 -38
  11. package/dist/runtime/components/Core.vue +13 -13
  12. package/dist/runtime/components/Dialog/index.vue +108 -108
  13. package/dist/runtime/components/Dropdown/index.vue +70 -70
  14. package/dist/runtime/components/FlexDeck/Base.vue +90 -90
  15. package/dist/runtime/components/FlexDeck/index.vue +66 -66
  16. package/dist/runtime/components/Form/FieldWrapper.vue +23 -23
  17. package/dist/runtime/components/Form/Fields.vue +230 -222
  18. package/dist/runtime/components/Form/InputCheckbox/index.vue +21 -21
  19. package/dist/runtime/components/Form/InputDateTime/index.vue +60 -60
  20. package/dist/runtime/components/Form/InputDateTimeRange/index.vue +83 -83
  21. package/dist/runtime/components/Form/InputNumber/index.vue +27 -27
  22. package/dist/runtime/components/Form/InputRadio/index.vue +27 -27
  23. package/dist/runtime/components/Form/InputSelect/index.vue +36 -36
  24. package/dist/runtime/components/Form/InputSelect/types.d.ts +2 -1
  25. package/dist/runtime/components/Form/InputSelectMultiple/index.vue +51 -0
  26. package/dist/runtime/components/Form/InputSelectMultiple/types.d.ts +15 -0
  27. package/dist/runtime/components/Form/InputSelectMultiple/types.mjs +0 -0
  28. package/dist/runtime/components/Form/InputStatic/index.vue +16 -16
  29. package/dist/runtime/components/Form/InputTags/index.vue +145 -134
  30. package/dist/runtime/components/Form/InputText/index.vue +67 -67
  31. package/dist/runtime/components/Form/InputTextarea/index.vue +25 -25
  32. package/dist/runtime/components/Form/InputToggle/index.vue +14 -14
  33. package/dist/runtime/components/Form/InputUploadDropzone/index.vue +206 -206
  34. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue +341 -333
  35. package/dist/runtime/components/Form/InputUploadDropzoneAuto/types.d.ts +2 -1
  36. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/{Item.vue → ItemUpload.vue} +241 -260
  37. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/ItemView.vue +89 -0
  38. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue +164 -140
  39. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/types.d.ts +4 -3
  40. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/{item.vue → ItemUpload.vue} +161 -179
  41. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/ItemView.vue +64 -0
  42. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/index.vue +172 -148
  43. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/types.d.ts +4 -3
  44. package/dist/runtime/components/Form/InputUploadFileClassic/index.vue +95 -95
  45. package/dist/runtime/components/Form/InputUploadFileClassicAuto/index.vue +151 -143
  46. package/dist/runtime/components/Form/InputUploadFileClassicAuto/types.d.ts +2 -1
  47. package/dist/runtime/components/Form/InputUploadImageAuto/index.vue +219 -222
  48. package/dist/runtime/components/Form/InputUploadImageAuto/types.d.ts +2 -1
  49. package/dist/runtime/components/Form/InputWYSIWYG/index.vue +53 -53
  50. package/dist/runtime/components/Form/index.vue +6 -6
  51. package/dist/runtime/components/Form/types.d.ts +9 -1
  52. package/dist/runtime/components/Form/types.mjs +1 -0
  53. package/dist/runtime/components/Icon.vue +23 -23
  54. package/dist/runtime/components/Image.vue +36 -36
  55. package/dist/runtime/components/Loader.vue +27 -27
  56. package/dist/runtime/components/Modal/index.vue +146 -146
  57. package/dist/runtime/components/QRCode.vue +22 -22
  58. package/dist/runtime/components/SimplePagination.vue +96 -96
  59. package/dist/runtime/components/Slideover/index.vue +110 -110
  60. package/dist/runtime/components/Table/Base.vue +139 -139
  61. package/dist/runtime/components/Table/ColumnDate.vue +16 -16
  62. package/dist/runtime/components/Table/ColumnDateTime.vue +18 -18
  63. package/dist/runtime/components/Table/ColumnImage.vue +15 -15
  64. package/dist/runtime/components/Table/ColumnNumber.vue +14 -14
  65. package/dist/runtime/components/Table/ColumnText.vue +25 -25
  66. package/dist/runtime/components/Table/Simple.vue +69 -69
  67. package/dist/runtime/components/Table/index.vue +65 -65
  68. package/dist/runtime/components/Tabs/index.vue +64 -64
  69. package/dist/runtime/helpers/apiListHelper.d.ts +0 -1
  70. package/dist/runtime/helpers/apiObjectHelper.d.ts +0 -1
  71. package/dist/runtime/helpers/apiPageHelper.d.ts +0 -1
  72. package/dist/runtime/helpers/componentHelper.d.ts +6 -0
  73. package/dist/runtime/helpers/componentHelper.mjs +15 -0
  74. package/package.json +92 -92
@@ -1,148 +1,172 @@
1
- <template>
2
- <FieldWrapper v-bind="wrapperProps">
3
- <div class="space-y-3">
4
- <div
5
- ref="dropzoneRef"
6
- :class="[
7
- ui.base,
8
- {
9
- [ui.disabled]: isDisabled,
10
- [ui.background.default]: !isOverDropZone && !isDisabled,
11
- [ui.background.dragover]: isOverDropZone && !isDisabled,
12
- },
13
- ]"
14
- >
15
- <input
16
- ref="fileInputRef"
17
- type="file"
18
- class="hidden"
19
- :name="name"
20
- :accept="acceptFile"
21
- :disabled="isDisabled"
22
- multiple
23
- @change="handleChange"
24
- />
25
- <div :class="[ui.wrapper]">
26
- <div v-if="selectedFiles.length === 0" :class="[ui.placeholderWrapper]">
27
- <Icon :name="ui.default.uploadIcon" :class="[ui.labelIcon]" />
28
- <div :class="[ui.labelWrapper]">
29
- <p class="text-primary cursor-pointer" @click="handleOpenFile">
30
- {{ selectFileLabel }}
31
- </p>
32
- <p>{{ selectFileSubLabel }}</p>
33
- </div>
34
- <p v-if="placeholder" :class="[ui.placeholder]">{{ placeholder }}</p>
35
- </div>
36
-
37
- <div v-else :class="ui.imageItemWrapper">
38
- <Item
39
- v-for="(file, index) in selectedFiles"
40
- :key="file.key"
41
- v-bind="$props"
42
- :ui="ui"
43
- :selected-file="file.file"
44
- @success="handleSuccess(index, $event)"
45
- @delete="handleDeleteFile(index)"
46
- @error="handleError(index, $event)"
47
- />
48
- <Item v-bind="$props" is-adding-btn :ui="ui" @add="handleOpenFile" />
49
- </div>
50
- </div>
51
- </div>
52
- </div>
53
- </FieldWrapper>
54
- </template>
55
-
56
- <script lang="ts" setup>
57
- import { useDropZone } from '@vueuse/core'
58
- import { type IUploadDropzoneImageAutoMultipleProps } from './types'
59
- import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
60
- import { useFieldHOC } from '#core/composables/useForm'
61
- import { _get, computed, ref, toRef, StringHelper, useUI, useUiConfig } from '#imports'
62
- import { uploadFileDropzoneImage } from '#core/ui.config'
63
- import Item from './item.vue'
64
-
65
- const config = useUiConfig<typeof uploadFileDropzoneImage>(
66
- uploadFileDropzoneImage,
67
- 'uploadFileDropzoneImage'
68
- )
69
-
70
- const props = withDefaults(defineProps<IUploadDropzoneImageAutoMultipleProps>(), {
71
- accept: 'image/*',
72
- bodyKey: 'file',
73
- responseKey: 'url',
74
- selectFileLabel: 'คลิกเพื่อเลือกไฟล์',
75
- selectFileSubLabel: 'หรือ ลากและวางที่นี่',
76
- uploadAddLabel: 'อัพโหลด',
77
- })
78
-
79
- const emits = defineEmits(['change', 'success', 'delete'])
80
- const selectedFiles = ref<Array<{ file: File; key: string }>>([])
81
-
82
- const { wrapperProps, handleChange: onChange, value } = useFieldHOC<File[]>(props)
83
-
84
- const { ui } = useUI('uploadFileDropzoneImage', toRef(props, 'ui'), config)
85
-
86
- const fileInputRef = ref<HTMLInputElement | null>()
87
- const dropzoneRef = ref<HTMLDivElement>()
88
-
89
- const acceptFile = computed(() =>
90
- typeof props.accept === 'string' ? props.accept : props.accept?.join(',')
91
- )
92
-
93
- const onDrop = (files: File[] | null) => {
94
- if (props.isDisabled || files?.length === 0 || !files) return
95
-
96
- for (const file of files) {
97
- selectedFiles.value = [
98
- ...selectedFiles.value,
99
- {
100
- file,
101
- key: StringHelper.genString(),
102
- },
103
- ]
104
-
105
- emits('change', value.value)
106
- }
107
- }
108
-
109
- const { isOverDropZone } = useDropZone(dropzoneRef as unknown as HTMLElement, {
110
- onDrop,
111
- })
112
-
113
- const handleChange = (e: Event) => {
114
- if (props.isDisabled) return
115
-
116
- for (const file of (e.target as HTMLInputElement).files ?? []) {
117
- selectedFiles.value = [
118
- ...selectedFiles.value,
119
- {
120
- file,
121
- key: StringHelper.genString(),
122
- },
123
- ]
124
-
125
- emits('change', value.value)
126
- }
127
-
128
- fileInputRef.value?.value && (fileInputRef.value.value = '')
129
- }
130
-
131
- const handleOpenFile = () => {
132
- fileInputRef.value?.click()
133
- }
134
-
135
- const handleDeleteFile = (index: number) => {
136
- selectedFiles.value.splice(index, 1)
137
- onChange(undefined)
138
- emits('delete')
139
- }
140
-
141
- const handleError = (index: number, error: any) => {}
142
-
143
- const handleSuccess = (index: number, any: any) => {
144
- value.value = [_get(any, props.responseKey), ...(value.value || [])]
145
- emits('change', value.value)
146
- emits('success', value.value)
147
- }
148
- </script>
1
+ <template>
2
+ <FieldWrapper v-bind="wrapperProps">
3
+ <div class="space-y-3">
4
+ <div
5
+ ref="dropzoneRef"
6
+ :class="[
7
+ ui.base,
8
+ {
9
+ [ui.disabled]: isDisabled,
10
+ [ui.background.default]: !isOverDropZone && !isDisabled,
11
+ [ui.background.dragover]: isOverDropZone && !isDisabled,
12
+ },
13
+ ]"
14
+ >
15
+ <input
16
+ ref="fileInputRef"
17
+ type="file"
18
+ class="hidden"
19
+ :name="name"
20
+ :accept="acceptFile"
21
+ :disabled="isDisabled"
22
+ multiple
23
+ @change="handleChange"
24
+ />
25
+ <div :class="[ui.wrapper]">
26
+ <div v-if="value && value.length === 0" :class="[ui.placeholderWrapper]">
27
+ <Icon :name="ui.default.uploadIcon" :class="[ui.labelIcon]" />
28
+ <div :class="[ui.labelWrapper]">
29
+ <p class="text-primary cursor-pointer" @click="handleOpenFile">
30
+ {{ selectFileLabel }}
31
+ </p>
32
+ <p>{{ selectFileSubLabel }}</p>
33
+ </div>
34
+ <p v-if="placeholder" :class="[ui.placeholder]">{{ placeholder }}</p>
35
+ </div>
36
+
37
+ <div v-else :class="ui.imageItemWrapper">
38
+ <ItemView
39
+ v-for="(file, index) in value"
40
+ :key="file.url"
41
+ v-bind="$props"
42
+ :ui="ui"
43
+ :selected-file="file"
44
+ @delete="handleDeleteFileView(index)"
45
+ />
46
+ <ItemUpload
47
+ v-for="(file, index) in selectedFiles"
48
+ :key="file.key"
49
+ v-bind="$props"
50
+ :ui="ui"
51
+ :selected-file="file.file"
52
+ @success="handleSuccess(index, $event)"
53
+ @delete="handleDeleteFile(index)"
54
+ @error="handleError(index, $event)"
55
+ />
56
+ <itemUpload v-bind="$props" is-adding-btn :ui="ui" @add="handleOpenFile" />
57
+ </div>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </FieldWrapper>
62
+ </template>
63
+
64
+ <script lang="ts" setup>
65
+ import { useDropZone } from '@vueuse/core'
66
+ import { type IUploadDropzoneImageAutoMultipleProps } from './types'
67
+ import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
68
+ import { useFieldHOC } from '#core/composables/useForm'
69
+ import { _get, computed, ref, toRef, StringHelper, useUI, useUiConfig, ArrayHelper } from '#imports'
70
+ import { uploadFileDropzoneImage } from '#core/ui.config'
71
+ import ItemUpload from './ItemUpload.vue'
72
+ import ItemView from './ItemView.vue'
73
+ import type { IFileValue } from '#core/components/Form/types'
74
+
75
+ const config = useUiConfig<typeof uploadFileDropzoneImage>(
76
+ uploadFileDropzoneImage,
77
+ 'uploadFileDropzoneImage'
78
+ )
79
+
80
+ const props = withDefaults(defineProps<IUploadDropzoneImageAutoMultipleProps>(), {
81
+ accept: 'image/*',
82
+ bodyKey: 'file',
83
+ responseURL: 'url',
84
+ responsePath: 'path',
85
+ selectFileLabel: 'คลิกเพื่อเลือกไฟล์',
86
+ selectFileSubLabel: 'หรือ ลากและวางที่นี่',
87
+ uploadAddLabel: 'อัพโหลด',
88
+ })
89
+
90
+ const emits = defineEmits(['change', 'success', 'delete'])
91
+ const selectedFiles = ref<Array<{ file: File; key: string }>>([])
92
+
93
+ const { wrapperProps, handleChange: onChange, value } = useFieldHOC<IFileValue[]>(props)
94
+
95
+ const { ui } = useUI('uploadFileDropzoneImage', toRef(props, 'ui'), config)
96
+
97
+ const fileInputRef = ref<HTMLInputElement | null>()
98
+ const dropzoneRef = ref<HTMLDivElement>()
99
+
100
+ const acceptFile = computed(() =>
101
+ typeof props.accept === 'string' ? props.accept : props.accept?.join(',')
102
+ )
103
+
104
+ const onDrop = (files: File[] | null) => {
105
+ if (props.isDisabled || files?.length === 0 || !files) return
106
+
107
+ for (const file of files) {
108
+ selectedFiles.value = [
109
+ ...selectedFiles.value,
110
+ {
111
+ file,
112
+ key: StringHelper.genString(),
113
+ },
114
+ ]
115
+
116
+ emits('change', value.value)
117
+ }
118
+ }
119
+
120
+ const { isOverDropZone } = useDropZone(dropzoneRef as unknown as HTMLElement, {
121
+ onDrop,
122
+ })
123
+
124
+ const handleChange = (e: Event) => {
125
+ if (props.isDisabled) return
126
+
127
+ for (const file of (e.target as HTMLInputElement).files ?? []) {
128
+ selectedFiles.value = [
129
+ ...selectedFiles.value,
130
+ {
131
+ file,
132
+ key: StringHelper.genString(),
133
+ },
134
+ ]
135
+
136
+ emits('change', value.value)
137
+ }
138
+
139
+ fileInputRef.value?.value && (fileInputRef.value.value = '')
140
+ }
141
+
142
+ const handleOpenFile = () => {
143
+ fileInputRef.value?.click()
144
+ }
145
+
146
+ const handleDeleteFile = (index: number) => {
147
+ selectedFiles.value.splice(index, 1)
148
+ }
149
+
150
+ const handleDeleteFileView = (index: number) => {
151
+ value.value.splice(index, 1)
152
+ emits('delete')
153
+ }
154
+
155
+ const handleError = (index: number, error: any) => {}
156
+
157
+ const handleSuccess = (index: number, res: any) => {
158
+ value.value = [
159
+ {
160
+ url: _get(res, props.responseURL),
161
+ path: _get(res, props.responsePath),
162
+ name: res.name,
163
+ size: res.size,
164
+ },
165
+ ...ArrayHelper.toArray(value.value),
166
+ ]
167
+
168
+ selectedFiles.value.splice(index, 1)
169
+ emits('change', value.value)
170
+ emits('success', value.value)
171
+ }
172
+ </script>
@@ -1,5 +1,5 @@
1
1
  import { type AxiosRequestConfig } from 'axios';
2
- import { type IFieldProps, type IFormFieldBase, type INPUT_TYPES } from '../types';
2
+ import { type IFieldProps, type IFileValue, type IFormFieldBase, type INPUT_TYPES } from '../types';
3
3
  export interface IUploadDropzoneImageAutoMultipleProps extends IFieldProps {
4
4
  requestOptions: Omit<AxiosRequestConfig, 'baseURL'> & {
5
5
  baseURL: string;
@@ -10,11 +10,12 @@ export interface IUploadDropzoneImageAutoMultipleProps extends IFieldProps {
10
10
  uploadAddLabel?: string;
11
11
  accept?: string[] | string;
12
12
  bodyKey?: string;
13
- responseKey?: string;
13
+ responseURL?: string;
14
+ responsePath?: string;
14
15
  maxSize?: number;
15
16
  }
16
17
  export type IUploadDropzoneImageAutoMultipleField = IFormFieldBase<INPUT_TYPES.UPLOAD_DROPZONE_IMAGE_AUTO_MULTIPLE, IUploadDropzoneImageAutoMultipleProps, {
17
- change: (value: File[] | undefined) => void;
18
+ change: (value: IFileValue[] | undefined) => void;
18
19
  success: (res: any) => void;
19
20
  delete: () => void;
20
21
  }>;
@@ -1,95 +1,95 @@
1
- <template>
2
- <FieldWrapper v-bind="wrapperProps">
3
- <div :class="[ui.base]">
4
- <input
5
- ref="fileInput"
6
- type="file"
7
- class="hidden"
8
- :name="name"
9
- :accept="fileAllocate.acceptFile.value"
10
- :disabled="isDisabled"
11
- @change="handleChange"
12
- />
13
- <div :class="[ui.wrapper]">
14
- <div :class="[ui.selectFileBox]">
15
- <Button size="2xs" @click="handleOpenFile">{{ selectFileLabel }}</Button>
16
- <p :class="ui.placeholder">
17
- {{ value?.name ?? placeholder ?? 'ยังไม่ได้เลือกไฟล์' }}
18
- </p>
19
- <Badge v-if="value" size="xs" variant="outline">
20
- {{
21
- fileAllocate.isSelectedFileUseMb.value
22
- ? `${fileAllocate.selectedFileSizeMb.value} MB`
23
- : `${fileAllocate.selectedFileSizeKb.value} KB`
24
- }}
25
- </Badge>
26
- </div>
27
- </div>
28
- </div>
29
- </FieldWrapper>
30
- </template>
31
- <script lang="ts" setup>
32
- import { useFieldHOC } from '#core/composables/useForm'
33
- import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
34
- import { type IUploadFileClassicFieldProps } from '#core/components/Form/InputUploadFileClassic/types'
35
- import { useUiConfig } from '#core/composables/useConfig'
36
- import { uploadFileInputClassicAuto } from '#core/ui.config'
37
- import { ref, toRef, useUI } from '#imports'
38
- import i18next from 'i18next'
39
- import { checkMaxSize, useFileAllocate } from '#core/helpers/componentHelper'
40
-
41
- const config = useUiConfig<typeof uploadFileInputClassicAuto>(
42
- uploadFileInputClassicAuto,
43
- 'uploadFileInputClassicAuto'
44
- )
45
-
46
- const emits = defineEmits(['change'])
47
- const props = withDefaults(defineProps<IUploadFileClassicFieldProps>(), {
48
- selectFileLabel: 'เลือกไฟล์',
49
- })
50
-
51
- const { value, wrapperProps, setErrors } = useFieldHOC<File | undefined>(props)
52
- const fileAllocate = useFileAllocate(value, props)
53
-
54
- const fileInput = ref<HTMLInputElement>()
55
-
56
- const handleOpenFile = () => {
57
- fileInput.value?.click()
58
- }
59
-
60
- const { ui } = useUI('uploadFileInputClassicAuto', toRef(props, 'ui'), config)
61
-
62
- const handleCheckFileCondition = (file: File | undefined): boolean => {
63
- if (!file) return false
64
-
65
- const maxSize = checkMaxSize(file, props.maxSize)
66
-
67
- if (!maxSize) {
68
- if (fileAllocate.isAcceptFileUseMb.value) {
69
- setErrors(
70
- i18next.t('custom:invalid_file_size_mb', { size: fileAllocate.acceptFileSizeMb.value })
71
- )
72
- } else {
73
- setErrors(
74
- i18next.t('custom:invalid_file_size_kb', { size: fileAllocate.acceptFileSizeKb.value })
75
- )
76
- }
77
-
78
- return false
79
- }
80
-
81
- setErrors('')
82
-
83
- return true
84
- }
85
-
86
- const handleChange = (e: Event) => {
87
- const file = (e.target as HTMLInputElement).files?.[0]
88
- const result = handleCheckFileCondition(file)
89
-
90
- if (result && file) {
91
- value.value = file
92
- emits('change', file)
93
- }
94
- }
95
- </script>
1
+ <template>
2
+ <FieldWrapper v-bind="wrapperProps">
3
+ <div :class="[ui.base]">
4
+ <input
5
+ ref="fileInput"
6
+ type="file"
7
+ class="hidden"
8
+ :name="name"
9
+ :accept="fileAllocate.acceptFile.value"
10
+ :disabled="isDisabled"
11
+ @change="handleChange"
12
+ />
13
+ <div :class="[ui.wrapper]">
14
+ <div :class="[ui.selectFileBox]">
15
+ <Button size="2xs" @click="handleOpenFile">{{ selectFileLabel }}</Button>
16
+ <p :class="ui.placeholder">
17
+ {{ value?.name ?? placeholder ?? 'ยังไม่ได้เลือกไฟล์' }}
18
+ </p>
19
+ <Badge v-if="value" size="xs" variant="outline">
20
+ {{
21
+ fileAllocate.isSelectedFileUseMb.value
22
+ ? `${fileAllocate.selectedFileSizeMb.value} MB`
23
+ : `${fileAllocate.selectedFileSizeKb.value} KB`
24
+ }}
25
+ </Badge>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </FieldWrapper>
30
+ </template>
31
+ <script lang="ts" setup>
32
+ import { useFieldHOC } from '#core/composables/useForm'
33
+ import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
34
+ import { type IUploadFileClassicFieldProps } from '#core/components/Form/InputUploadFileClassic/types'
35
+ import { useUiConfig } from '#core/composables/useConfig'
36
+ import { uploadFileInputClassicAuto } from '#core/ui.config'
37
+ import { ref, toRef, useUI } from '#imports'
38
+ import i18next from 'i18next'
39
+ import { checkMaxSize, useFileAllocate } from '#core/helpers/componentHelper'
40
+
41
+ const config = useUiConfig<typeof uploadFileInputClassicAuto>(
42
+ uploadFileInputClassicAuto,
43
+ 'uploadFileInputClassicAuto'
44
+ )
45
+
46
+ const emits = defineEmits(['change'])
47
+ const props = withDefaults(defineProps<IUploadFileClassicFieldProps>(), {
48
+ selectFileLabel: 'เลือกไฟล์',
49
+ })
50
+
51
+ const { value, wrapperProps, setErrors } = useFieldHOC<File | undefined>(props)
52
+ const fileAllocate = useFileAllocate(value, props)
53
+
54
+ const fileInput = ref<HTMLInputElement>()
55
+
56
+ const handleOpenFile = () => {
57
+ fileInput.value?.click()
58
+ }
59
+
60
+ const { ui } = useUI('uploadFileInputClassicAuto', toRef(props, 'ui'), config)
61
+
62
+ const handleCheckFileCondition = (file: File | undefined): boolean => {
63
+ if (!file) return false
64
+
65
+ const maxSize = checkMaxSize(file, props.maxSize)
66
+
67
+ if (!maxSize) {
68
+ if (fileAllocate.isAcceptFileUseMb.value) {
69
+ setErrors(
70
+ i18next.t('custom:invalid_file_size_mb', { size: fileAllocate.acceptFileSizeMb.value })
71
+ )
72
+ } else {
73
+ setErrors(
74
+ i18next.t('custom:invalid_file_size_kb', { size: fileAllocate.acceptFileSizeKb.value })
75
+ )
76
+ }
77
+
78
+ return false
79
+ }
80
+
81
+ setErrors('')
82
+
83
+ return true
84
+ }
85
+
86
+ const handleChange = (e: Event) => {
87
+ const file = (e.target as HTMLInputElement).files?.[0]
88
+ const result = handleCheckFileCondition(file)
89
+
90
+ if (result && file) {
91
+ value.value = file
92
+ emits('change', file)
93
+ }
94
+ }
95
+ </script>