@finema/core 1.4.92 → 1.4.93

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 (24) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +1 -1
  3. package/dist/runtime/components/Form/Fields.vue +9 -0
  4. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue +7 -1
  5. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/Item.vue +283 -282
  6. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue +13 -4
  7. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/index.vue +134 -0
  8. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/item.vue +198 -0
  9. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/types.d.ts +20 -0
  10. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/types.mjs +0 -0
  11. package/dist/runtime/components/Form/InputUploadFileClassic/index.vue +5 -3
  12. package/dist/runtime/components/Form/InputUploadFileClassicAuto/index.vue +9 -5
  13. package/dist/runtime/components/Form/types.d.ts +4 -2
  14. package/dist/runtime/components/Form/types.mjs +1 -0
  15. package/dist/runtime/composables/useNotification.d.ts +7 -0
  16. package/dist/runtime/composables/useNotification.mjs +39 -0
  17. package/dist/runtime/types/config.d.ts +1 -1
  18. package/dist/runtime/ui.config/index.d.ts +1 -0
  19. package/dist/runtime/ui.config/index.mjs +1 -0
  20. package/dist/runtime/ui.config/uploadDropzoneImage.d.ts +83 -0
  21. package/dist/runtime/ui.config/uploadDropzoneImage.mjs +26 -0
  22. package/dist/runtime/ui.config/uploadFileDropzone.d.ts +4 -0
  23. package/dist/runtime/ui.config/uploadFileDropzone.mjs +5 -1
  24. package/package.json +1 -1
