Skip to content

Commit 5dca6a1

Browse files
committed
Refactor modal options to replace _onShow and _onHide with _effect handling. Adjust Card props for consistency with prefixed variables. Update types and utilities for enhanced modal functionality.
1 parent 6aa0e1f commit 5dca6a1

8 files changed

Lines changed: 64 additions & 45 deletions

File tree

example/src/components/atoms/Card/Card.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ const Card = ({
3434
<CardRoot style={style}
3535
className={className}
3636
onClick={onClick}
37-
isGutter={isGutter}
37+
$isGutter={isGutter}
3838
>
39-
<CardBody direction={direction} fluid={fluid} className="gap-2">
39+
<CardBody $direction={direction} $fluid={fluid} className="gap-2">
4040
{title && <CardTitle>{title}</CardTitle>}
4141
{children}
4242
</CardBody>
@@ -50,17 +50,17 @@ export default Card;
5050

5151

5252
const CardBody = styled.div<{
53-
fluid?: boolean,
54-
direction?: 'row'|'column',
53+
$fluid?: boolean,
54+
$direction?: 'row'|'column',
5555
}>`
5656
height: 100%;
5757
display: flex;
5858
//overflow: hidden; // 影響正常項目跑版
59-
flex-direction: ${props => props.direction === 'column' ? 'column': 'row'};
60-
padding: ${props => props.fluid ? 0: '5px 10px'};
59+
flex-direction: ${props => props.$direction === 'column' ? 'column': 'row'};
60+
padding: ${props => props.$fluid ? 0: '5px 10px'};
6161
6262
${props => media.lg`
63-
padding: ${props.fluid ? 0: '10px 20px'};
63+
padding: ${props.$fluid ? 0: '10px 20px'};
6464
`}
6565
`;
6666

@@ -74,7 +74,7 @@ const CardTitle = styled.h3`
7474
`;
7575

7676
const CardRoot = styled.div<{
77-
isGutter: boolean,
77+
$isGutter: boolean,
7878
}>`
7979
8080
//margin-bottom: 15px;
@@ -92,7 +92,7 @@ const CardRoot = styled.div<{
9292
width: 100%;
9393
9494
95-
${props => props.isGutter && css`
95+
${props => props.$isGutter && css`
9696
border-color: transparent;
9797
background: transparent;
9898
${CardBody}{

example/src/components/examples/ZoomInCenter/ZoomInCenter.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ export default createModal(
2828
animation: animation.zoomInCenter,
2929
isHideWithMaskClick: true,
3030
// isFixedDisabled: false,
31-
_onShow: () => {
32-
console.log('onShow');
33-
},
34-
_onHide: () => {
35-
console.log('onHide');
31+
_effect: {
32+
onShow: () => {
33+
console.log('event onShow');
34+
},
35+
onHide: () => {
36+
console.log('event onHide');
37+
}
3638
}
3739
}
3840
);

example/src/components/primary/CreateStageModal/CreateStateModalPrimary.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@ export default createStateModal(
3535
CreateStateModalPrimary,
3636
{
3737
animation: animation.generateFadeInFromTop(),
38-
className: 'p-3'
38+
className: 'p-3',
39+
_effect: {
40+
onShow: () => {
41+
console.log('event onShow');
42+
},
43+
onHide: () => {
44+
console.log('event onHide');
45+
}
46+
}
3947
},
4048
);
4149

src/Modal.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ class Modal extends React.Component<IModalPortalProps, IState> {
5151
* (自動 QueueKey)
5252
* @param ModalComponent
5353
* @param args
54+
* @param onHide
5455
*/
55-
show: TShow = (ModalComponent, args) => {
56+
show: TShow = (ModalComponent, args, onHide) => {
5657
const queueKey = createQueueKey();
57-
this.showWithKey(ModalComponent, queueKey, args);
58+
59+
this.showWithKey(ModalComponent, queueKey, args, onHide);
5860
};
5961

6062
/**
@@ -63,17 +65,18 @@ class Modal extends React.Component<IModalPortalProps, IState> {
6365
* @param ModalComponent
6466
* @param queueKey
6567
* @param args
68+
* @param onHide
6669
*/
67-
showWithKey: TShowWithKey = (ModalComponent, queueKey, args) => {
70+
showWithKey: TShowWithKey = (ModalComponent, queueKey, args, onHide) => {
6871
this.setState(prev => {
69-
if(this.typeProps._onShow){
70-
this.typeProps._onShow(queueKey);
72+
if(this.typeProps.onShow){
73+
this.typeProps.onShow(queueKey);
7174
}
7275

7376
const activeIdx = prev.rows.findIndex(row => row.queueKey === queueKey);
7477
if(activeIdx === -1){
7578
return {
76-
rows: [...prev.rows, {queueKey, ModalComponent, args}],
79+
rows: [...prev.rows, {queueKey, ModalComponent, args, onHide}],
7780
};
7881
}
7982

@@ -94,13 +97,17 @@ class Modal extends React.Component<IModalPortalProps, IState> {
9497
hide: THidden = (queueKey) => {
9598
this.setState(prev => {
9699
const index = prev.rows.findIndex(row => row.queueKey === queueKey);
100+
101+
const {onHide} = prev.rows[index];
102+
if(onHide) onHide(queueKey);
103+
97104
return {
98105
rows: removeByIndex(prev.rows, index),
99106
};
100107
});
101108

102-
if(this.typeProps._onHide){
103-
this.typeProps._onHide(queueKey);
109+
if(this.typeProps.onHide){
110+
this.typeProps.onHide(queueKey);
104111
}
105112
};
106113

src/MotionDrawer/MotionDrawer.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const MotionDrawer = ({
4242
modalOptions,
4343
children,
4444
}: IProps, ref?: ForwardedRef<HTMLDivElement>) => {
45-
const {style, className, isMaskHidden, isHideWithMaskClick, isBodyScrollEnable, isFixedDisabled, animation, _onHide, _onShow} = modalOptions ?? {className: ''};
45+
const {style, className, isMaskHidden, isHideWithMaskClick, isBodyScrollEnable, isFixedDisabled, animation} = modalOptions ?? {className: ''};
4646
const id = useId();
4747
const isPresent = useIsPresent();
4848

@@ -67,14 +67,6 @@ const MotionDrawer = ({
6767
};
6868
}, []);
6969

70-
useEffect(() => {
71-
if(_onShow) _onShow(id);
72-
73-
return () => {
74-
if(_onHide) _onHide(id);
75-
};
76-
}, [_onShow, _onHide]);
77-
7870

7971
/**
8072
* 渲染主內容

src/compose/createModal.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import {modal} from '../Modal';
44
import MotionDrawer from '../MotionDrawer';
55
import {IModalOptions} from '../types';
6+
import {createQueueKey} from '../utils';
67

78

89

@@ -50,13 +51,15 @@ type TMotionModal<T> =
5051
* @param modalOptions
5152
*/
5253
function createModal<T = undefined>(ModalComponent: React.FC<T>, modalOptions?: IModalOptions): ICreateModal<T> {
54+
const {_effect, ...options} = modalOptions ?? {} as IModalOptions;
55+
5356
/**
5457
* Add framer motion
5558
* @param args
5659
*/
5760
const MotionModal: TMotionModal<T> = (args?: T) => {
5861
return (
59-
<MotionDrawer modalOptions={modalOptions}>
62+
<MotionDrawer modalOptions={options}>
6063
<ModalComponent {...args as T & {}} />
6164
</MotionDrawer>
6265
);
@@ -66,22 +69,26 @@ function createModal<T = undefined>(ModalComponent: React.FC<T>, modalOptions?:
6669
function show();
6770
function show(args: T): void;
6871
function show(args?: T): void {
72+
const queueKey = createQueueKey();
73+
6974
if (args) {
70-
modal.show(MotionModal, args);
75+
modal.showWithKey(MotionModal, queueKey, args, _effect?.onHide);
7176
} else {
72-
modal.show(MotionModal);
77+
modal.showWithKey(MotionModal, queueKey, undefined, _effect?.onHide);
7378
}
79+
if(_effect?.onShow) _effect.onShow(queueKey);
7480
}
7581

7682
// Overload signatures
7783
function showWithKey(queueKey: string);
7884
function showWithKey(queueKey: string, args: T): void;
7985
function showWithKey(queueKey: string, args?: T): void {
8086
if (args) {
81-
modal.showWithKey(MotionModal, queueKey, args);
87+
modal.showWithKey(MotionModal, queueKey, args, _effect?.onHide);
8288
} else {
83-
modal.showWithKey(MotionModal, queueKey);
89+
modal.showWithKey(MotionModal, queueKey, undefined, _effect?.onHide);
8490
}
91+
if(_effect?.onShow) _effect.onShow(queueKey);
8592
}
8693

8794
// Assign the overloaded function to MotionModal.show

src/compose/createStateModal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {ReactDidMountPortal} from '@acrool/react-portal';
22
import {AnimatePresence} from 'framer-motion';
3-
import React, {useCallback, useEffect, useRef, useState} from 'react';
3+
import React, {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react';
44

55
import {rootId} from '../config';
66
import {ModalProviderContext} from '../ModalProvider';
@@ -34,9 +34,9 @@ function createStateModal<T>(ModalComponent: React.FC<T>, modalOptions?: IStageM
3434

3535

3636
useEffect(() => {
37-
if(modalOptions?._onShow) modalOptions._onShow(queueKey);
37+
if(modalOptions?._effect?.onShow) modalOptions._effect.onShow(queueKey);
3838
return () => {
39-
if(modalOptions?._onHide) modalOptions._onHide(queueKey);
39+
if(modalOptions?._effect?.onHide) modalOptions._effect.onHide(queueKey);
4040
};
4141
}, []);
4242

src/types.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface IRow<T = any> {
77
queueKey: string
88
ModalComponent: React.FC<T>
99
args?: T
10+
onHide?: (queryKey: string) => void
1011
}
1112

1213
export interface IModal {
@@ -16,17 +17,18 @@ export interface IModal {
1617
hideAll: THiddenAll
1718
}
1819

20+
type TOnHide = (queryKey: string) => void
1921

2022

21-
export type TShow = <T>(children: React.FC<T>, args?: T) => void
22-
export type TShowWithKey = <T>(children: React.FC<T>, queueKey: string, args?: T) => void
23+
export type TShow = <T>(children: React.FC<T>, args?: T, onHide?: TOnHide) => void
24+
export type TShowWithKey = <T>(children: React.FC<T>, queueKey: string, args?: T, onHide?: TOnHide) => void
2325
export type THidden = (queueKey: string) => void;
2426
export type THiddenAll = (ignoreKeys?: string[]) => void;
2527

2628

2729
interface IControlVisibleStatus {
28-
_onShow?: (queueKey: string) => void
29-
_onHide?: (queueKey: string) => void
30+
onShow?: (queueKey: string) => void
31+
onHide?: (queueKey: string) => void
3032
}
3133

3234
export interface IModalPortalProps extends IControlVisibleStatus{
@@ -48,14 +50,15 @@ export type TAnimationConfig = {
4850
transition?: Transition,
4951
}
5052

51-
export interface IModalOptions extends IControlVisibleStatus{
53+
export interface IModalOptions{
5254
animation?: TAnimationConfig
5355
className?: string
5456
style?: CSS.Properties
5557
isMaskHidden?: boolean
5658
isHideWithMaskClick?: boolean
5759
isBodyScrollEnable?: boolean
5860
isFixedDisabled?: boolean
61+
_effect?: IControlVisibleStatus
5962
}
6063

6164
export interface IStageModalOptions extends IModalOptions{

0 commit comments

Comments
 (0)