@finema/core 2.21.1 → 2.23.0

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 (29) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +1 -1
  3. package/dist/runtime/components/Form/Fields.vue +5 -1
  4. package/dist/runtime/components/Form/InputUploadDropzone/index.vue +105 -0
  5. package/dist/runtime/components/Form/InputUploadDropzone/index.vue.d.ts +12 -0
  6. package/dist/runtime/components/Form/InputUploadDropzone/types.d.ts +11 -0
  7. package/dist/runtime/components/Form/InputUploadDropzone/types.js +0 -0
  8. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue +5 -5
  9. package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/EmptyState.vue +1 -1
  10. package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/FailedState.vue +1 -1
  11. package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/LoadingState.vue +1 -1
  12. package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/SuccessState.vue +7 -6
  13. package/dist/runtime/components/Form/fileState/useFileState.d.ts +23 -0
  14. package/dist/runtime/components/Form/fileState/useFileState.js +154 -0
  15. package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/useUploadState.d.ts +1 -1
  16. package/dist/runtime/components/Form/types.d.ts +2 -1
  17. package/dist/runtime/components/Table/index.vue +1 -0
  18. package/dist/runtime/composables/useFileIcon.d.ts +1 -0
  19. package/dist/runtime/composables/useFileIcon.js +9 -0
  20. package/dist/runtime/theme/uploadFileDropzone.d.ts +4 -3
  21. package/dist/runtime/theme/uploadFileDropzone.js +4 -3
  22. package/package.json +1 -1
  23. /package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/EmptyState.vue.d.ts +0 -0
  24. /package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/FailedState.vue.d.ts +0 -0
  25. /package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/LoadingState.vue.d.ts +0 -0
  26. /package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/PreviewModal.vue +0 -0
  27. /package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/PreviewModal.vue.d.ts +0 -0
  28. /package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/SuccessState.vue.d.ts +0 -0
  29. /package/dist/runtime/components/Form/{InputUploadDropzoneAuto → fileState}/useUploadState.js +0 -0
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "2.21.1",
3
+ "version": "2.23.0",
4
4
  "configKey": "core",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.1",
package/dist/module.mjs CHANGED
@@ -3,7 +3,7 @@ import defu from 'defu';
3
3
  import * as theme from '../dist/runtime/theme/index.js';
4
4
 
5
5
  const name = "@finema/core";
6
- const version = "2.21.1";
6
+ const version = "2.23.0";
7
7
 