@@ -0,0 +1,134 @@
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.name + index"
41
+ v-bind="$props"
42
+ :ui="ui"
43
+ :selected-file="file"
44
+ @success="handleSuccess(index, $event)"
45
+ @delete="handleDeleteFile(index)"
46
+ @error="handleError(index, $event)"
47
+ />
48
+
49
+ <Item v-bind="$props" is-adding-btn :ui="ui" @add="handleOpenFile" />
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </FieldWrapper>
55
+ </template>
56
+
57
+ <script lang="ts" setup>
58
+ import { useDropZone } from '@vueuse/core'
59
+ import { type IUploadDropzoneImageAutoMultipleProps } from './types'
60
+ import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
61
+ import { useFieldHOC } from '#core/composables/useForm'
62
+ import { _get, computed, ref, toRef, useUI, useUiConfig } from '#imports'
63
+ import { uploadFileDropzoneImage } from '#core/ui.config'
64
+ import Item from './item.vue'
65
+
66
+ const config = useUiConfig<typeof uploadFileDropzoneImage>(
67
+ uploadFileDropzoneImage,
68
+ 'uploadFileDropzoneImage'
69
+ )
70
+
71
+ const props = withDefaults(defineProps<IUploadDropzoneImageAutoMultipleProps>(), {
72
+ accept: 'image/*',
73
+ bodyKey: 'file',
74
+ responseKey: 'url',
75
+ selectFileLabel: 'คลิกเพื่อเลือกไฟล์',
76
+ selectFileSubLabel: 'หรือ ลากและวางที่นี่',
77
+ uploadAddLabel: 'อัพโหลด',
78
+ })
79
+
80
+ const emits = defineEmits(['change', 'success', 'delete'])
81
+ const selectedFiles = ref<File[]>([])
82
+
83
+ const { wrapperProps, handleChange: onChange, value } = useFieldHOC<File[]>(props)
84
+
85
+ const { ui } = useUI('uploadFileDropzoneImage', toRef(props, 'ui'), config)
86
+
87
+ const fileInputRef = ref<HTMLInputElement>()
88
+ const dropzoneRef = ref<HTMLDivElement>()
89
+
90
+ const acceptFile = computed(() =>
91
+ typeof props.accept === 'string' ? props.accept : props.accept?.join(',')
92
+ )
93
+
94
+ const onDrop = (files: File[] | null) => {
95
+ if (props.isDisabled || files?.length === 0 || !files) return
96
+
97
+ for (const file of files) {
98
+ selectedFiles.value = [...selectedFiles.value, file]
99
+
100
+ emits('change', value.value)
101
+ }
102
+ }
103
+
104
+ const { isOverDropZone } = useDropZone(dropzoneRef as unknown as HTMLElement, {
105
+ onDrop,
106
+ })
107
+
108
+ const handleChange = (e: Event) => {
109
+ if (props.isDisabled) return
110
+
111
+ for (const file of (e.target as HTMLInputElement).files ?? []) {
112
+ selectedFiles.value = [...selectedFiles.value, file]
113
+ emits('change', value.value)
114
+ }
115
+ }
116
+
117
+ const handleOpenFile = () => {
118
+ fileInputRef.value?.click()
119
+ }
120
+
121
+ const handleDeleteFile = (index: number) => {
122
+ selectedFiles.value.splice(index, 1)
123
+ onChange(undefined)
124
+ emits('delete')
125
+ }
126
+
127
+ const handleError = (index: number, error: any) => {}
128
+
129
+ const handleSuccess = (index: number, any: any) => {
130
+ value.value = [_get(any, props.responseKey), ...(value.value || [])]
131
+ emits('change', value.value)
132
+ emits('success', value.value)
133
+ }
134
+ </script>
@@ -0,0 +1,198 @@
1
+ <template>
2
+ <div :class="[ui.imageItem.wrapper]">
3
+ <div v-if="isAddingBtn" class="w-full">
4
+ <div :class="[ui.action.addingWrapper]" @click="$emit('add')">
5
+ <Icon :name="ui.action.addingIcon" :class="[ui.action.addingBtnClass]" />
6
+ <p :class="[ui.action.addingTextClass]">{{ uploadAddLabel }}</p>
7
+ </div>
8
+ </div>
9
+
10
+ <!-- Loading State -->
11
+ <div v-if="selectedFile && upload.status.value.isLoading" class="w-full">
12
+ <div :class="[ui.imageItem.onLoading.wrapper]">
13
+ <div :class="[ui.imageItem.onLoading.percentClass]">{{ percent }}%</div>
14
+ <UProgress :value="percent" />
15
+ </div>
16
+ </div>
17
+
18
+ <!-- Success State -->
19
+ <div v-if="selectedFile && upload.status.value.isSuccess" class="w-full">
20
+ <div :class="[ui.imageItem.onPreview.wrapper]">
21
+ <img
22
+ :class="[ui.imageItem.onPreview.previewImgClass]"
23
+ :src="upload.data.value[responseKey]"
24
+ alt="img"
25
+ />
26
+ <div :class="[ui.imageItem.onPreview.previewActionWrapper]">
27
+ <Icon
28
+ title="ดูตัวอย่าง"
29
+ :name="ui.action.previewIcon"
30
+ :class="[ui.imageItem.onPreview.actionBtnClass]"
31
+ @click="() => (isPreviewOpen = true)"
32
+ />
33
+ <Icon
34
+ title="ลบไฟล์"
35
+ :name="ui.action.deleteIcon"
36
+ :class="[ui.imageItem.onPreview.actionBtnClass]"
37
+ @click="handleDeleteFile"
38
+ />
39
+ <Modal v-model="isPreviewOpen" :title="selectedFile?.name">
40
+ <img :src="upload.data.value[responseKey]" alt="image-preview" />
41
+ </Modal>
42
+ </div>
43
+ </div>
44
+
45
+ <div :class="[ui.imageItem.onPreview.previewTextWrapper]">
46
+ <p :class="[ui.imageItem.onPreview.previewText]">{{ selectedFile.name }}</p>
47
+ </div>
48
+ </div>
49
+
50
+ <!-- Failed State -->
51
+ <div v-if="selectedFile && upload.status.value.isError" class="w-full">
52
+ <div :class="[ui.imageItem.onFailed.wrapper]">
53
+ <img
54
+ :class="[ui.imageItem.onFailed.failedImgClass]"
55
+ :src="generateURL(selectedFile)"
56
+ alt="img"
57
+ />
58
+ <div :class="[ui.imageItem.onFailed.failedActionWrapper]">
59
+ <Icon
60
+ title="ลบไฟล์"
61
+ :name="ui.action.deleteIcon"
62
+ :class="[ui.imageItem.onFailed.actionBtnClass]"
63
+ @click="handleDeleteFile"
64
+ />
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </div>
69
+ </template>
70
+
71
+ <script lang="ts" setup>
72
+ import {
73
+ checkFileType,
74
+ checkMaxSize,
75
+ generateURL,
76
+ getFileAllocate,
77
+ } from '#core/helpers/componentHelper'
78
+ import { type uploadFileDropzoneImage } from '#core/ui.config'
79
+ import type { IUploadDropzoneImageAutoMultipleProps } from '#core/components/Form/InputUploadDropzoneImageAutoMultiple/types'
80
+ import {
81
+ computed,
82
+ type IUploadRequest,
83
+ onMounted,
84
+ ref,
85
+ StringHelper,
86
+ useUploadLoader,
87
+ useWatchTrue,
88
+ } from '#imports'
89
+ import i18next from 'i18next'
90
+
91
+ const emits = defineEmits(['success', 'error', 'delete', 'add'])
92
+ const props = defineProps<
93
+ {
94
+ ui: typeof uploadFileDropzoneImage
95
+ selectedFile?: File
96
+ isAddingBtn?: boolean
97
+ } & IUploadDropzoneImageAutoMultipleProps
98
+ >()
99
+
100
+ const request: IUploadRequest = {
101
+ pathURL: props.uploadPathURL,
102
+ requestOptions: props.requestOptions,
103
+ }
104
+
105
+ const isPreviewOpen = ref<boolean>(false)
106
+ const percent = ref<number | string>(0)
107
+ const upload = useUploadLoader(request)
108
+ const errMsg = ref<string>('')
109
+
110
+ const acceptFile = computed(() =>
111
+ typeof props.accept === 'string' ? props.accept : props.accept?.join(',')
112
+ )
113
+
114
+ const fileAllocate = computed(() =>
115
+ getFileAllocate(props.maxSize ?? 0, props.selectedFile?.size ?? 0)
116
+ )
117
+
118
+ const handleDeleteFile = () => {
119
+ emits('delete')
120
+ }
121
+
122
+ const onUploadProgress = (progressEvent: ProgressEvent) => {
123
+ percent.value = StringHelper.withFixed(
124
+ (Math.floor((progressEvent.loaded * 100) / progressEvent.total) || 0) * 0.8
125
+ )
126
+ }
127
+
128
+ const onDownloadProgress = (progressEvent: ProgressEvent) => {
129
+ if (progressEvent.total === 0) {
130
+ percent.value = 100
131
+
132
+ return
133
+ }
134
+
135
+ percent.value = StringHelper.withFixed(
136
+ (Math.floor((progressEvent.loaded * 100) / progressEvent.total) || 0) * 0.2 + 80
137
+ )
138
+ }
139
+
140
+ const handleCheckFileCondition = (file: File | undefined): boolean => {
141
+ if (!file) return false
142
+
143
+ const fileType = checkFileType(file, acceptFile.value ?? '')
144
+
145
+ if (!fileType) {
146
+ errMsg.value = i18next.t('custom:invalid_file_type')
147
+
148
+ return false
149
+ }
150
+
151
+ const maxSize = checkMaxSize(file, fileAllocate.value.acceptFileSizeKb ?? 0)
152
+
153
+ if (!maxSize) {
154
+ if (fileAllocate.value.isAcceptFileUseMb) {
155
+ errMsg.value = i18next.t('custom:invalid_file_size_mb', {
156
+ size: fileAllocate.value.acceptFileSizeMb,
157
+ })
158
+ } else {
159
+ errMsg.value = i18next.t('custom:invalid_file_size_kb', {
160
+ size: fileAllocate.value.acceptFileSizeKb,
161
+ })
162
+ }
163
+
164
+ return false
165
+ }
166
+
167
+ errMsg.value = ''
168
+
169
+ return true
170
+ }
171
+
172
+ onMounted(() => {
173
+ if (props.isAddingBtn) return
174
+
175
+ const result = handleCheckFileCondition(props.selectedFile)
176
+
177
+ if (result) {
178
+ const formData = new FormData()
179
+
180
+ formData.append(props.bodyKey!, props.selectedFile!)
181
+ upload.run(formData, { data: { onUploadProgress, onDownloadProgress } })
182
+ }
183
+ })
184
+
185
+ useWatchTrue(
186
+ () => upload.status.value.isSuccess,
187
+ () => {
188
+ emits('success', upload.data.value)
189
+ }
190
+ )
191
+
192
+ useWatchTrue(
193
+ () => upload.status.value.isError,
194
+ () => {
195
+ emits('error', upload.status.value.errorData)
196
+ }
197
+ )
198
+ </script>
@@ -0,0 +1,20 @@
1
+ import { type AxiosRequestConfig } from 'axios';
2
+ import { type IFieldProps, type IFormFieldBase, type INPUT_TYPES } from '../types';
3
+ export interface IUploadDropzoneImageAutoMultipleProps extends IFieldProps {
4
+ requestOptions: Omit<AxiosRequestConfig, 'baseURL'> & {
5
+ baseURL: string;
6
+ };
7
+ uploadPathURL?: string;
8
+ selectFileLabel?: string;
9
+ selectFileSubLabel?: string;
10
+ uploadAddLabel?: string;
11
+ accept?: string[] | string;
12
+ bodyKey?: string;
13
+ responseKey?: string;
14
+ maxSize?: number;
15
+ }
16
+ export type IUploadDropzoneImageAutoMultipleField = IFormFieldBase<INPUT_TYPES.UPLOAD_DROPZONE_IMAGE_AUTO_MULTIPLE, IUploadDropzoneImageAutoMultipleProps, {
17
+ change: (value: File[] | undefined) => void;
18
+ success: (res: any) => void;
19
+ delete: () => void;
20
+ }>;
@@ -12,9 +12,9 @@
12
12
  />
