Skip to content

Commit e07e107

Browse files
committed
refactor(ui): no longer use cloneElement to change action
Use `cloneElement` that mean must provide specified element, this does not apply to components like upload. BREAKING CHANGE: provide action components
1 parent 8eb70ca commit e07e107

File tree

23 files changed

+174
-67
lines changed

23 files changed

+174
-67
lines changed

packages/ui/src/components/card/Card.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { getClassName } from '@react-devui/utils';
55
import { registerComponentMate } from '../../utils';
66
import { useComponentConfig, usePrefixConfig } from '../root';
77
import { DSeparator } from '../separator';
8+
import { DCardAction } from './CardAction';
89
import { DCardContent } from './CardContent';
910
import { DCardHeader } from './CardHeader';
1011

@@ -17,6 +18,7 @@ export interface DCardProps extends React.HTMLAttributes<HTMLDivElement> {
1718
const { COMPONENT_NAME } = registerComponentMate({ COMPONENT_NAME: 'DCard' as const });
1819
export const DCard: {
1920
(props: DCardProps): JSX.Element | null;
21+
Action: typeof DCardAction;
2022
Header: typeof DCardHeader;
2123
Content: typeof DCardContent;
2224
} = (props) => {
@@ -45,11 +47,9 @@ export const DCard: {
4547
{children}
4648
{dActions && (
4749
<div className={`${dPrefix}card__actions`}>
48-
{React.Children.map(dActions as any[], (action, index) => (
50+
{React.Children.map(dActions, (action, index) => (
4951
<>
50-
{React.cloneElement(action, {
51-
className: getClassName(action.props.className, `${dPrefix}card__action`),
52-
})}
52+
{action}
5353
{index !== dActions.length - 1 && <DSeparator style={{ margin: 8 }} dVertical></DSeparator>}
5454
</>
5555
))}
@@ -59,5 +59,6 @@ export const DCard: {
5959
);
6060
};
6161

62+
DCard.Action = DCardAction;
6263
DCard.Header = DCardHeader;
6364
DCard.Content = DCardContent;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react';
2+
3+
import { getClassName } from '@react-devui/utils';
4+
5+
import { registerComponentMate } from '../../utils';
6+
import { useComponentConfig, usePrefixConfig } from '../root';
7+
8+
export type DCardActionProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
9+
10+
const { COMPONENT_NAME } = registerComponentMate({ COMPONENT_NAME: 'DCard.Action' as const });
11+
function CardAction(props: DCardActionProps, ref: React.ForwardedRef<HTMLButtonElement>): JSX.Element | null {
12+
const {
13+
children,
14+
15+
...restProps
16+
} = useComponentConfig(COMPONENT_NAME, props);
17+
18+
//#region Context
19+
const dPrefix = usePrefixConfig();
20+
//#endregion
21+
22+
return (
23+
<button
24+
{...restProps}
25+
ref={ref}
26+
className={getClassName(restProps.className, `${dPrefix}card__action`)}
27+
type={restProps['type'] ?? 'button'}
28+
>
29+
{children}
30+
</button>
31+
);
32+
}
33+
34+
export const DCardAction = React.forwardRef(CardAction);

packages/ui/src/components/card/demos/1.Basic.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ export default function Demo() {
2121
<DCard
2222
style={{ width: 300 }}
2323
dActions={[
24-
<button title="edit">
24+
<DCard.Action title="edit">
2525
<EditOutlined />
26-
</button>,
27-
<button title="delete">
26+
</DCard.Action>,
27+
<DCard.Action title="delete">
2828
<DeleteOutlined />
29-
</button>,
30-
<button title="more">
29+
</DCard.Action>,
30+
<DCard.Action title="more">
3131
<EllipsisOutlined />
32-
</button>,
32+
</DCard.Action>,
3333
]}
3434
>
3535
<DCard.Header dAction={<DButton dType="link">More</DButton>}>Card title</DCard.Header>

packages/ui/src/components/card/demos/2.Style.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,15 @@ export default function Demo() {
4949
dBorder={border}
5050
dShadow={shadow}
5151
dActions={[
52-
<button title="edit">
52+
<DCard.Action title="edit">
5353
<EditOutlined />
54-
</button>,
55-
<button title="delete">
54+
</DCard.Action>,
55+
<DCard.Action title="delete">
5656
<DeleteOutlined />
57-
</button>,
58-
<button title="more">
57+
</DCard.Action>,
58+
<DCard.Action title="more">
5959
<EllipsisOutlined />
60-
</button>,
60+
</DCard.Action>,
6161
]}
6262
>
6363
<DCard.Content>

packages/ui/src/components/card/demos/3.Media.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ export default function Demo() {
2121
<DCard
2222
style={{ width: 300 }}
2323
dActions={[
24-
<button title="edit">
24+
<DCard.Action title="edit">
2525
<EditOutlined />
26-
</button>,
27-
<button title="delete">
26+
</DCard.Action>,
27+
<DCard.Action title="delete">
2828
<DeleteOutlined />
29-
</button>,
30-
<button title="more">
29+
</DCard.Action>,
30+
<DCard.Action title="more">
3131
<EllipsisOutlined />
32-
</button>,
32+
</DCard.Action>,
3333
]}
3434
>
3535
<div style={{ margin: '-1px -1px 0 -1px' }}>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './Card';
2+
export * from './CardAction';
23
export * from './CardHeader';
34
export * from './CardContent';

packages/ui/src/components/image/Image.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import React, { useRef } from 'react';
33
import { useForceUpdate } from '@react-devui/hooks';
44
import { getClassName } from '@react-devui/utils';
55

6-
import { cloneHTMLElement, registerComponentMate } from '../../utils';
6+
import { registerComponentMate } from '../../utils';
77
import { useComponentConfig, usePrefixConfig } from '../root';
8+
import { DImageAction } from './ImageAction';
89
import { DImagePreview } from './ImagePreview';
910

1011
export interface DImageProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
@@ -17,6 +18,7 @@ export interface DImageProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
1718
const { COMPONENT_NAME } = registerComponentMate({ COMPONENT_NAME: 'DImage' as const });
1819
export const DImage: {
1920
(props: DImageProps): JSX.Element | null;
21+
Action: typeof DImageAction;
2022
Preview: typeof DImagePreview;
2123
} = (props) => {
2224
const {
@@ -83,17 +85,10 @@ export const DImage: {
8385
}}
8486
/>
8587
}
86-
{dActions && (
87-
<div className={`${dPrefix}image__actions`}>
88-
{React.Children.map(dActions, (action) =>
89-
cloneHTMLElement(action, {
90-
className: getClassName(action.props.className, `${dPrefix}image__action`),
91-
})
92-
)}
93-
</div>
94-
)}
88+
{dActions && <div className={`${dPrefix}image__actions`}>{React.Children.map(dActions, (action) => action)}</div>}
9589
</div>
9690
);
9791
};
9892

93+
DImage.Action = DImageAction;
9994
DImage.Preview = DImagePreview;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react';
2+
3+
import { getClassName } from '@react-devui/utils';
4+
5+
import { registerComponentMate } from '../../utils';
6+
import { useComponentConfig, usePrefixConfig } from '../root';
7+
8+
export type DImageActionProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
9+
10+
const { COMPONENT_NAME } = registerComponentMate({ COMPONENT_NAME: 'DImage.Action' as const });
11+
function ImageAction(props: DImageActionProps, ref: React.ForwardedRef<HTMLButtonElement>): JSX.Element | null {
12+
const {
13+
children,
14+
15+
...restProps
16+
} = useComponentConfig(COMPONENT_NAME, props);
17+
18+
//#region Context
19+
const dPrefix = usePrefixConfig();
20+
//#endregion
21+
22+
return (
23+
<button
24+
{...restProps}
25+
ref={ref}
26+
className={getClassName(restProps.className, `${dPrefix}image__action`)}
27+
type={restProps['type'] ?? 'button'}
28+
>
29+
{children}
30+
</button>
31+
);
32+
}
33+
34+
export const DImageAction = React.forwardRef(ImageAction);

packages/ui/src/components/image/demos/3.Actions.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ export default function Demo() {
2222
style={{ height: 100 }}
2323
dImgProps={{ src: '/assets/imgs/image-1.jpg', alt: 'demo' }}
2424
dActions={[
25-
<button title="edit">
25+
<DImage.Action title="edit">
2626
<EditOutlined />
27-
</button>,
28-
<button title="delete">
27+
</DImage.Action>,
28+
<DImage.Action title="delete">
2929
<DeleteOutlined />
30-
</button>,
31-
<button title="more">
30+
</DImage.Action>,
31+
<DImage.Action title="more">
3232
<EllipsisOutlined />
33-
</button>,
33+
</DImage.Action>,
3434
]}
3535
></DImage>
3636
);

packages/ui/src/components/image/demos/4.Preview.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ export default function Demo() {
3535
style={{ height: 100 }}
3636
dImgProps={props}
3737
dActions={[
38-
<button
38+
<DImage.Action
3939
className="button"
4040
onClick={() => {
4141
setVisible(true);
4242
}}
4343
>
4444
<EyeOutlined />
4545
{index !== 3 && <span>Preview</span>}
46-
</button>,
46+
</DImage.Action>,
4747
]}
4848
onClick={() => {
4949
setActive(index);

0 commit comments

Comments
 (0)