@finema/core 1.4.152 → 1.4.154

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 (168) hide show
  1. package/README.md +60 -60
  2. package/dist/module.json +1 -5
  3. package/dist/module.mjs +10 -2
  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 +37 -37
  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 +143 -143
  15. package/dist/runtime/components/FlexDeck/index.vue +68 -68
  16. package/dist/runtime/components/Form/FieldWrapper.vue +23 -23
  17. package/dist/runtime/components/Form/Fields.vue +230 -230
  18. package/dist/runtime/components/Form/InputCheckbox/index.vue +28 -28
  19. package/dist/runtime/components/Form/InputDateTime/index.vue +60 -60
  20. package/dist/runtime/components/Form/InputDateTimeRange/date_range_time_field.types.d.ts +1 -1
  21. package/dist/runtime/components/Form/InputDateTimeRange/index.vue +83 -83
  22. package/dist/runtime/components/Form/InputNumber/index.vue +27 -27
  23. package/dist/runtime/components/Form/InputRadio/index.vue +27 -27
  24. package/dist/runtime/components/Form/InputSelect/index.vue +45 -45
  25. package/dist/runtime/components/Form/InputSelectMultiple/index.vue +54 -54
  26. package/dist/runtime/components/Form/InputStatic/index.vue +16 -16
  27. package/dist/runtime/components/Form/InputTags/index.vue +145 -145
  28. package/dist/runtime/components/Form/InputText/index.vue +67 -67
  29. package/dist/runtime/components/Form/InputTextarea/index.vue +25 -25
  30. package/dist/runtime/components/Form/InputToggle/index.vue +14 -14
  31. package/dist/runtime/components/Form/InputUploadDropzone/index.vue +206 -206
  32. package/dist/runtime/components/Form/InputUploadDropzone/types.d.ts +1 -1
  33. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue +342 -342
  34. package/dist/runtime/components/Form/InputUploadDropzoneAuto/types.d.ts +1 -1
  35. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/ItemUpload.vue +241 -241
  36. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/ItemView.vue +89 -89
  37. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue +164 -164
  38. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/types.d.ts +1 -1
  39. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/ItemUpload.vue +161 -161
  40. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/ItemView.vue +64 -64
  41. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/index.vue +172 -172
  42. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/types.d.ts +1 -1
  43. package/dist/runtime/components/Form/InputUploadFileClassic/index.vue +95 -95
  44. package/dist/runtime/components/Form/InputUploadFileClassicAuto/index.vue +151 -151
  45. package/dist/runtime/components/Form/InputUploadFileClassicAuto/types.d.ts +1 -1
  46. package/dist/runtime/components/Form/InputUploadImageAuto/index.vue +219 -219
  47. package/dist/runtime/components/Form/InputUploadImageAuto/types.d.ts +1 -1
  48. package/dist/runtime/components/Form/InputWYSIWYG/index.vue +53 -53
  49. package/dist/runtime/components/Form/index.vue +6 -6
  50. package/dist/runtime/components/Icon.vue +23 -23
  51. package/dist/runtime/components/Image.vue +36 -36
  52. package/dist/runtime/components/Loader.vue +27 -27
  53. package/dist/runtime/components/Modal/index.vue +146 -146
  54. package/dist/runtime/components/QRCode.vue +22 -22
  55. package/dist/runtime/components/SimplePagination.vue +96 -96
  56. package/dist/runtime/components/Slideover/index.vue +110 -110
  57. package/dist/runtime/components/Table/Base.vue +139 -139
  58. package/dist/runtime/components/Table/ColumnDate.vue +16 -16
  59. package/dist/runtime/components/Table/ColumnDateTime.vue +18 -18
  60. package/dist/runtime/components/Table/ColumnImage.vue +15 -15
  61. package/dist/runtime/components/Table/ColumnNumber.vue +14 -14
  62. package/dist/runtime/components/Table/ColumnText.vue +25 -25
  63. package/dist/runtime/components/Table/Simple.vue +69 -69
  64. package/dist/runtime/components/Table/index.vue +65 -65
  65. package/dist/runtime/components/Tabs/index.vue +64 -64
  66. package/dist/runtime/components/TeleportSafe.vue +40 -40
  67. package/dist/runtime/composables/loaderList.d.ts +2 -2
  68. package/dist/runtime/composables/{loaderList.js → loaderList.mjs} +2 -2
  69. package/dist/runtime/composables/loaderObject.d.ts +1 -1
  70. package/dist/runtime/composables/{loaderObject.js → loaderObject.mjs} +2 -2
  71. package/dist/runtime/composables/loaderPage.d.ts +1 -1
  72. package/dist/runtime/composables/{loaderPage.js → loaderPage.mjs} +3 -3
  73. package/dist/runtime/composables/useConfig.d.ts +1 -1
  74. package/dist/runtime/composables/useForm.d.ts +1 -1
  75. package/dist/runtime/composables/useTable.d.ts +2 -2
  76. package/dist/runtime/composables/{useTable.js → useTable.mjs} +1 -1
  77. package/dist/runtime/composables/{useUpload.js → useUpload.mjs} +1 -1
  78. package/dist/runtime/helpers/{apiListHelper.js → apiListHelper.mjs} +1 -1
  79. package/dist/runtime/helpers/{apiObjectHelper.js → apiObjectHelper.mjs} +1 -1
  80. package/dist/runtime/helpers/apiPageHelper.d.ts +1 -1
  81. package/dist/runtime/helpers/{apiPageHelper.js → apiPageHelper.mjs} +4 -4
  82. package/dist/runtime/ui.config/index.d.ts +16 -16
  83. package/dist/runtime/ui.config/index.mjs +16 -0
  84. package/dist/runtime/ui.config/{uploadDropzoneImage.js → uploadDropzoneImage.mjs} +1 -1
  85. package/dist/runtime/utils/ArrayHelper.d.ts +1 -1
  86. package/dist/runtime/utils/{ArrayHelper.spec.js → ArrayHelper.spec.mjs} +1 -1
  87. package/dist/runtime/utils/{FileHelper.spec.js → FileHelper.spec.mjs} +1 -1
  88. package/dist/runtime/utils/ObjectHelper.d.ts +2 -2
  89. package/dist/runtime/utils/{ObjectHelper.js → ObjectHelper.mjs} +2 -2
  90. package/dist/runtime/utils/{ObjectHelper.spec.js → ObjectHelper.spec.mjs} +1 -1
  91. package/dist/runtime/utils/ParamHelper.d.ts +1 -1
  92. package/dist/runtime/utils/{ParamHelper.spec.js → ParamHelper.spec.mjs} +1 -1
  93. package/dist/runtime/utils/{StringHelper.spec.js → StringHelper.spec.mjs} +1 -1
  94. package/dist/runtime/utils/{TimeHelper.spec.js → TimeHelper.spec.mjs} +1 -1
  95. package/dist/runtime/utils/{TimeHelper.thai.spec.js → TimeHelper.thai.spec.mjs} +1 -1
  96. package/dist/types.d.mts +16 -1
  97. package/dist/types.d.ts +16 -1
  98. package/package.json +92 -93
  99. package/dist/runtime/ui.config/index.js +0 -16
  100. /package/dist/runtime/components/Dropdown/{types.js → types.mjs} +0 -0
  101. /package/dist/runtime/components/FlexDeck/{types.js → types.mjs} +0 -0
  102. /package/dist/runtime/components/Form/InputCheckbox/{types.js → types.mjs} +0 -0
  103. /package/dist/runtime/components/Form/InputDateTime/{date_time_field.types.js → date_time_field.types.mjs} +0 -0
  104. /package/dist/runtime/components/Form/InputDateTimeRange/{date_range_time_field.types.js → date_range_time_field.types.mjs} +0 -0
  105. /package/dist/runtime/components/Form/InputNumber/{types.js → types.mjs} +0 -0
  106. /package/dist/runtime/components/Form/InputRadio/{types.js → types.mjs} +0 -0
  107. /package/dist/runtime/components/Form/InputSelect/{types.js → types.mjs} +0 -0
  108. /package/dist/runtime/components/Form/InputSelectMultiple/{types.js → types.mjs} +0 -0
  109. /package/dist/runtime/components/Form/InputStatic/{types.js → types.mjs} +0 -0
  110. /package/dist/runtime/components/Form/InputTags/{types.js → types.mjs} +0 -0
  111. /package/dist/runtime/components/Form/InputText/{types.js → types.mjs} +0 -0
  112. /package/dist/runtime/components/Form/InputTextarea/{types.js → types.mjs} +0 -0
  113. /package/dist/runtime/components/Form/InputToggle/{types.js → types.mjs} +0 -0
  114. /package/dist/runtime/components/Form/InputUploadDropzone/{types.js → types.mjs} +0 -0
  115. /package/dist/runtime/components/Form/InputUploadDropzoneAuto/{types.js → types.mjs} +0 -0
  116. /package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/{types.js → types.mjs} +0 -0
  117. /package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/{types.js → types.mjs} +0 -0
  118. /package/dist/runtime/components/Form/InputUploadFileClassic/{types.js → types.mjs} +0 -0
  119. /package/dist/runtime/components/Form/InputUploadFileClassicAuto/{types.js → types.mjs} +0 -0
  120. /package/dist/runtime/components/Form/InputUploadImageAuto/{types.js → types.mjs} +0 -0
  121. /package/dist/runtime/components/Form/InputWYSIWYG/{types.js → types.mjs} +0 -0
  122. /package/dist/runtime/components/Form/{types.js → types.mjs} +0 -0
  123. /package/dist/runtime/components/Table/{types.js → types.mjs} +0 -0
  124. /package/dist/runtime/composables/{useApp.js → useApp.mjs} +0 -0
  125. /package/dist/runtime/composables/{useConfig.js → useConfig.mjs} +0 -0
  126. /package/dist/runtime/composables/{useDialog.js → useDialog.mjs} +0 -0
  127. /package/dist/runtime/composables/{useFlexDeck.js → useFlexDeck.mjs} +0 -0
  128. /package/dist/runtime/composables/{useForm.js → useForm.mjs} +0 -0
  129. /package/dist/runtime/composables/{useNotification.js → useNotification.mjs} +0 -0
  130. /package/dist/runtime/composables/{useWatch.js → useWatch.mjs} +0 -0
  131. /package/dist/runtime/{core.config.js → core.config.mjs} +0 -0
  132. /package/dist/runtime/helpers/{componentHelper.js → componentHelper.mjs} +0 -0
  133. /package/dist/runtime/lib/{Requester.js → Requester.mjs} +0 -0
  134. /package/dist/runtime/{plugin.js → plugin.mjs} +0 -0
  135. /package/dist/runtime/{quill.plugin.js → quill.plugin.mjs} +0 -0
  136. /package/dist/runtime/types/{common.js → common.mjs} +0 -0
  137. /package/dist/runtime/types/{config.js → config.mjs} +0 -0
  138. /package/dist/runtime/types/{lib.js → lib.mjs} +0 -0
  139. /package/dist/runtime/ui.config/{alert.js → alert.mjs} +0 -0
  140. /package/dist/runtime/ui.config/{badge.js → badge.mjs} +0 -0
  141. /package/dist/runtime/ui.config/{breadcrumb.js → breadcrumb.mjs} +0 -0
  142. /package/dist/runtime/ui.config/{button.js → button.mjs} +0 -0
  143. /package/dist/runtime/ui.config/{buttonGroup.js → buttonGroup.mjs} +0 -0
  144. /package/dist/runtime/ui.config/{card.js → card.mjs} +0 -0
  145. /package/dist/runtime/ui.config/{checkbox.js → checkbox.mjs} +0 -0
  146. /package/dist/runtime/ui.config/{formGroup.js → formGroup.mjs} +0 -0
  147. /package/dist/runtime/ui.config/{icon.js → icon.mjs} +0 -0
  148. /package/dist/runtime/ui.config/{input.js → input.mjs} +0 -0
  149. /package/dist/runtime/ui.config/{modal.js → modal.mjs} +0 -0
  150. /package/dist/runtime/ui.config/{notification.js → notification.mjs} +0 -0
  151. /package/dist/runtime/ui.config/{pagination.js → pagination.mjs} +0 -0
  152. /package/dist/runtime/ui.config/{select.js → select.mjs} +0 -0
  153. /package/dist/runtime/ui.config/{selectMenu.js → selectMenu.mjs} +0 -0
  154. /package/dist/runtime/ui.config/{slideover.js → slideover.mjs} +0 -0
  155. /package/dist/runtime/ui.config/{table.js → table.mjs} +0 -0
  156. /package/dist/runtime/ui.config/{tabs.js → tabs.mjs} +0 -0
  157. /package/dist/runtime/ui.config/{tags.js → tags.mjs} +0 -0
  158. /package/dist/runtime/ui.config/{textarea.js → textarea.mjs} +0 -0
  159. /package/dist/runtime/ui.config/{toggle.js → toggle.mjs} +0 -0
  160. /package/dist/runtime/ui.config/{uploadFileDropzone.js → uploadFileDropzone.mjs} +0 -0
  161. /package/dist/runtime/ui.config/{uploadFileInputClassicAuto.js → uploadFileInputClassicAuto.mjs} +0 -0
  162. /package/dist/runtime/ui.config/{uploadImage.js → uploadImage.mjs} +0 -0
  163. /package/dist/runtime/utils/{ArrayHelper.js → ArrayHelper.mjs} +0 -0
  164. /package/dist/runtime/utils/{FileHelper.js → FileHelper.mjs} +0 -0
  165. /package/dist/runtime/utils/{ParamHelper.js → ParamHelper.mjs} +0 -0
  166. /package/dist/runtime/utils/{StringHelper.js → StringHelper.mjs} +0 -0
  167. /package/dist/runtime/utils/{TimeHelper.js → TimeHelper.mjs} +0 -0
  168. /package/dist/runtime/utils/{lodash.js → lodash.mjs} +0 -0