13
13
  <div :class="[ui.wrapper]">
14
14
  <div :class="[ui.selectFileBox]">
15
- <Button size="2xs" @click="handleOpenFile">{{ selectFileLabel || 'Choose File' }}</Button>
15
+ <Button size="2xs" @click="handleOpenFile">{{ selectFileLabel }}</Button>
16
16
  <p :class="ui.placeholder">
17
- {{ value?.name ?? placeholder ?? 'No file chosen' }}
17
+ {{ value?.name ?? placeholder ?? 'ยังไม่ได้เลือกไฟล์' }}
18
18
  </p>
19
19
  <Badge v-if="value" size="xs" variant="outline">
20
20
  {{ isSelectedFileUseMb ? `${selectedFileSizeMb} MB` : `${selectedFileSizeKb} KB` }}
@@ -39,7 +39,9 @@ const config = useUiConfig<typeof uploadFileInputClassicAuto>(
39
39
  )
40
40
 
41
41
  const emits = defineEmits(['change'])
42
- const props = withDefaults(defineProps<IUploadFileClassicFieldProps>(), {})
42
+ const props = withDefaults(defineProps<IUploadFileClassicFieldProps>(), {
43
+ selectFileLabel: 'เลือกไฟล์',
44
+ })
43
45
 
44
46
  const { value, wrapperProps, setErrors } = useFieldHOC<File | undefined>(props)
