mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-12 15:19:58 +08:00
commit
b4bbe51ed7
@ -7,7 +7,7 @@ import { convertLegacyProps } from '../button/button';
|
|||||||
export interface ActionButtonProps {
|
export interface ActionButtonProps {
|
||||||
type?: LegacyButtonType;
|
type?: LegacyButtonType;
|
||||||
actionFn?: (...args: any[]) => any | PromiseLike<any>;
|
actionFn?: (...args: any[]) => any | PromiseLike<any>;
|
||||||
close: Function;
|
close?: Function;
|
||||||
autoFocus?: boolean;
|
autoFocus?: boolean;
|
||||||
prefixCls: string;
|
prefixCls: string;
|
||||||
buttonProps?: ButtonProps;
|
buttonProps?: ButtonProps;
|
||||||
@ -24,6 +24,10 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
|||||||
const clickedRef = React.useRef<boolean>(false);
|
const clickedRef = React.useRef<boolean>(false);
|
||||||
const ref = React.useRef<any>();
|
const ref = React.useRef<any>();
|
||||||
const [loading, setLoading] = useState<ButtonProps['loading']>(false);
|
const [loading, setLoading] = useState<ButtonProps['loading']>(false);
|
||||||
|
const { close } = props;
|
||||||
|
const onInternalClose = (...args: any[]) => {
|
||||||
|
close?.(...args);
|
||||||
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
let timeoutId: any;
|
let timeoutId: any;
|
||||||
@ -39,7 +43,6 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handlePromiseOnOk = (returnValueOfOnOk?: PromiseLike<any>) => {
|
const handlePromiseOnOk = (returnValueOfOnOk?: PromiseLike<any>) => {
|
||||||
const { close } = props;
|
|
||||||
if (!isThenable(returnValueOfOnOk)) {
|
if (!isThenable(returnValueOfOnOk)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -47,7 +50,7 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
|||||||
returnValueOfOnOk!.then(
|
returnValueOfOnOk!.then(
|
||||||
(...args: any[]) => {
|
(...args: any[]) => {
|
||||||
setLoading(false, true);
|
setLoading(false, true);
|
||||||
close(...args);
|
onInternalClose(...args);
|
||||||
clickedRef.current = false;
|
clickedRef.current = false;
|
||||||
},
|
},
|
||||||
(e: Error) => {
|
(e: Error) => {
|
||||||
@ -62,13 +65,13 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
const { actionFn, close } = props;
|
const { actionFn } = props;
|
||||||
if (clickedRef.current) {
|
if (clickedRef.current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clickedRef.current = true;
|
clickedRef.current = true;
|
||||||
if (!actionFn) {
|
if (!actionFn) {
|
||||||
close();
|
onInternalClose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let returnValueOfOnOk;
|
let returnValueOfOnOk;
|
||||||
@ -76,7 +79,7 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
|||||||
returnValueOfOnOk = actionFn(e);
|
returnValueOfOnOk = actionFn(e);
|
||||||
if (props.quitOnNullishReturnValue && !isThenable(returnValueOfOnOk)) {
|
if (props.quitOnNullishReturnValue && !isThenable(returnValueOfOnOk)) {
|
||||||
clickedRef.current = false;
|
clickedRef.current = false;
|
||||||
close(e);
|
onInternalClose(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (actionFn.length) {
|
} else if (actionFn.length) {
|
||||||
@ -86,7 +89,7 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
|||||||
} else {
|
} else {
|
||||||
returnValueOfOnOk = actionFn();
|
returnValueOfOnOk = actionFn();
|
||||||
if (!returnValueOfOnOk) {
|
if (!returnValueOfOnOk) {
|
||||||
close();
|
onInternalClose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import type { TransferLocale as TransferLocaleForEmpty } from '../empty';
|
|||||||
import type { ModalLocale } from '../modal/locale';
|
import type { ModalLocale } from '../modal/locale';
|
||||||
import { changeConfirmLocale } from '../modal/locale';
|
import { changeConfirmLocale } from '../modal/locale';
|
||||||
import type { PaginationLocale } from '../pagination/Pagination';
|
import type { PaginationLocale } from '../pagination/Pagination';
|
||||||
import type { PopconfirmLocale } from '../popconfirm';
|
import type { PopconfirmLocale } from '../popconfirm/PurePanel';
|
||||||
import type { TableLocale } from '../table/interface';
|
import type { TableLocale } from '../table/interface';
|
||||||
import type { TransferLocale } from '../transfer';
|
import type { TransferLocale } from '../transfer';
|
||||||
import type { UploadLocale } from '../upload/interface';
|
import type { UploadLocale } from '../upload/interface';
|
||||||
|
81
components/popconfirm/PurePanel.tsx
Normal file
81
components/popconfirm/PurePanel.tsx
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import type { PopconfirmProps } from '.';
|
||||||
|
import Button from '../button';
|
||||||
|
import { convertLegacyProps } from '../button/button';
|
||||||
|
import ActionButton from '../_util/ActionButton';
|
||||||
|
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||||
|
import defaultLocale from '../locale/default';
|
||||||
|
import { getRenderPropValue } from '../_util/getRenderPropValue';
|
||||||
|
import { ConfigContext } from '../config-provider';
|
||||||
|
|
||||||
|
export interface PopconfirmLocale {
|
||||||
|
okText: string;
|
||||||
|
cancelText: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OverlayProps
|
||||||
|
extends Pick<
|
||||||
|
PopconfirmProps,
|
||||||
|
| 'icon'
|
||||||
|
| 'okButtonProps'
|
||||||
|
| 'cancelButtonProps'
|
||||||
|
| 'cancelText'
|
||||||
|
| 'okText'
|
||||||
|
| 'okType'
|
||||||
|
| 'showCancel'
|
||||||
|
| 'title'
|
||||||
|
> {
|
||||||
|
prefixCls: string;
|
||||||
|
close?: Function;
|
||||||
|
onConfirm?: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
|
onCancel?: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Overlay(props: OverlayProps) {
|
||||||
|
const {
|
||||||
|
prefixCls,
|
||||||
|
okButtonProps,
|
||||||
|
cancelButtonProps,
|
||||||
|
title,
|
||||||
|
cancelText,
|
||||||
|
okText,
|
||||||
|
okType,
|
||||||
|
icon,
|
||||||
|
showCancel = true,
|
||||||
|
close,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LocaleReceiver componentName="Popconfirm" defaultLocale={defaultLocale.Popconfirm}>
|
||||||
|
{(popconfirmLocale: PopconfirmLocale) => (
|
||||||
|
<div className={`${prefixCls}-inner-content`}>
|
||||||
|
<div className={`${prefixCls}-message`}>
|
||||||
|
{icon}
|
||||||
|
<div className={`${prefixCls}-message-title`}>{getRenderPropValue(title)}</div>
|
||||||
|
</div>
|
||||||
|
<div className={`${prefixCls}-buttons`}>
|
||||||
|
{showCancel && (
|
||||||
|
<Button onClick={onCancel} size="small" {...cancelButtonProps}>
|
||||||
|
{cancelText || popconfirmLocale.cancelText}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<ActionButton
|
||||||
|
buttonProps={{ size: 'small', ...convertLegacyProps(okType), ...okButtonProps }}
|
||||||
|
actionFn={onConfirm}
|
||||||
|
close={close}
|
||||||
|
prefixCls={getPrefixCls('btn')}
|
||||||
|
quitOnNullishReturnValue
|
||||||
|
emitEvent
|
||||||
|
>
|
||||||
|
{okText || popconfirmLocale.okText}
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</LocaleReceiver>
|
||||||
|
);
|
||||||
|
}
|
@ -3,19 +3,15 @@ import classNames from 'classnames';
|
|||||||
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
||||||
import KeyCode from 'rc-util/lib/KeyCode';
|
import KeyCode from 'rc-util/lib/KeyCode';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import Button from '../button';
|
|
||||||
import type { ButtonProps, LegacyButtonType } from '../button/button';
|
import type { ButtonProps, LegacyButtonType } from '../button/button';
|
||||||
import { convertLegacyProps } from '../button/button';
|
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
|
||||||
import defaultLocale from '../locale/default';
|
|
||||||
import Popover from '../popover';
|
import Popover from '../popover';
|
||||||
import genPurePanel from '../_util/PurePanel';
|
import genPurePanel from '../_util/PurePanel';
|
||||||
import type { AbstractTooltipProps } from '../tooltip';
|
import type { AbstractTooltipProps } from '../tooltip';
|
||||||
import ActionButton from '../_util/ActionButton';
|
|
||||||
import type { RenderFunction } from '../_util/getRenderPropValue';
|
import type { RenderFunction } from '../_util/getRenderPropValue';
|
||||||
import { getRenderPropValue } from '../_util/getRenderPropValue';
|
|
||||||
import { cloneElement } from '../_util/reactNode';
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
import { Overlay } from './PurePanel';
|
||||||
|
|
||||||
import usePopconfirmStyle from './style';
|
import usePopconfirmStyle from './style';
|
||||||
|
|
||||||
export interface PopconfirmProps extends AbstractTooltipProps {
|
export interface PopconfirmProps extends AbstractTooltipProps {
|
||||||
@ -40,11 +36,6 @@ export interface PopconfirmState {
|
|||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PopconfirmLocale {
|
|
||||||
okText: string;
|
|
||||||
cancelText: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
||||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
const [visible, setVisible] = useMergedState(false, {
|
const [visible, setVisible] = useMergedState(false, {
|
||||||
@ -87,44 +78,6 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
|||||||
settingVisible(value);
|
settingVisible(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderOverlay = (prefixCls: string, popconfirmLocale: PopconfirmLocale) => {
|
|
||||||
const {
|
|
||||||
okButtonProps,
|
|
||||||
cancelButtonProps,
|
|
||||||
title,
|
|
||||||
cancelText,
|
|
||||||
okText,
|
|
||||||
okType,
|
|
||||||
icon,
|
|
||||||
showCancel = true,
|
|
||||||
} = props;
|
|
||||||
return (
|
|
||||||
<div className={`${prefixCls}-inner-content`}>
|
|
||||||
<div className={`${prefixCls}-message`}>
|
|
||||||
{icon}
|
|
||||||
<div className={`${prefixCls}-message-title`}>{getRenderPropValue(title)}</div>
|
|
||||||
</div>
|
|
||||||
<div className={`${prefixCls}-buttons`}>
|
|
||||||
{showCancel && (
|
|
||||||
<Button onClick={onCancel} size="small" {...cancelButtonProps}>
|
|
||||||
{cancelText || popconfirmLocale.cancelText}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<ActionButton
|
|
||||||
buttonProps={{ size: 'small', ...convertLegacyProps(okType), ...okButtonProps }}
|
|
||||||
actionFn={onConfirm}
|
|
||||||
close={close}
|
|
||||||
prefixCls={getPrefixCls('btn')}
|
|
||||||
quitOnNullishReturnValue
|
|
||||||
emitEvent
|
|
||||||
>
|
|
||||||
{okText || popconfirmLocale.okText}
|
|
||||||
</ActionButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
placement,
|
placement,
|
||||||
@ -137,19 +90,21 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
|||||||
|
|
||||||
const [wrapSSR] = usePopconfirmStyle(prefixCls);
|
const [wrapSSR] = usePopconfirmStyle(prefixCls);
|
||||||
|
|
||||||
const overlay = (
|
|
||||||
<LocaleReceiver componentName="Popconfirm" defaultLocale={defaultLocale.Popconfirm}>
|
|
||||||
{(popconfirmLocale: PopconfirmLocale) => renderOverlay(prefixCls, popconfirmLocale)}
|
|
||||||
</LocaleReceiver>
|
|
||||||
);
|
|
||||||
|
|
||||||
return wrapSSR(
|
return wrapSSR(
|
||||||
<Popover
|
<Popover
|
||||||
{...restProps}
|
{...restProps}
|
||||||
placement={placement}
|
placement={placement}
|
||||||
onVisibleChange={onVisibleChange}
|
onVisibleChange={onVisibleChange}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
_overlay={overlay}
|
_overlay={
|
||||||
|
<Overlay
|
||||||
|
{...props}
|
||||||
|
prefixCls={prefixCls}
|
||||||
|
close={close}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
onCancel={onCancel}
|
||||||
|
/>
|
||||||
|
}
|
||||||
overlayClassName={overlayClassNames}
|
overlayClassName={overlayClassNames}
|
||||||
ref={ref as any}
|
ref={ref as any}
|
||||||
data-popover-inject
|
data-popover-inject
|
||||||
|
@ -59,7 +59,7 @@ Select component to select value from options.
|
|||||||
| removeIcon | The custom remove icon | ReactNode | - | |
|
| removeIcon | The custom remove icon | ReactNode | - | |
|
||||||
| searchValue | The current input "search" text | string | - | |
|
| searchValue | The current input "search" text | string | - | |
|
||||||
| showArrow | Whether to show the drop-down arrow | boolean | true(for single select), false(for multiple select) | |
|
| showArrow | Whether to show the drop-down arrow | boolean | true(for single select), false(for multiple select) | |
|
||||||
| showSearch | Whether show search input in single mode | boolean | false | |
|
| showSearch | Whether select is searchable | boolean | single: false, multple: true | |
|
||||||
| size | Size of Select input | `large` \| `middle` \| `small` | `middle` | |
|
| size | Size of Select input | `large` \| `middle` \| `small` | `middle` | |
|
||||||
| status | Set validation status | 'error' \| 'warning' | - | 4.19.0 |
|
| status | Set validation status | 'error' \| 'warning' | - | 4.19.0 |
|
||||||
| suffixIcon | The custom suffix icon | ReactNode | - | |
|
| suffixIcon | The custom suffix icon | ReactNode | - | |
|
||||||
@ -107,7 +107,7 @@ Select component to select value from options.
|
|||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
### Why sometime search will show 2 same option when in `tag` mode?
|
### Why sometime search will show 2 same option when in `tags` mode?
|
||||||
|
|
||||||
It's caused by option with different `label` and `value`. You can use `optionFilterProp="label"` to change filter logic instead.
|
It's caused by option with different `label` and `value`. You can use `optionFilterProp="label"` to change filter logic instead.
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
|
|||||||
| removeIcon | 自定义的多选框清除图标 | ReactNode | - | |
|
| removeIcon | 自定义的多选框清除图标 | ReactNode | - | |
|
||||||
| searchValue | 控制搜索文本 | string | - | |
|
| searchValue | 控制搜索文本 | string | - | |
|
||||||
| showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | |
|
| showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | |
|
||||||
| showSearch | 使单选模式可搜索 | boolean | false | |
|
| showSearch | 配置是否可搜索 | boolean | 单选为 false,多选为 true | |
|
||||||
| size | 选择框大小 | `large` \| `middle` \| `small` | `middle` | |
|
| size | 选择框大小 | `large` \| `middle` \| `small` | `middle` | |
|
||||||
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
|
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
|
||||||
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
|
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
|
||||||
@ -108,7 +108,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
|
|||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
### `tag` 模式下为何搜索有时会出现两个相同选项?
|
### `mode="tags"` 模式下为何搜索有时会出现两个相同选项?
|
||||||
|
|
||||||
这一般是 `options` 中的 `label` 和 `value` 不同导致的,你可以通过 `optionFilterProp="label"` 将过滤设置为展示值以避免这种情况。
|
这一般是 `options` 中的 `label` 和 `value` 不同导致的,你可以通过 `optionFilterProp="label"` 将过滤设置为展示值以避免这种情况。
|
||||||
|
|
||||||
|
@ -724,7 +724,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last"
|
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last ant-table-cell-fix-left-all"
|
||||||
style="position: sticky; left: 0px;"
|
style="position: sticky; left: 0px;"
|
||||||
>
|
>
|
||||||
Name
|
Name
|
||||||
@ -784,7 +784,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
|
|||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last"
|
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last ant-table-cell-fix-left-all"
|
||||||
style="position: sticky; left: 0px;"
|
style="position: sticky; left: 0px;"
|
||||||
>
|
>
|
||||||
Jack
|
Jack
|
||||||
@ -816,7 +816,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
|
|||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last"
|
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last ant-table-cell-fix-left-all"
|
||||||
style="position: sticky; left: 0px;"
|
style="position: sticky; left: 0px;"
|
||||||
>
|
>
|
||||||
Lucy
|
Lucy
|
||||||
@ -848,7 +848,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
|
|||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last"
|
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last ant-table-cell-fix-left-all"
|
||||||
style="position: sticky; left: 0px;"
|
style="position: sticky; left: 0px;"
|
||||||
>
|
>
|
||||||
Tom
|
Tom
|
||||||
@ -880,7 +880,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
|
|||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last"
|
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last ant-table-cell-fix-left-all"
|
||||||
style="position: sticky; left: 0px;"
|
style="position: sticky; left: 0px;"
|
||||||
>
|
>
|
||||||
Jerry
|
Jerry
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
// import '../../style/index.less';
|
|
||||||
// import './index.less';
|
|
||||||
|
|
||||||
// deps-lint-skip-all
|
// deps-lint-skip-all
|
||||||
import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
|
import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
|
||||||
import { Keyframes } from '@ant-design/cssinjs';
|
import { Keyframes } from '@ant-design/cssinjs';
|
||||||
@ -163,6 +160,21 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
|
|||||||
color: 'inherit',
|
color: 'inherit',
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'&-draggable': {
|
||||||
|
[`${treeCls}-draggable-icon`]: {
|
||||||
|
width: treeTitleHeight,
|
||||||
|
lineHeight: `${treeTitleHeight}px`,
|
||||||
|
textAlign: 'center',
|
||||||
|
visibility: 'visible',
|
||||||
|
opacity: 0.2,
|
||||||
|
transition: `opacity ${token.motionDurationSlow}`,
|
||||||
|
|
||||||
|
[`${treeNodeCls}:hover &`]: {
|
||||||
|
opacity: 0.45,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// >>> Indent
|
// >>> Indent
|
||||||
@ -178,15 +190,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
|
|||||||
|
|
||||||
// >>> Drag Handler
|
// >>> Drag Handler
|
||||||
[`${treeCls}-draggable-icon`]: {
|
[`${treeCls}-draggable-icon`]: {
|
||||||
width: treeTitleHeight,
|
visibility: 'hidden',
|
||||||
lineHeight: `${treeTitleHeight}px`,
|
|
||||||
textAlign: 'center',
|
|
||||||
opacity: 0.2,
|
|
||||||
transition: `opacity ${token.motionDurationSlow}`,
|
|
||||||
|
|
||||||
[`${treeNodeCls}:hover &`]: {
|
|
||||||
opacity: 0.45,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// >>> Switcher
|
// >>> Switcher
|
||||||
|
@ -928,6 +928,35 @@ describe('Upload List', () => {
|
|||||||
unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('upload svg file with <foreignObject> should not have CORS error', async () => {
|
||||||
|
const mockFile = new File(
|
||||||
|
[
|
||||||
|
'<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><foreignObject x="20" y="20" width="160" height="160"><div xmlns="http://www.w3.org/1999/xhtml">Test</div></foreignObject></svg>',
|
||||||
|
],
|
||||||
|
'bar.svg',
|
||||||
|
{ type: 'image/svg+xml' },
|
||||||
|
);
|
||||||
|
|
||||||
|
const previewFunc = jest.fn(previewImage);
|
||||||
|
|
||||||
|
const { unmount } = render(
|
||||||
|
<Upload
|
||||||
|
fileList={[{ originFileObj: mockFile }]}
|
||||||
|
previewFile={previewFunc}
|
||||||
|
locale={{ uploading: 'uploading' }}
|
||||||
|
listType="picture-card"
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(previewFunc).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
await previewFunc(mockFile).then(dataUrl => {
|
||||||
|
expect(dataUrl).toEqual('data:image/png;base64,');
|
||||||
|
});
|
||||||
|
unmount();
|
||||||
|
});
|
||||||
|
|
||||||
it("upload non image file shouldn't be converted to the base64", async () => {
|
it("upload non image file shouldn't be converted to the base64", async () => {
|
||||||
const mockFile = new File([''], 'foo.7z', {
|
const mockFile = new File([''], 'foo.7z', {
|
||||||
type: 'application/x-7z-compressed',
|
type: 'application/x-7z-compressed',
|
||||||
|
@ -110,6 +110,15 @@ export function previewImage(file: File | Blob): Promise<string> {
|
|||||||
|
|
||||||
resolve(dataURL);
|
resolve(dataURL);
|
||||||
};
|
};
|
||||||
img.src = window.URL.createObjectURL(file);
|
img.crossOrigin = 'anonymous';
|
||||||
|
if (file.type.startsWith('image/svg+xml')) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.addEventListener('load', () => {
|
||||||
|
if (reader.result) img.src = reader.result as string;
|
||||||
|
});
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
} else {
|
||||||
|
img.src = window.URL.createObjectURL(file);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user