` | `undefined` | 自定义文件缩略图 |
@@ -63,6 +63,12 @@ abstract
| type? | `string \| null` | MIME 类型 |
| url? | `string \| null` | 文件下载 URL |
+### UploadTrigger Props
+
+| 名称 | 类型 | 默认值 | 说明 |
+| -------- | --------- | ------- | ------------------- |
+| abstract | `boolean` | `false` | 是否不存在 DOM 包裹 |
+
### Upload Methods
| 名称 | 类型 | 说明 |
diff --git a/src/upload/src/Upload.tsx b/src/upload/src/Upload.tsx
index 47a42703a..b22059a1e 100644
--- a/src/upload/src/Upload.tsx
+++ b/src/upload/src/Upload.tsx
@@ -7,7 +7,6 @@ import {
ref,
PropType,
CSSProperties,
- renderSlot,
Fragment,
Teleport,
nextTick
@@ -18,7 +17,6 @@ import { useConfig, useTheme, useFormItem } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import {
ExtractPublicPropTypes,
- getFirstSlotVNode,
warn,
MaybeArray,
call,
@@ -501,7 +499,8 @@ export default defineComponent({
openFileDialog,
draggerInsideRef,
handleFileAddition,
- fileListStyle: props.fileListStyle,
+ mergedDisabledRef,
+ fileListStyleRef: toRef(props, 'fileListStyle'),
abstractRef: toRef(props, 'abstract'),
cssVarsRef
})
@@ -509,7 +508,6 @@ export default defineComponent({
mergedClsPrefix: mergedClsPrefixRef,
draggerInsideRef,
inputElRef,
- mergedDisabled: mergedDisabledRef,
mergedTheme: themeRef,
dragOver: dragOverRef,
handleFileInputChange,
@@ -519,53 +517,44 @@ export default defineComponent({
},
render () {
const { draggerInsideRef, mergedClsPrefix, $slots } = this
+
if ($slots.default && !this.abstract) {
- const firstChild = getFirstSlotVNode($slots, 'default')
- // @ts-expect-error
- if (firstChild?.type?.[uploadDraggerKey]) {
+ const firstChild = $slots.default()[0]
+ if ((firstChild as any)?.type?.[uploadDraggerKey]) {
draggerInsideRef.value = true
}
}
+ const inputNode = (
+
+ )
+
return this.abstract ? (
<>
- {renderSlot(this.$slots, 'default')}
-
-
-
+ {$slots.default?.()}
+ {inputNode}
>
) : (
-
+ {inputNode}
{this.listType !== 'image-card' && (
- {this.$slots}
+ {$slots}
)}
- {this.showFileList && {this.$slots}}
+ {this.showFileList && {$slots}}
)
}
diff --git a/src/upload/src/UploadDragger.tsx b/src/upload/src/UploadDragger.tsx
index 9e63fe865..c0a2da3bf 100644
--- a/src/upload/src/UploadDragger.tsx
+++ b/src/upload/src/UploadDragger.tsx
@@ -15,10 +15,21 @@ export default defineComponent({
'`n-upload-dragger` must be placed inside `n-upload`.'
)
}
- return () => (
-
- {slots}
-
- )
+ return () => {
+ const {
+ mergedClsPrefixRef: { value: mergedClsPrefix },
+ mergedDisabledRef: { value: mergedDisabled }
+ } = NUpload
+ return (
+
+ {slots}
+
+ )
+ }
}
})
diff --git a/src/upload/src/UploadFileList.tsx b/src/upload/src/UploadFileList.tsx
index d936b89ee..61638091e 100644
--- a/src/upload/src/UploadFileList.tsx
+++ b/src/upload/src/UploadFileList.tsx
@@ -21,14 +21,16 @@ export default defineComponent({
mergedClsPrefixRef,
listTypeRef,
mergedFileListRef,
- fileListStyle,
- cssVarsRef
+ fileListStyleRef,
+ cssVarsRef,
+ mergedDisabledRef
} = NUpload
+
const isImageCardTypeRef = computed(
() => listTypeRef.value === 'image-card'
)
- const createFileList = (): VNode[] =>
+ const renderFileList = (): VNode[] =>
mergedFileListRef.value.map((file) => (
))
- const createUploadFileList = (): VNode =>
+ const renderUploadFileList = (): VNode =>
isImageCardTypeRef.value ? (
- {{ default: createFileList }}
+ {{ default: renderFileList }}
) : (
{{
- default: createFileList
+ default: renderFileList
}}
)
- return () => (
-
- {createUploadFileList()}
- {isImageCardTypeRef.value && {slots}}
-
- )
+ return () => {
+ const { value: mergedClsPrefix } = mergedClsPrefixRef
+ return (
+
+ {renderUploadFileList()}
+ {isImageCardTypeRef.value && {slots}}
+
+ )
+ }
}
})
diff --git a/src/upload/src/UploadTrigger.tsx b/src/upload/src/UploadTrigger.tsx
index 164398c52..a3b370bab 100644
--- a/src/upload/src/UploadTrigger.tsx
+++ b/src/upload/src/UploadTrigger.tsx
@@ -1,11 +1,14 @@
-import { h, defineComponent, inject, renderSlot, computed } from 'vue'
+import { h, defineComponent, inject, computed } from 'vue'
import { throwError } from '../../_utils'
import { uploadInjectionKey } from './interface'
import NUploadDragger from './UploadDragger'
export default defineComponent({
name: 'UploadTrigger',
- setup (_, { slots }) {
+ props: {
+ abstract: Boolean
+ },
+ setup (props, { slots }) {
const NUpload = inject(uploadInjectionKey, null)
if (!NUpload) {
throwError(
@@ -16,13 +19,13 @@ export default defineComponent({
const {
mergedClsPrefixRef,
+ mergedDisabledRef,
listTypeRef,
disabledRef,
dragOverRef,
openFileDialog,
draggerInsideRef,
- handleFileAddition,
- abstractRef
+ handleFileAddition
} = NUpload
const isImageCardTypeRef = computed(
@@ -56,9 +59,10 @@ export default defineComponent({
dragOverRef.value = false
}
- return () =>
- abstractRef.value ? (
- renderSlot(slots, 'default', {
+ return () => {
+ const { value: mergedClsPrefix } = mergedClsPrefixRef
+ return props.abstract ? (
+ slots.default?.({
handleClick: handleTriggerClick,
handleDrop: handleTriggerDrop,
handleDragOver: handleTriggerDragOver,
@@ -68,9 +72,11 @@ export default defineComponent({
) : (
)
+ }
}
})
diff --git a/src/upload/src/interface.ts b/src/upload/src/interface.ts
index 4a564effa..b89d698f6 100644
--- a/src/upload/src/interface.ts
+++ b/src/upload/src/interface.ts
@@ -65,19 +65,20 @@ export interface UploadInjection {
onRemoveRef: Ref
onDownloadRef: Ref
XhrMap: Map
- submit: (fileId?: string) => void
doChange: DoChange
showPreivewButtonRef: Ref
onPreviewRef: Ref
- getFileThumbnailUrl: (file: FileInfo) => Promise
listTypeRef: Ref
dragOverRef: Ref
draggerInsideRef: { value: boolean }
- handleFileAddition: (files: FileList | null, e?: Event) => void
- fileListStyle: string | CSSProperties | undefined
- openFileDialog: () => void
+ fileListStyleRef: Ref
+ mergedDisabledRef: Ref
abstractRef: Ref
cssVarsRef: Ref
+ submit: (fileId?: string) => void
+ getFileThumbnailUrl: (file: FileInfo) => Promise
+ handleFileAddition: (files: FileList | null, e?: Event) => void
+ openFileDialog: () => void
}
export const uploadInjectionKey: InjectionKey =
diff --git a/src/upload/src/styles/index.cssr.ts b/src/upload/src/styles/index.cssr.ts
index 6a8de0044..586645193 100644
--- a/src/upload/src/styles/index.cssr.ts
+++ b/src/upload/src/styles/index.cssr.ts
@@ -4,69 +4,73 @@ import createIconSwitchTransition from '../../../_styles/transitions/icon-switch
export default c([
cB('upload', [
- cE('trigger', `
- display: inline-block;
- box-sizing: border-box;
- `, [
- cM('image-card', [
- cB('upload-dragger', `
- padding: 0;
- height: 100%;
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- `)
- ])
- ]),
cM('dragger-inside', [
cE('trigger', `
display: block;
`)
]),
- cB('upload-dragger', `
- cursor: pointer;
- box-sizing: border-box;
- width: 100%;
- text-align: center;
- border-radius: var(--border-radius);
- padding: 24px;
- transition:
- border-color .3s var(--bezier),
- background-color .3s var(--bezier);
- background-color: var(--dragger-color);
- border: var(--dragger-border);
- `, [
- c('&:hover', `
- border: var(--dragger-border-hover);
- `)
- ]),
- cM('disabled', `
- opacity: var(--item-disabled-opacity);
- `, [
- cE('trigger', `
- cursor: not-allowed;
- `),
- cB('upload-file', `
- cursor: not-allowed;
- `),
- cB('upload-file-list', `
- cursor: not-allowed;
- `),
- cB('upload-dragger', `
- cursor: not-allowed;
- `)
- ]),
cM('drag-over', [
cB('upload-dragger', `
border: var(--dragger-border-hover);
`)
])
]),
+ cB('upload-dragger', `
+ cursor: pointer;
+ box-sizing: border-box;
+ width: 100%;
+ text-align: center;
+ border-radius: var(--border-radius);
+ padding: 24px;
+ opacity: 1;
+ transition:
+ opacity: .3s var(--bezier),
+ border-color .3s var(--bezier),
+ background-color .3s var(--bezier);
+ background-color: var(--dragger-color);
+ border: var(--dragger-border);
+ `, [
+ c('&:hover', `
+ border: var(--dragger-border-hover);
+ `),
+ cM('disabled', `
+ opacity: var(--item-disabled-opacity);
+ cursor: not-allowed;
+ `)
+ ]),
+ cB('upload-trigger', `
+ display: inline-block;
+ box-sizing: border-box;
+ opacity: 1;
+ transition: opacity .3s var(--bezier);
+ `, [
+ cM('disabled', `
+ opacity: var(--item-disabled-opacity);
+ cursor: not-allowed;
+ `),
+ cM('image-card', [
+ cB('upload-dragger', `
+ padding: 0;
+ height: 100%;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ `)
+ ])
+ ]),
cB('upload-file-list', `
margin-top: 8px;
line-height: var(--line-height);
+ opacity: 1;
+ transition: opacity .3s var(--bezier);
`, [
+ cM('disabled', `
+ opacity: var(--item-disabled-opacity);
+ cursor: not-allowed;
+ `, [
+ cB('upload-file', 'cursor: not-allowed;')
+ ]),
cM('grid', `
display: grid;
grid-template-columns: repeat(auto-fill, 96px);
@@ -88,7 +92,7 @@ export default c([
})
]),
c('&:hover', `
- background-color: var(--item-color-hover);
+ background-color: var(--item-color-hover);
`, [
cB('upload-file-info', [
cE('action', `
@@ -307,7 +311,7 @@ export default c([
])
])
]),
- cB('upload__file-input', `
+ cB('upload-file-input', `
display: block;
width: 0;
height: 0;
diff --git a/src/upload/tests/Upload.spec.ts b/src/upload/tests/Upload.spec.ts
index 0333c1436..8e94bfd6a 100644
--- a/src/upload/tests/Upload.spec.ts
+++ b/src/upload/tests/Upload.spec.ts
@@ -31,10 +31,19 @@ describe('n-upload', () => {
it('should work with `disabled` prop', async () => {
const wrapper = mount(NUpload)
- expect(wrapper.find('.n-upload--disabled').exists()).not.toBe(true)
-
+ const disabledClasses = [
+ 'n-upload-trigger--disabled',
+ 'n-upload-file-list--disabled'
+ ]
+ for (const disabledClass of disabledClasses) {
+ expect(wrapper.find(disabledClass).exists()).not.toBe(true)
+ }
await wrapper.setProps({ disabled: true })
- expect(wrapper.find('.n-upload').classes()).toContain('n-upload--disabled')
+ for (const disabledClass of disabledClasses) {
+ expect(
+ wrapper.find('.' + disabledClass.split('--')[0]).classes()
+ ).toContain(disabledClass)
+ }
})
it('should work with `on-before-upload` prop', async () => {
@@ -347,7 +356,7 @@ describe('n-upload-trigger', () => {
default: () => h(NButton, null, { default: () => 'button1' })
}
})
- const triggerItem = wrapper.find('.n-upload__trigger')
+ const triggerItem = wrapper.find('.n-upload-trigger')
await triggerItem.trigger('click')
await triggerItem.trigger('drop')