45
47
  const selectedFileSizeKb = computed(() => ((value.value?.size || 0) / 1000).toFixed(2))
@@ -12,9 +12,9 @@
12
12
  />
13
13
  <div :class="[ui.wrapper]">
14
14
  <div :class="[ui.selectFileBox]">
15
- <Button size="2xs" @click="handleOpenFile">{{ selectFileLabel || 'Choose File' }}</Button>
15
+ <Button size="2xs" @click="handleOpenFile">{{ selectFileLabel }}</Button>
16
16
  <p :class="ui.placeholder">
17
- {{ selectedFile?.name ?? placeholder ?? 'No file chosen' }}
17
+ {{ selectedFile?.name ?? placeholder ?? 'ยังไม่ได้เลือกไฟล์' }}
18
18
  </p>
19
19
  <Badge v-if="selectedFile" size="xs" variant="outline">
20
20
  {{ isSelectedFileUseMb ? `${selectedFileSizeMb} MB` : `${selectedFileSizeKb} KB` }}
@@ -67,7 +67,11 @@ const config = useUiConfig<typeof uploadFileInputClassicAuto>(
67
67
  )
68
68
 
69
69
  const emits = defineEmits(['success'])
70
- const props = withDefaults(defineProps<IUploadFileProps>(), {})
70
+ const props = withDefaults(defineProps<IUploadFileProps>(), {
71
+ bodyKey: 'file',
72
+ responseKey: 'url',
73
+ selectFileLabel: 'เลือกไฟล์',
74
+ })
71
75
 
72
76
  const { wrapperProps, setErrors, value } = useFieldHOC<string>(props)
73
77
 
@@ -110,7 +114,7 @@ const handleChange = (e: Event) => {
110
114
  selectedFile.value = file
111
115
  const formData = new FormData()
112
116
 
113
- formData.append(props.bodyKey || 'file', file)
117
+ formData.append(props.bodyKey, file)
114
118
  upload.run(formData, { data: { onUploadProgress, onDownloadProgress } })
115
119
  }