@@ -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>
@@ -1,151 +1,151 @@
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
- {{ selectedFile?.name ?? placeholder ?? 'ยังไม่ได้เลือกไฟล์' }}
18
- </p>
19
- <Badge v-if="selectedFile" 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 v-if="selectedFile">
28
- <Icon
29
- v-if="upload.status.value.isSuccess"
30
- name="heroicons:check-circle-20-solid"
31
- class="text-success"
32
- />
33
- <Icon
34
- v-if="upload.status.value.isError"
35
- name="heroicons:x-circle-20-solid"
36
- class="text-danger"
37
- />
38
- <Icon
39
- v-if="upload.status.value.isLoading"
40
- name="i-svg-spinners:180-ring-with-bg"
41
- class="text-primary"
42
- />
43
- </div>
44
- </div>
45
- </div>
46
- <img v-if="imagePreviewURL && value" :src="imagePreviewURL" alt="" :class="ui.previewURL" />
47
- </FieldWrapper>
48
- </template>
49
-
50
- <script lang="tsx" setup>
51
- import { _get, ref, StringHelper, toRef, useUI, useUiConfig, useWatchTrue } from '#imports'
52
- import { type IUploadFileProps } from './types'
53
- import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
54
- import { useFieldHOC } from '#core/composables/useForm'
55
- import { type IUploadRequest, useUploadLoader } from '#core/composables/useUpload'
56
- import { uploadFileInputClassicAuto } from '#core/ui.config'
57
- import i18next from 'i18next'
58
- import { checkMaxSize, useFileAllocate, useFileProgress } from '#core/helpers/componentHelper'
59
- import type { IFileValue } from '#core/components/Form/types'
60
-
61
- const config = useUiConfig<typeof uploadFileInputClassicAuto>(
62
- uploadFileInputClassicAuto,
63
- 'uploadFileInputClassicAuto'
64
- )
65
-
66
- const emits = defineEmits(['success'])
67
- const props = withDefaults(defineProps<IUploadFileProps>(), {
68
- bodyKey: 'file',
69
- responseURL: 'url',
70
- responsePath: 'path',
71
- selectFileLabel: 'เลือกไฟล์',
72
- })
73
-
74
- const { wrapperProps, setErrors, value } = useFieldHOC<IFileValue>(props)
75
-
76
- const request: IUploadRequest = {
77
- pathURL: props.uploadPathURL,
78
- requestOptions: props.requestOptions,
79
- }
80
-
81
- const upload = useUploadLoader(request)
82
-
83
- const fileInput = ref<HTMLInputElement>()
84
- const selectedFile = ref<File | undefined>()
85
-
86
- const fileAllocate = useFileAllocate(selectedFile, props)
87
- const { onUploadProgress, onDownloadProgress, percent } = useFileProgress()
88
- const { ui } = useUI('uploadFileInputClassicAuto', toRef(props, 'ui'), config)
89
-
90
- const handleOpenFile = () => {
91
- fileInput.value?.click()
92
- }
93
-
94
- const handleChange = (e: Event) => {
95
- const file = (e.target as HTMLInputElement).files?.[0]
96
- const result = handleCheckFileCondition(file)
97
-
98
- if (result && file) {
99
- selectedFile.value = file
100
- const formData = new FormData()
101
-
102
- formData.append(props.bodyKey, file)
103
- upload.run(formData, { data: { onUploadProgress, onDownloadProgress } })
104
- }
105
- }
106
-
107
- const handleCheckFileCondition = (file: File | undefined): boolean => {
108
- if (!file) return false
109
-
110
- const maxSize = checkMaxSize(file, fileAllocate.acceptFileSizeKb.value)
111
-
112
- if (!maxSize) {
113
- if (fileAllocate.isAcceptFileUseMb.value) {
114
- setErrors(
115
- i18next.t('custom:invalid_file_size_mb', { size: fileAllocate.acceptFileSizeMb.value })
116
- )
117
- } else {
118
- setErrors(
119
- i18next.t('custom:invalid_file_size_kb', { size: fileAllocate.acceptFileSizeKb.value })
120
- )
121
- }
122
-
123
- return false
124
- }
125
-
126
- setErrors('')
127
-
128
- return true
129
- }
130
-
131
- useWatchTrue(
132
- () => upload.status.value.isSuccess,
133
- () => {
134
- value.value = {
135
- url: _get(upload.data.value, props.responseURL),
136
- path: _get(upload.data.value, props.responsePath),
137
- name: upload.data.value.name,
138
- size: upload.data.value.size,
139
- }
140
-
141
- emits('success', value.value)
142
- }
143
- )
144
-
145
- useWatchTrue(
146
- () => upload.status.value.isError,
147
- () => {
148
- setErrors(StringHelper.getError(upload.status.value.errorData))
149
- }
150
- )
151
- </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
+ {{ selectedFile?.name ?? placeholder ?? 'ยังไม่ได้เลือกไฟล์' }}
18
+ </p>
19
+ <Badge v-if="selectedFile" 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 v-if="selectedFile">
28
+ <Icon
29
+ v-if="upload.status.value.isSuccess"
30
+ name="heroicons:check-circle-20-solid"
31
+ class="text-success"
32
+ />
33
+ <Icon
34
+ v-if="upload.status.value.isError"
35
+ name="heroicons:x-circle-20-solid"
36
+ class="text-danger"
37
+ />
38
+ <Icon
39
+ v-if="upload.status.value.isLoading"
40
+ name="i-svg-spinners:180-ring-with-bg"
41
+ class="text-primary"
42
+ />
43
+ </div>
44
+ </div>
45
+ </div>
46
+ <img v-if="imagePreviewURL && value" :src="imagePreviewURL" alt="" :class="ui.previewURL" />
47
+ </FieldWrapper>
48
+ </template>
49
+
50
+ <script lang="tsx" setup>
51
+ import { _get, ref, StringHelper, toRef, useUI, useUiConfig, useWatchTrue } from '#imports'
52
+ import { type IUploadFileProps } from './types'
53
+ import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
54
+ import { useFieldHOC } from '#core/composables/useForm'
55
+ import { type IUploadRequest, useUploadLoader } from '#core/composables/useUpload'
56
+ import { uploadFileInputClassicAuto } from '#core/ui.config'
57
+ import i18next from 'i18next'
58
+ import { checkMaxSize, useFileAllocate, useFileProgress } from '#core/helpers/componentHelper'
59
+ import type { IFileValue } from '#core/components/Form/types'
60
+
61
+ const config = useUiConfig<typeof uploadFileInputClassicAuto>(
62
+ uploadFileInputClassicAuto,
63
+ 'uploadFileInputClassicAuto'
64
+ )
65
+
66
+ const emits = defineEmits(['success'])
67
+ const props = withDefaults(defineProps<IUploadFileProps>(), {
68
+ bodyKey: 'file',
69
+ responseURL: 'url',
70
+ responsePath: 'path',
71
+ selectFileLabel: 'เลือกไฟล์',
72
+ })
73
+
74
+ const { wrapperProps, setErrors, value } = useFieldHOC<IFileValue>(props)
75
+
76
+ const request: IUploadRequest = {
77
+ pathURL: props.uploadPathURL,
78
+ requestOptions: props.requestOptions,
79
+ }
80
+
81
+ const upload = useUploadLoader(request)
82
+
83
+ const fileInput = ref<HTMLInputElement>()
84
+ const selectedFile = ref<File | undefined>()
85
+
86
+ const fileAllocate = useFileAllocate(selectedFile, props)
87
+ const { onUploadProgress, onDownloadProgress, percent } = useFileProgress()
88
+ const { ui } = useUI('uploadFileInputClassicAuto', toRef(props, 'ui'), config)
89
+
90
+ const handleOpenFile = () => {
91
+ fileInput.value?.click()
92
+ }
93
+
94
+ const handleChange = (e: Event) => {
95
+ const file = (e.target as HTMLInputElement).files?.[0]
96
+ const result = handleCheckFileCondition(file)
97
+
98
+ if (result && file) {
99
+ selectedFile.value = file
100
+ const formData = new FormData()
101
+
102
+ formData.append(props.bodyKey, file)
103
+ upload.run(formData, { data: { onUploadProgress, onDownloadProgress } })
104
+ }
105
+ }
106
+
107
+ const handleCheckFileCondition = (file: File | undefined): boolean => {
108
+ if (!file) return false
109
+
110
+ const maxSize = checkMaxSize(file, fileAllocate.acceptFileSizeKb.value)
111
+
112
+ if (!maxSize) {
113
+ if (fileAllocate.isAcceptFileUseMb.value) {
114
+ setErrors(
115
+ i18next.t('custom:invalid_file_size_mb', { size: fileAllocate.acceptFileSizeMb.value })
116
+ )
117
+ } else {
118
+ setErrors(
119
+ i18next.t('custom:invalid_file_size_kb', { size: fileAllocate.acceptFileSizeKb.value })
120
+ )
121
+ }
122
+
123
+ return false
124
+ }
125
+
126
+ setErrors('')
127
+
128
+ return true
129
+ }
130
+
131
+ useWatchTrue(
132
+ () => upload.status.value.isSuccess,
133
+ () => {
134
+ value.value = {
135
+ url: _get(upload.data.value, props.responseURL),
136
+ path: _get(upload.data.value, props.responsePath),
137
+ name: upload.data.value.name,
138
+ size: upload.data.value.size,
139
+ }
140
+
141
+ emits('success', value.value)
142
+ }
143
+ )
144
+
145
+ useWatchTrue(
146
+ () => upload.status.value.isError,
147
+ () => {
148
+ setErrors(StringHelper.getError(upload.status.value.errorData))
149
+ }
150
+ )
151
+ </script>
@@ -1,5 +1,5 @@
1
1
  import { type AxiosRequestConfig } from 'axios';
2
- import { type IFieldProps, type IFormFieldBase, type INPUT_TYPES } from '../types.js';
2
+ import { type IFieldProps, type IFormFieldBase, type INPUT_TYPES } from '../types';
3
3
  export interface IUploadFileProps extends IFieldProps {
4
4
  requestOptions: Omit<AxiosRequestConfig, 'baseURL'> & {
5
5
  baseURL: string;