diff --git a/components/upload/__tests__/upload-866.spec.ts b/components/upload/__tests__/upload-866.spec.ts new file mode 100644 index 000000000..a23fcb76d --- /dev/null +++ b/components/upload/__tests__/upload-866.spec.ts @@ -0,0 +1,48 @@ +import { describe, expect, it } from 'vitest'; +import { mount } from '@vue/test-utils'; +import FUpload from '../upload'; + +describe('FUpload drag prop #866', () => { + it('renders drag zone when drag prop is true', async () => { + const wrapper = mount(FUpload, { + props: { drag: true }, + slots: { default: () => 'Drop files here' }, + }); + await wrapper.vm.$nextTick(); + const draggerEl = wrapper.find('.fes-upload-dragger'); + expect(draggerEl.exists()).toBe(true); + }); + + it('renders normal trigger when drag prop is false', async () => { + const wrapper = mount(FUpload, { + props: { drag: false }, + slots: { default: () => 'Click to upload' }, + }); + await wrapper.vm.$nextTick(); + const draggerEl = wrapper.find('.fes-upload-dragger'); + expect(draggerEl.exists()).toBe(false); + }); + + it('drop event triggers file handling', async () => { + const wrapper = mount(FUpload, { + props: { drag: true }, + slots: { default: () => 'Drop here' }, + }); + await wrapper.vm.$nextTick(); + const file = new File(['test'], 'test.txt', { type: 'text/plain' }); + const dataTransfer = { files: [file] }; + const dropEvent = new DragEvent('drop', { bubbles: true, cancelable: true }); + Object.defineProperty(dropEvent, 'dataTransfer', { value: dataTransfer }); + const draggerEl = wrapper.find('.fes-upload-dragger'); + expect(draggerEl.exists()).toBe(true); + draggerEl.element.dispatchEvent(dropEvent); + }); + + it('drag zone has correct class structure', async () => { + const wrapper = mount(FUpload, { + props: { drag: true }, + }); + await wrapper.vm.$nextTick(); + expect(wrapper.find('.fes-upload-dragger').exists()).toBe(true); + }); +}); \ No newline at end of file diff --git a/components/upload/upload.tsx b/components/upload/upload.tsx index de1d61899..407b1bdf7 100644 --- a/components/upload/upload.tsx +++ b/components/upload/upload.tsx @@ -8,6 +8,7 @@ import { useTheme } from '../_theme/useTheme'; import type { ExtractPublicPropTypes } from '../_util/interface'; import Trigger from './trigger.vue'; import FileList from './fileList.vue'; +import UploadDragger from './uploadDragger'; import useUpload from './useUpload'; import type { FileItem } from './interface'; @@ -66,6 +67,10 @@ export const uploadProps = { type: Function, }, transformResponse: Function, + drag: { + type: Boolean, + default: false, + }, } as const satisfies ComponentObjectPropsOptions; export type UploadProps = ExtractPublicPropTypes; @@ -106,6 +111,19 @@ export default defineComponent({ }); return () => { + if (props.drag) { + return ( + <> + + {ctx.slots.default?.({ + uploadFiles: uploadFiles.value, + })} + + {ctx.slots.tip?.()} + {getFileList()} + + ); + } return ( <> {ctx.slots.default