116
120
  }
@@ -160,7 +164,7 @@ const onDownloadProgress = (progressEvent: ProgressEvent) => {
160
164
  useWatchTrue(
161
165
  () => upload.status.value.isSuccess,
162
166
  () => {
163
- value.value = _get(upload.data.value, props.responseKey || 'url')
167
+ value.value = _get(upload.data.value, props.responseKey)
164
168
  emits('success', upload.data.value)
165
169
  }
166
170
  )
@@ -14,6 +14,7 @@ import { type IUploadDropzoneField } from '#core/components/Form/InputUploadDrop
14
14
  import { type IUploadDropzoneAutoField } from '#core/components/Form/InputUploadDropzoneAuto/types';
15
15
  import type { INumberField } from '#core/components/Form/InputNumber/types';
16
16
  import type { IUploadDropzoneAutoMultipleField } from '#core/components/Form/InputUploadDropzoneAutoMultiple/types';
17
+ import type { IUploadDropzoneImageAutoMultipleField } from '#core/components/Form/InputUploadDropzoneImageAutoMultiple/types';
17
18
  export declare const enum INPUT_TYPES {
18
19
  TEXT = "TEXT",
19
20
  NUMBER = "NUMBER",
@@ -31,7 +32,8 @@ export declare const enum INPUT_TYPES {
31
32
  UPLOAD_FILE_CLASSIC_AUTO = "UPLOAD_FILE_CLASSIC_AUTO",
32
33
  UPLOAD_DROPZONE = "UPLOAD_DROPZONE",
33
34
  UPLOAD_DROPZONE_AUTO = "UPLOAD_DROPZONE_AUTO",
34
- UPLOAD_DROPZONE_AUTO_MULTIPLE = "UPLOAD_DROPZONE_AUTO_MULTIPLE"
35
+ UPLOAD_DROPZONE_AUTO_MULTIPLE = "UPLOAD_DROPZONE_AUTO_MULTIPLE",
36
+ UPLOAD_DROPZONE_IMAGE_AUTO_MULTIPLE = "UPLOAD_DROPZONE_IMAGE_AUTO_MULTIPLE"
35
37
  }
36
38
  export interface IFieldProps {
37
39
  form?: FormContext;
@@ -60,4 +62,4 @@ export interface IFormFieldBase<I extends INPUT_TYPES, P extends IFieldProps, O>
60
62
  props: P;
61
63
  on?: O;
62
64
  }
63
- export type IFormField = ITextField | INumberField | IStaticField | ICheckboxField | IRadioField | ISelectField | IToggleField | ITextareaField | IDateTimeField | IUploadFileClassicField | IUploadFileField | IUploadDropzoneField | IUploadDropzoneAutoField | IUploadDropzoneAutoMultipleField;
65
+ export type IFormField = ITextField | INumberField | IStaticField | ICheckboxField | IRadioField | ISelectField | IToggleField | ITextareaField | IDateTimeField | IUploadFileClassicField | IUploadFileField | IUploadDropzoneField | IUploadDropzoneAutoField | IUploadDropzoneAutoMultipleField | IUploadDropzoneImageAutoMultipleField;
@@ -16,5 +16,6 @@ export var INPUT_TYPES = /* @__PURE__ */ ((INPUT_TYPES2) => {
16
16
  INPUT_TYPES2["UPLOAD_DROPZONE"] = "UPLOAD_DROPZONE";
17
17
  INPUT_TYPES2["UPLOAD_DROPZONE_AUTO"] = "UPLOAD_DROPZONE_AUTO";
18
18
  INPUT_TYPES2["UPLOAD_DROPZONE_AUTO_MULTIPLE"] = "UPLOAD_DROPZONE_AUTO_MULTIPLE";
19
+ INPUT_TYPES2["UPLOAD_DROPZONE_IMAGE_AUTO_MULTIPLE"] = "UPLOAD_DROPZONE_IMAGE_AUTO_MULTIPLE";
19
20
  return INPUT_TYPES2;
20
21
  })(INPUT_TYPES || {});
@@ -0,0 +1,7 @@
1
+ export declare const useNotification: () => {
2
+ info: (notification: Notification) => void;
3
+ success: (notification: Notification) => void;
4
+ warning: (notification: Notification) => void;
5
+ error: (notification: Notification) => void;
6
+ remove: any;
7
+ };
@@ -0,0 +1,39 @@
1
+ import { useToast } from "#imports";
2
+ export const useNotification = () => {
3
+ const toast = useToast();
4
+ const info = (notification) => {
5
+ toast.add({
6
+ icon: "ph:info",
7
+ color: "info",
8
+ ...notification
9
+ });
10
+ };
11
+ const success = (notification) => {
12
+ toast.add({
13
+ icon: "ph:check-circle",
14
+ color: "success",
15
+ ...notification
16
+ });
17
+ };
18
+ const warning = (notification) => {
19
+ toast.add({
20
+ icon: "ph:warning",
21
+ color: "warning",
22
+ ...notification
23
+ });
24
+ };
25
+ const error = (notification) => {
26
+ toast.add({
27
+ icon: "ph:x-circle",
28
+ color: "danger",
29
+ ...notification
30
+ });
31
+ };
32
+ return {
33
+ info,
34
+ success,
35
+ warning,
36
+ error,
37
+ remove: toast.remove
38
+ };
39
+ };
@@ -1 +1 @@
1
- export type UIComponentList = 'modal' | 'slideover' | 'dropdown' | 'icon' | 'button' | 'buttonGroup' | 'tabs' | 'card' | 'breadcrumb' | 'badge' | 'input' | 'pagination' | 'notification' | 'uploadFileInputClassicAuto' | 'uploadFileDropzone';
1
+ export type UIComponentList = 'modal' | 'slideover' | 'dropdown' | 'icon' | 'button' | 'buttonGroup' | 'tabs' | 'card' | 'breadcrumb' | 'badge' | 'input' | 'pagination' | 'notification' | 'uploadFileInputClassicAuto' | 'uploadFileDropzone' | 'uploadFileDropzoneImage';
@@ -11,3 +11,4 @@ export { slideover } from './slideover';
11
11
  export { breadcrumb } from './breadcrumb';
12
12
  export { uploadFileInputClassicAuto } from './uploadFileInputClassicAuto';
13
13
  export { uploadFileDropzone } from './uploadFileDropzone';
14
+ export { uploadFileDropzoneImage } from './uploadDropzoneImage';
@@ -11,3 +11,4 @@ export { slideover } from "./slideover.mjs";
11
11
  export { breadcrumb } from "./breadcrumb.mjs";
12
12
  export { uploadFileInputClassicAuto } from "./uploadFileInputClassicAuto.mjs";
13
13
  export { uploadFileDropzone } from "./uploadFileDropzone.mjs";
14
+ export { uploadFileDropzoneImage } from "./uploadDropzoneImage.mjs";
@@ -0,0 +1,83 @@
1
+ export declare const uploadFileDropzoneImage: {
2
+ imageItemWrapper: string;
3
+ imageItem: {
4
+ wrapper: string;
5
+ onLoading: {
6
+ wrapper: string;
7
+ percentClass: string;
8
+ };
9
+ onPreview: {
10
+ wrapper: string;
11
+ previewImgClass: string;
12
+ previewActionWrapper: string;
13
+ actionBtnClass: string;
14
+ previewTextWrapper: string;
15
+ previewText: string;
16
+ };
17
+ onFailed: {
18
+ wrapper: string;
19
+ failedImgClass: string;
20
+ failedActionWrapper: string;
21
+ actionBtnClass: string;
22
+ };
23
+ };
24
+ base: string;
25
+ wrapper: string;
26
+ disabled: string;
27
+ failed: string;
28
+ placeholderWrapper: string;
29
+ placeholder: string;
30
+ labelWrapper: string;
31
+ onLoading: {
32
+ wrapper: string;
33
+ placeholderWrapper: string;
34
+ placeholderImgIcon: string;
35
+ placeholderFileIcon: string;
36
+ placeholderIconClass: string;
37
+ textWrapper: string;
38
+ loadingIcon: string;
39
+ loadingIconClass: string;
40
+ };
41
+ onPreview: {
42
+ wrapper: string;
43
+ previewImgWrapper: string;
44
+ previewImgClass: string;
45
+ previewFileIcon: string;
46
+ previewFileClass: string;
47
+ textWrapper: string;
48
+ };
49
+ onFailed: {
50
+ wrapper: string;
51
+ failedImgWrapper: string;
52
+ failedImgIcon: string;
53
+ failedFileIcon: string;
54
+ failedIconClass: string;
55
+ textWrapper: string;
56
+ };
57
+ action: {
58
+ wrapper: string;
59
+ addingWrapper: string;
60
+ iconClass: string;
61
+ deleteIconClass: string;
62
+ retryBtnClass: string;
63
+ addingBtnClass: string;
64
+ addingTextClass: string;
65
+ previewIcon: string;
66
+ downloadIcon: string;
67
+ deleteIcon: string;
68
+ retryIcon: string;
69
+ addingIcon: string;
70
+ };
71
+ background: {
72
+ default: string;
73
+ dragover: string;
74
+ };
75
+ labelIcon: string;
76
+ default: {
77
+ filePreviewIcon: string;
78
+ uploadIcon: string;
79
+ placeholderImgIcon: string;
80
+ failedImgIcon: string;
81
+ loadingIcon: string;
82
+ };
83
+ };
@@ -0,0 +1,26 @@
1
+ import { uploadFileDropzone } from "./uploadFileDropzone.mjs";
2
+ export const uploadFileDropzoneImage = {
3
+ ...uploadFileDropzone,
4
+ imageItemWrapper: "flex w-full flex-wrap gap-4",
5
+ imageItem: {
6
+ wrapper: "max-w-[96px]",
7
+ onLoading: {
8
+ wrapper: "flex size-24 flex-col items-center justify-center overflow-hidden rounded-lg border-[1px] border-dashed p-2",
9
+ percentClass: "text-primary"
10
+ },
11
+ onPreview: {
12
+ wrapper: "relative size-24 overflow-hidden rounded-lg ring-[1px] ring-gray-100",
13
+ previewImgClass: "size-full object-cover",
14
+ previewActionWrapper: "absolute inset-0 z-10 flex items-center justify-center space-x-2 opacity-0 transition hover:bg-black/50 hover:opacity-100",
15
+ actionBtnClass: "size-7 cursor-pointer text-white",
16
+ previewTextWrapper: "mt-2 truncate",
17
+ previewText: "truncate text-center text-sm"
18
+ },
19
+ onFailed: {
20
+ wrapper: "ring-danger relative size-24 overflow-hidden rounded-lg ring-[1px]",
21
+ failedImgClass: "size-full object-cover",
22
+ failedActionWrapper: "absolute inset-0 z-10 flex items-center justify-center space-x-2 bg-white/50",
23
+ actionBtnClass: "text-danger size-7 cursor-pointer"
24
+ }
25
+ }
26
+ };
@@ -34,13 +34,17 @@ export declare const uploadFileDropzone: {
34
34
  };
35
35
  action: {
36
36
  wrapper: string;
37
+ addingWrapper: string;
37
38
  iconClass: string;
38
39
  deleteIconClass: string;
39
40
  retryBtnClass: string;
41
+ addingBtnClass: string;
42
+ addingTextClass: string;
40
43
  previewIcon: string;
41
44
  downloadIcon: string;
42
45
  deleteIcon: string;
43
46
  retryIcon: string;
47
+ addingIcon: string;
44
48
  };
45
49
  background: {
46
50
  default: string;
@@ -34,13 +34,17 @@ export const uploadFileDropzone = {
34
34
  },
35
35
  action: {
36
36
  wrapper: "flex items-center space-x-4",
37
+ addingWrapper: "flex size-24 flex-col items-center justify-center overflow-hidden rounded-lg border-[1px] border-dashed p-2 cursor-pointer transition hover:bg-gray-100",
37
38
  iconClass: "size-6 text-gray-400 cursor-pointer",
38
39
  deleteIconClass: "size-6 text-danger cursor-pointer",
39
40
  retryBtnClass: "px-0",
41
+ addingBtnClass: "size-7 text-gray-500",
42
+ addingTextClass: "text-center text-sm text-gray-500",
40
43
  previewIcon: "i-ic:outline-remove-red-eye",
41
44
  downloadIcon: "i-ic:outline-file-download",
42
45
  deleteIcon: "ph:trash",
43
- retryIcon: "ph:arrow-counter-clockwise"
46
+ retryIcon: "ph:arrow-counter-clockwise",
47
+ addingIcon: "i-material-symbols:add"
44
48
  },
45
49
  background: {
46
50
  default: "bg-white border-gray-border",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "1.4.92",
3
+ "version": "1.4.93",
4
4
  "repository": "https://gitlab.finema.co/finema/ui-kit",
5
5
  "license": "MIT",
6
6
  "author": "Finema Dev Core Team",