diff --git a/components/style.ts b/components/style.ts index 566d1da404..82c15a7f60 100644 --- a/components/style.ts +++ b/components/style.ts @@ -43,7 +43,7 @@ import './timeline/style'; import './input-number/style'; import './transfer/style'; import './tree/style'; -import './upload/style'; +// import './upload/style'; // import './layout/style'; // import './anchor/style'; // import './list/style'; diff --git a/components/theme/interface/components.ts b/components/theme/interface/components.ts index fd3707fbb8..659d7747bd 100644 --- a/components/theme/interface/components.ts +++ b/components/theme/interface/components.ts @@ -44,7 +44,7 @@ import type { ComponentToken as TagComponentToken } from '../../tag/style'; import type { ComponentToken as TooltipComponentToken } from '../../tooltip/style'; // import type { ComponentToken as TransferComponentToken } from '../../transfer/style'; import type { ComponentToken as TypographyComponentToken } from '../../typography/style'; -// import type { ComponentToken as UploadComponentToken } from '../../upload/style'; +import type { ComponentToken as UploadComponentToken } from '../../upload/style'; // import type { ComponentToken as TourComponentToken } from '../../tour/style'; // import type { ComponentToken as QRCodeComponentToken } from '../../qrcode/style'; // import type { ComponentToken as AppComponentToken } from '../../app/style'; @@ -107,7 +107,7 @@ export interface ComponentTokenMap { Menu?: MenuComponentToken; Modal?: ModalComponentToken; Message?: MessageComponentToken; - // Upload?: UploadComponentToken; + Upload?: UploadComponentToken; Tooltip?: TooltipComponentToken; // Table?: TableComponentToken; Space?: SpaceComponentToken; diff --git a/components/upload/Upload.tsx b/components/upload/Upload.tsx index f1fe7bad3d..c4aa8848a5 100644 --- a/components/upload/Upload.tsx +++ b/components/upload/Upload.tsx @@ -23,6 +23,9 @@ import type { VueNode } from '../_util/type'; import classNames from '../_util/classNames'; import { useInjectFormItemContext } from '../form'; +// CSSINJS +import useStyle from './style'; + export const LIST_IGNORE = `__LIST_IGNORE_${Date.now()}__`; export default defineComponent({ @@ -292,6 +295,10 @@ export default defineComponent({ }); const { prefixCls, direction } = useConfigInject('upload', props); + + // style + const [wrapSSR, hashId] = useStyle(prefixCls); + const [locale] = useLocaleReceiver( 'Upload', defaultLocale.Upload, @@ -366,6 +373,11 @@ export default defineComponent({ if (!slots.default || disabled) { delete rcUploadProps.id; } + + const rtlCls = { + [`${prefixCls}-rtl`]: direction.value === 'rtl', + }; + if (type === 'drag') { const dragCls = classNames( prefixCls.value, @@ -379,9 +391,14 @@ export default defineComponent({ [`${prefixCls.value}-rtl`]: direction.value === 'rtl', }, attrs.class, + hashId.value, ); - return ( - + + return wrapSSR( +
{renderUploadList()} -
+
, ); } @@ -417,17 +434,29 @@ export default defineComponent({ ); if (listType === 'picture-card') { - return ( - + return wrapSSR( + {renderUploadList(renderUploadButton, !!(children && children.length))} - + , ); } - return ( - + return wrapSSR( + {renderUploadButton(children && children.length ? undefined : { display: 'none' })} {renderUploadList()} - + , ); }; }, diff --git a/components/upload/UploadList/ListItem.tsx b/components/upload/UploadList/ListItem.tsx index eaf294e81c..e12ef14eb9 100644 --- a/components/upload/UploadList/ListItem.tsx +++ b/components/upload/UploadList/ListItem.tsx @@ -1,5 +1,5 @@ import { computed, defineComponent, onBeforeUnmount, onMounted, ref } from 'vue'; -import type { ExtractPropTypes, PropType, CSSProperties } from 'vue'; +import type { ExtractPropTypes, CSSProperties } from 'vue'; import EyeOutlined from '@ant-design/icons-vue/EyeOutlined'; import DeleteOutlined from '@ant-design/icons-vue/DeleteOutlined'; import DownloadOutlined from '@ant-design/icons-vue/DownloadOutlined'; @@ -16,36 +16,39 @@ import type { import type { VueNode } from '../../_util/type'; import useConfigInject from '../../config-provider/hooks/useConfigInject'; import Transition, { getTransitionProps } from '../../_util/transition'; +import { booleanType, stringType, functionType, arrayType, objectType } from '../../_util/type'; + export const listItemProps = () => { return { prefixCls: String, - locale: { type: Object as PropType, default: undefined as UploadLocale }, - file: Object as PropType, - items: Array as PropType, - listType: String as PropType, - isImgUrl: Function as PropType<(file: UploadFile) => boolean>, + locale: objectType(undefined as UploadLocale), + file: objectType(), + items: arrayType(), + listType: stringType(), + isImgUrl: functionType<(file: UploadFile) => boolean>(), - showRemoveIcon: { type: Boolean, default: undefined }, - showDownloadIcon: { type: Boolean, default: undefined }, - showPreviewIcon: { type: Boolean, default: undefined }, - removeIcon: Function as PropType<(opt: { file: UploadFile }) => VueNode>, - downloadIcon: Function as PropType<(opt: { file: UploadFile }) => VueNode>, - previewIcon: Function as PropType<(opt: { file: UploadFile }) => VueNode>, + showRemoveIcon: booleanType(), + showDownloadIcon: booleanType(), + showPreviewIcon: booleanType(), + removeIcon: functionType<(opt: { file: UploadFile }) => VueNode>(), + downloadIcon: functionType<(opt: { file: UploadFile }) => VueNode>(), + previewIcon: functionType<(opt: { file: UploadFile }) => VueNode>(), - iconRender: Function as PropType<(opt: { file: UploadFile }) => VueNode>, - actionIconRender: Function as PropType< - (opt: { - customIcon: VueNode; - callback: () => void; - prefixCls: string; - title?: string | undefined; - }) => VueNode - >, - itemRender: Function as PropType, - onPreview: Function as PropType<(file: UploadFile, e: Event) => void>, - onClose: Function as PropType<(file: UploadFile) => void>, - onDownload: Function as PropType<(file: UploadFile) => void>, - progress: Object as PropType, + iconRender: functionType<(opt: { file: UploadFile }) => VueNode>(), + actionIconRender: + functionType< + (opt: { + customIcon: VueNode; + callback: () => void; + prefixCls: string; + title?: string | undefined; + }) => VueNode + >(), + itemRender: functionType(), + onPreview: functionType<(file: UploadFile, e: Event) => void>(), + onClose: functionType<(file: UploadFile) => void>(), + onDownload: functionType<(file: UploadFile) => void>(), + progress: objectType(), }; }; @@ -93,7 +96,6 @@ export default defineComponent({ const { class: className, style } = attrs; // This is used for legacy span make scrollHeight the wrong value. // We will force these to be `display: block` with non `picture-card` - const spanClassName = `${prefixCls}-span`; const iconNode = iconRender({ file }); let icon =
{iconNode}
; @@ -162,7 +164,7 @@ export default defineComponent({ - {icon} - {preview} - - ); const dom = (
-
{iconAndPreview}
+ {icon} + {preview} {actions} {showProgress.value && (
{'percent' in file ? ( - + ) : null}
@@ -254,7 +255,7 @@ export default defineComponent({
); const listContainerNameClass = { - [`${prefixCls}-list-${listType}-container`]: true, + [`${prefixCls}-list-item-container`]: true, [`${className}`]: !!className, }; const item = diff --git a/components/upload/UploadList/index.tsx b/components/upload/UploadList/index.tsx index 7d4e450f15..0051015f73 100644 --- a/components/upload/UploadList/index.tsx +++ b/components/upload/UploadList/index.tsx @@ -121,7 +121,7 @@ export default defineComponent({ onClick: () => { callback(); }, - class: `${prefixCls}-list-item-card-actions-btn`, + class: `${prefixCls}-list-item-action`, }; if (isValidElement(customIcon)) { return