8
8
  const nuxtAppOptions = {
9
9
  head: {
@@ -33,6 +33,7 @@ import FormInputRadio from "./InputRadio/index.vue";
33
33
  import FormInputDateTime from "./InputDateTime/index.vue";
34
34
  import FormInputDateTimeRange from "./InputDateTimeRange/index.vue";
35
35
  import FormInputUploadDropzoneAuto from "./InputUploadDropzoneAuto/index.vue";
36
+ import FormInputUploadDropzone from "./InputUploadDropzone/index.vue";
36
37
  import FormInputWYSIWYG from "./InputWYSIWYG/index.vue";
37
38
  import { INPUT_TYPES } from "#core/components/Form/types";
38
39
  import { formTheme } from "#core/theme/form";
@@ -121,7 +122,10 @@ const componentMap = {
121
122
  [INPUT_TYPES.UPLOAD_FILE_CLASSIC]: void 0,
122
123
  [INPUT_TYPES.UPLOAD_FILE_CLASSIC_AUTO]: void 0,
123
124
  [INPUT_TYPES.UPLOAD_IMAGE_AUTO]: void 0,
124
- [INPUT_TYPES.UPLOAD_DROPZONE]: void 0,
125
+ [INPUT_TYPES.UPLOAD_DROPZONE]: {
126
+ component: FormInputUploadDropzone,
127
+ props: {}
128
+ },
125
129
  [INPUT_TYPES.UPLOAD_DROPZONE_AUTO]: {
126
130
  component: FormInputUploadDropzoneAuto,
127
131
  props: {}
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <FieldWrapper v-bind="wrapperProps">
3
+ <div
4
+ ref="dropzoneRef"
5
+ :class="theme.base()"
6
+ >
7
+ <div :class="theme.wrapper()">
8
+ <!-- Empty State -->
9
+ <EmptyState
10
+ v-if="uploadState.isEmpty.value"
11
+ :theme="theme"
12
+ :select-file-label="selectFileLabel"
13
+ :select-file-sub-label="selectFileSubLabel"
14
+ :placeholder="placeholder"
15
+ @open-file="uploadState.handleOpenFile"
16
+ />
17
+
18
+ <!-- Success State -->
19
+ <SuccessState
20
+ v-if="uploadState.isSuccess.value"
21
+ :theme="theme"
22
+ :value="value"
23
+ :disabled="wrapperProps.disabled"
24
+ :readonly="wrapperProps.readonly"
25
+ @preview="uploadState.handlePreview"
26
+ @download="handleDownloadFile"
27
+ @delete="uploadState.handleDeleteFile"
28
+ />
29
+ </div>
30
+ </div>
31
+ </FieldWrapper>
32
+ </template>
33
+
34
+ <script setup>
35
+ import EmptyState from "../fileState/EmptyState.vue";
36
+ import SuccessState from "../fileState/SuccessState.vue";
37
+ import { useFileState } from "../fileState/useFileState";
38
+ import { computed, useTemplateRef, useWatchChange } from "#imports";
39
+ import FieldWrapper from "#core/components/Form/FieldWrapper.vue";
40
+ import { useFieldHOC } from "#core/composables/useForm";
41
+ import { uploadFileDropzoneTheme } from "#core/theme/uploadFileDropzone";
42
+ import { useUiConfig } from "#core/composables/useConfig";
43
+ const props = defineProps({
44
+ accept: { type: [Array, String], required: false },
45
+ maxSize: { type: Number, required: false },
46
+ selectFileLabel: { type: String, required: false, default: "\u0E04\u0E25\u0E34\u0E01\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E1F\u0E25\u0E4C" },
47
+ selectFileSubLabel: { type: String, required: false, default: "\u0E2B\u0E23\u0E37\u0E2D \u0E25\u0E32\u0E01\u0E41\u0E25\u0E30\u0E27\u0E32\u0E07\u0E17\u0E35\u0E48\u0E19\u0E35\u0E48" },
48
+ form: { type: Object, required: false },
49
+ name: { type: String, required: true },
50
+ errorMessage: { type: String, required: false },
51
+ label: { type: null, required: false },
52
+ description: { type: String, required: false },
53
+ hint: { type: String, required: false },
54
+ rules: { type: null, required: false },
55
+ autoFocus: { type: Boolean, required: false },
56
+ placeholder: { type: String, required: false },
57
+ disabled: { type: Boolean, required: false },
58
+ readonly: { type: Boolean, required: false },
59
+ required: { type: Boolean, required: false },
60
+ help: { type: String, required: false },
61
+ ui: { type: null, required: false }
62
+ });
63
+ const emits = defineEmits(["change", "delete"]);
64
+ const {
65
+ wrapperProps,
66
+ handleChange: onChange,
67
+ setErrors,
68
+ value
69
+ } = useFieldHOC(props);
70
+ const acceptedFileTypes = computed(
71
+ () => typeof props.accept === "string" ? props.accept : props.accept?.join(",")
72
+ );
73
+ const dropzoneRef = useTemplateRef("dropzoneRef");
74
+ const uploadState = useFileState(
75
+ props,
76
+ emits,
77
+ onChange,
78
+ setErrors,
79
+ value,
80
+ acceptedFileTypes,
81
+ wrapperProps,
82
+ dropzoneRef
83
+ );
84
+ useWatchChange(() => value.value, (newValue) => {
85
+ if (typeof newValue === "object" && newValue !== null) {
86
+ onChange(newValue);
87
+ } else {
88
+ onChange(void 0);
89
+ }
90
+ });
91
+ const theme = computed(
92
+ () => useUiConfig(uploadFileDropzoneTheme, "uploadFileDropzone")({
93
+ dragover: uploadState.dropzone.isOverDropZone.value && uploadState.isEmpty.value,
94
+ disabled: wrapperProps.value.disabled
95
+ })
96
+ );
97
+ const handleDownloadFile = () => {
98
+ if (value.value?.url && value.value?.name) {
99
+ const a = document.createElement("a");
100
+ a.href = value.value.url;
101
+ a.download = value.value.name;
102
+ a.click();
103
+ }
104
+ };
105
+ </script>
@@ -0,0 +1,12 @@
1
+ import type { IUploadDropzoneProps } from './types.js';
2
+ declare const _default: import("vue").DefineComponent<IUploadDropzoneProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
+ delete: () => any;
4
+ change: (value: File | undefined) => any;
5
+ }, string, import("vue").PublicProps, Readonly<IUploadDropzoneProps> & Readonly<{
6
+ onDelete?: (() => any) | undefined;
7
+ onChange?: ((value: File | undefined) => any) | undefined;
8
+ }>, {
9
+ selectFileLabel: string;
10
+ selectFileSubLabel: string;
11
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import type { IFieldProps, IFormFieldBase, INPUT_TYPES } from '../types.js';
2
+ export interface IUploadDropzoneProps extends IFieldProps {
3
+ accept?: string[] | string;
4
+ maxSize?: number;
5
+ selectFileLabel?: string;
6
+ selectFileSubLabel?: string;
7
+ }
8
+ export type IUploadDropzoneField = IFormFieldBase<INPUT_TYPES.UPLOAD_DROPZONE, IUploadDropzoneProps, {
9
+ change: (value: File | undefined) => void;
10
+ delete: () => void;
11
+ }>;
@@ -52,11 +52,11 @@
52
52
  </template>
53
53
 
54
54
  <script setup>
55
- import EmptyState from "./EmptyState.vue";
56
- import LoadingState from "./LoadingState.vue";
57
- import SuccessState from "./SuccessState.vue";
58
- import FailedState from "./FailedState.vue";
59
- import { useUploadState } from "./useUploadState";
55
+ import EmptyState from "../fileState/EmptyState.vue";
56
+ import SuccessState from "../fileState/SuccessState.vue";
57
+ import LoadingState from "../fileState/LoadingState.vue";
58
+ import FailedState from "../fileState/FailedState.vue";
59
+ import { useUploadState } from "../fileState/useUploadState";
60
60
  import { computed, useTemplateRef, useWatchChange } from "#imports";
61
61
  import FieldWrapper from "#core/components/Form/FieldWrapper.vue";
62
62
  import { useFieldHOC } from "#core/composables/useForm";
@@ -23,7 +23,7 @@
23
23
  </template>
24
24
 
25
25
  <script setup>
26
- import { useUiIconConfig } from "#imports";
26
+ import { useUiIconConfig } from "#core/composables/useConfig";
27
27
  defineProps({
28
28
  theme: { type: null, required: true },
29
29
  selectFileLabel: { type: String, required: true },
@@ -36,7 +36,7 @@
36
36
 
37
37
  <script setup>
38
38
  import { isImage } from "#core/helpers/componentHelper";
39
- import { useUiIconConfig } from "#imports";
39
+ import { useUiIconConfig } from "#core/composables/useConfig";
40
40
  const props = defineProps({
41
41
  theme: { type: null, required: true },
42
42
  selectedFile: { type: null, required: true },
@@ -27,7 +27,7 @@
27
27
 
28
28
  <script setup>
29
29
  import { isImage } from "#core/helpers/componentHelper";
30
- import { useUiIconConfig } from "#imports";
30
+ import { useUiIconConfig } from "#core/composables/useConfig";
31
31
  const props = defineProps({
32
32
  theme: { type: null, required: true },
33
33
  selectedFile: { type: null, required: true },
@@ -1,20 +1,21 @@
1
1
  <template>
2
2
  <div :class="theme.onPreviewWrapper()">
3
- <div :class="theme.onPreviewPreviewImgWrapper()">
3
+ <div v-if="isImageFromPath(value.path)" :class="theme.onPreviewImgWrapper()">
4
4
  <div
5
- v-if="isImageFromPath(value.path)"
6
5
  class="size-full overflow-hidden"
7
6
  >
8
7
  <img
9
8
  :src="value.url"
10
- :class="theme.onPreviewPreviewImgClass()"
9
+ :class="theme.onPreviewImgClass()"
11
10
  alt="img-preview"
12
11
  />
13
12
  </div>
14
- <div v-else>
13
+ </div>
14
+ <div v-else :class="theme.onPreviewFileWrapper()">
15
+ <div >
15
16
  <Icon
16
17
  :name="icons.filePreviewIcon"
17
- :class="theme.onPreviewPreviewFileClass()"
18
+ :class="theme.onPreviewFileClass()"
18
19
  />
19
20
  </div>
20
21
  </div>
@@ -72,7 +73,7 @@ import {
72
73
  isVideoFromPath,
73
74
  useFileSize
74
75
  } from "#core/helpers/componentHelper";
75
- import { useUiIconConfig } from "#imports";
76
+ import { useUiIconConfig } from "#core/composables/useConfig";
76
77
  defineProps({
77
78
  theme: { type: null, required: true },
78
79
  value: { type: Object, required: true },
@@ -0,0 +1,23 @@
1
+ import type { TemplateRef } from 'vue';
2
+ import type { IUploadDropzoneProps } from '../InputUploadDropzone/types.js';
3
+ import type { IFileValue } from '#core/components/Form/types';
4
+ export declare enum UploadState {
5
+ EMPTY = "empty",
6
+ UPLOADING = "uploading",
7
+ SUCCESS = "success",
8
+ ERROR = "error"
9
+ }
10
+ export declare const useFileState: (props: IUploadDropzoneProps, emits: any, onChange: (value: IFileValue | undefined) => void, setErrors: (error: string) => void, value: any, acceptedFileTypes: any, wrapperProps: any, dropzoneRef: TemplateRef<HTMLDivElement | undefined>) => {
11
+ currentState: import("vue").ComputedRef<UploadState.EMPTY | UploadState.SUCCESS>;
12
+ isEmpty: import("vue").ComputedRef<boolean>;
13
+ isSuccess: import("vue").ComputedRef<boolean>;
14
+ selectedFile: import("vue").Ref<File | undefined, File | undefined>;
15
+ currentObjectUrl: import("vue").Ref<string, string>;
16
+ dropzone: import("@vueuse/core").UseDropZoneReturn;
17
+ handleInputChange: (event: Event) => void;
18
+ handleOpenFile: () => void;
19
+ handleDeleteFile: () => void;
20
+ handleRetryUpload: () => void;
21
+ handlePreview: () => void;
22
+ cleanup: () => void;
23
+ };
@@ -0,0 +1,154 @@
1
+ import { useDropZone, useFileDialog } from "@vueuse/core";
2
+ import PreviewModal from "../fileState/PreviewModal.vue";
3
+ import { computed, ref, useOverlay } from "#imports";
4
+ import { useFileAllocate } from "#core/helpers/componentHelper";
5
+ const overlay = useOverlay();
6
+ const previewModal = overlay.create(PreviewModal);
7
+ export var UploadState = /* @__PURE__ */ ((UploadState2) => {
8
+ UploadState2["EMPTY"] = "empty";
9
+ UploadState2["UPLOADING"] = "uploading";
10
+ UploadState2["SUCCESS"] = "success";
11
+ UploadState2["ERROR"] = "error";
12
+ return UploadState2;
13
+ })(UploadState || {});
14
+ export const useFileState = (props, emits, onChange, setErrors, value, acceptedFileTypes, wrapperProps, dropzoneRef) => {
15
+ const selectedFile = ref();
16
+ const currentObjectUrl = ref("");
17
+ const fileAllocate = useFileAllocate(selectedFile, props);
18
+ const validateFile = (file) => {
19
+ if (props.accept && fileAllocate.acceptFile.value) {
20
+ const acceptedTypes = fileAllocate.acceptFile.value;
21
+ const acceptedTypesList = acceptedTypes.split(",").map((type) => type.trim());
22
+ const fileExtension = file.name.toLowerCase().split(".").pop();
23
+ const isValidFileType = acceptedTypesList.some((acceptedType) => {
24
+ if (acceptedType.startsWith(".")) {
25
+ const extension = acceptedType.slice(1).toLowerCase();
26
+ return fileExtension === extension;
27
+ } else if (!acceptedType.includes("/") && !acceptedType.includes("*")) {
28
+ return fileExtension === acceptedType.toLowerCase();
29
+ }
30
+ if (acceptedType.endsWith("/*")) {
31
+ const baseType = acceptedType.slice(0, -2);
32
+ return file.type.startsWith(baseType + "/");
33
+ }
34
+ return file.type === acceptedType;
35
+ });
36
+ if (!isValidFileType) {
37
+ setErrors("\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17\u0E44\u0E1F\u0E25\u0E4C\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07 (\u0E23\u0E2D\u0E07\u0E23\u0E31\u0E1A\u0E40\u0E09\u0E1E\u0E32\u0E30 " + acceptedTypesList.join(", ") + ")");
38
+ return false;
39
+ }
40
+ }
41
+ if (props.maxSize) {
42
+ const maxSizeBytes = (fileAllocate.acceptFileSizeKb.value || 0) * 1024;
43
+ if (file.size > maxSizeBytes) {
44
+ if (fileAllocate.isAcceptFileUseMb.value) {
45
+ setErrors(`\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${fileAllocate.acceptFileSizeMb.value} MB`);
46
+ } else {
47
+ setErrors(`\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${fileAllocate.acceptFileSizeKb.value} KB`);
48
+ }
49
+ return false;
50
+ }
51
+ }
52
+ setErrors("");
53
+ return true;
54
+ };
55
+ const processFile = (file) => {
56
+ if (!validateFile(file)) return;
57
+ selectedFile.value = file;
58
+ emits("change", file);
59
+ if (currentObjectUrl.value) {
60
+ URL.revokeObjectURL(currentObjectUrl.value);
61
+ }
62
+ const objectUrl = URL.createObjectURL(file);
63
+ currentObjectUrl.value = objectUrl;
64
+ value.value = file;
65
+ emits("success", file);
66
+ };
67
+ const handleFileDrop = (files) => {
68
+ if (wrapperProps.value.disabled || wrapperProps.value.readonly || !files?.length || !isEmpty.value) return;
69
+ const file = files[0];
70
+ if (file) {
71
+ processFile(file);
72
+ }
73
+ };
74
+ const fileDialog = useFileDialog({
75
+ accept: acceptedFileTypes.value || "",
76
+ directory: false,
77
+ multiple: false
78
+ });
79
+ const dropzone = useDropZone(dropzoneRef, {
80
+ onDrop: handleFileDrop,
81
+ // dataTypes: typeof props.accept === 'string' ? [props.accept] : props.accept,
82
+ multiple: false,
83
+ preventDefaultForUnhandled: false
84
+ });
85
+ const currentState = computed(() => {
86
+ if (value.value) return "success" /* SUCCESS */;
87
+ return "empty" /* EMPTY */;
88
+ });
89
+ const isEmpty = computed(() => currentState.value === "empty" /* EMPTY */);
90
+ const isSuccess = computed(() => currentState.value === "success" /* SUCCESS */);
91
+ const handleInputChange = (event) => {
92
+ if (wrapperProps.value.disabled || wrapperProps.value.readonly) return;
93
+ const file = event.target.files?.[0];
94
+ if (file) {
95
+ processFile(file);
96
+ }
97
+ };
98
+ fileDialog.onChange((files) => {
99
+ if (files?.length) {
100
+ processFile(files[0]);
101
+ }
102
+ });
103
+ const handleOpenFile = () => {
104
+ if (wrapperProps.value.disabled || wrapperProps.value.readonly) return;
105
+ fileDialog.open();
106
+ };
107
+ const handleDeleteFile = () => {
108
+ fileDialog.reset();
109
+ if (currentObjectUrl.value) {
110
+ URL.revokeObjectURL(currentObjectUrl.value);
111
+ currentObjectUrl.value = "";
112
+ }
113
+ selectedFile.value = void 0;
114
+ onChange(void 0);
115
+ emits("delete");
116
+ };
117
+ const handleRetryUpload = () => {
118
+ if (selectedFile.value) {
119
+ processFile(selectedFile.value);
120
+ }
121
+ };
122
+ const handlePreview = () => {
123
+ previewModal.open({
124
+ value: value.value
125
+ });
126
+ };
127
+ const cleanup = () => {
128
+ if (currentObjectUrl.value) {
129
+ URL.revokeObjectURL(currentObjectUrl.value);
130
+ currentObjectUrl.value = "";
131
+ }
132
+ };
133
+ if (typeof window !== "undefined") {
134
+ window.addEventListener("beforeunload", cleanup);
135
+ }
136
+ return {
137
+ // State
138
+ currentState,
139
+ isEmpty,
140
+ isSuccess,
141
+ selectedFile,
142
+ currentObjectUrl,
143
+ // Upload utilities
144
+ dropzone,
145
+ // Handlers
146
+ handleInputChange,
147
+ handleOpenFile,
148
+ handleDeleteFile,
149
+ handleRetryUpload,
150
+ handlePreview,
151
+ // Cleanup
152
+ cleanup
153
+ };
154
+ };
@@ -1,5 +1,5 @@
1
1
  import type { TemplateRef } from 'vue';
2
- import type { IUploadDropzoneAutoProps } from './types.js';
2
+ import type { IUploadDropzoneAutoProps } from '../InputUploadDropzoneAuto/types.js';
3
3
  import type { IFileValue } from '#core/components/Form/types';
4
4
  export declare enum UploadState {
5
5
  EMPTY = "empty",
@@ -1,5 +1,6 @@
1
1
  import type { Component } from '@nuxt/schema';
2
2
  import type { FormContext } from 'vee-validate';
3
+ import type { IUploadDropzoneField } from './InputUploadDropzone/types.js';
3
4
  import type { IUploadDropzoneAutoField } from './InputUploadDropzoneAuto/types.js';
4
5
  import type { IDateTimeRangeField } from './InputDateTimeRange/date_range_time_field.types.js';
5
6
  import type { ITextField } from '#core/components/Form/InputText/types';
@@ -66,7 +67,7 @@ export interface IFormFieldBase<I extends INPUT_TYPES, P extends IFieldProps, O>
66
67
  props: P;
67
68
  on?: O;
68
69
  }
69
- export type IFormField = ITextField | ISearchField | INumberField | ITextareaField | IToggleField | ISelectField | ICheckboxField | ISelectMultipleField | IRadioField | IDateTimeField | IDateTimeRangeField | IUploadDropzoneAutoField | IWYSIWYGField | IFormFieldBase<INPUT_TYPES.COMPONENT, any, any>;
70
+ export type IFormField = ITextField | ISearchField | INumberField | ITextareaField | IToggleField | ISelectField | ICheckboxField | ISelectMultipleField | IRadioField | IDateTimeField | IDateTimeRangeField | IUploadDropzoneField | IUploadDropzoneAutoField | IWYSIWYGField | IFormFieldBase<INPUT_TYPES.COMPONENT, any, any>;
70
71
  export interface IFileValue {
71
72
  url: string;
72
73
  path?: string;
@@ -17,6 +17,7 @@
17
17
  :loading="options.status.isLoading"
18
18
  :data="options.rawData"
19
19
  :columns="options.columns"
20
+ :ui="ui"
20
21
  >
21
22
  <template #empty>
22
23
  <slot
@@ -0,0 +1 @@
1
+ export declare const getFileIcon: (file: File) => string;
@@ -0,0 +1,9 @@
1
+ import { isImage } from "../helpers/componentHelper.js";
2
+ import { useUiIconConfig } from "./useConfig.js";
3
+ export const getFileIcon = (file) => {
4
+ const icons = useUiIconConfig("uploadFileDropzone");
5
+ if (isImage(file)) {
6
+ return icons.placeholderImgIcon;
7
+ }
8
+ return icons.filePreviewIcon;
9
+ };
@@ -25,9 +25,10 @@ export declare const uploadFileDropzoneTheme: {
25
25
  onLoadingTextWrapper: string;
26
26
  onLoadingLoadingIconClass: string;
27
27
  onPreviewWrapper: string;
28
- onPreviewPreviewImgWrapper: string;
29
- onPreviewPreviewImgClass: string;
30
- onPreviewPreviewFileClass: string;
28
+ onPreviewImgWrapper: string;
29
+ onPreviewImgClass: string;
30
+ onPreviewFileWrapper: string;
31
+ onPreviewFileClass: string;
31
32
  onPreviewTextWrapper: string;
32
33
  onFailedWrapper: string;
33
34
  onFailedFailedImgWrapper: string;
@@ -27,9 +27,10 @@ export const uploadFileDropzoneTheme = {
27
27
  onLoadingLoadingIconClass: "size-10 text-primary animate-spin",
28
28
  // Preview state
29
29
  onPreviewWrapper: "flex items-center space-x-4 rounded-md w-full",
30
- onPreviewPreviewImgWrapper: "flex-shrink-0 w-16 h-16 rounded-md overflow-hidden bg-gray-100",
31
- onPreviewPreviewImgClass: "w-full h-full object-cover",
32
- onPreviewPreviewFileClass: "size-8 text-gray-400 m-auto mt-4",
30
+ onPreviewImgWrapper: "flex-shrink-0 w-16 h-16 flex justify-center items-center rounded-md overflow-hidden bg-gray-100",
31
+ onPreviewImgClass: "w-full h-full object-cover",
32
+ onPreviewFileWrapper: "flex-shrink-0 w-16 h-16 flex justify-center items-center rounded-md overflow-hidden",
33
+ onPreviewFileClass: "size-8 text-gray-400 m-auto",
33
34
  onPreviewTextWrapper: "flex-1 min-w-0 flex items-center justify-between",
34
35
  // Failed state
35
36
  onFailedWrapper: "flex items-start space-x-4 w-full rounded-md",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "2.21.1",
3
+ "version": "2.23.0",
4
4
  "repository": "https://gitlab.finema.co/finema/ui-kit",
5
5
  "license": "MIT",
6
6
  "author": "Finema Dev Core Team",