1- import React , { Component , HTMLAttributes , CSSProperties } from 'react' ;
1+ import React , {
2+ HTMLAttributes ,
3+ CSSProperties ,
4+ FC ,
5+ createContext ,
6+ useContext ,
7+ useCallback ,
8+ useMemo ,
9+ } from 'react' ;
210import classnames from 'classnames' ;
311import { Button } from './Button' ;
412
13+ /**
14+ *
15+ */
16+ const ModalHandlersContext = createContext < {
17+ onHide ?: ( ) => void ;
18+ } > ( { } ) ;
19+
20+ /**
21+ *
22+ */
523export type ModalHeaderProps = {
624 className ?: string ;
725 title ?: string ;
@@ -10,48 +28,54 @@ export type ModalHeaderProps = {
1028 onClose ?: ( ) => void ;
1129} ;
1230
13- export class ModalHeader extends Component < ModalHeaderProps > {
14- constructor ( props : Readonly < ModalHeaderProps > ) {
15- super ( props ) ;
16-
17- this . onClose = this . onClose . bind ( this ) ;
18- }
19-
20- onClose ( ) {
21- if ( this . props . onClose ) {
22- this . props . onClose ( ) ;
23- }
24- }
25-
26- render ( ) {
27- const { className , title , tagline , closeButton , ... props } = this . props ;
28- delete props . onClose ;
29- const hdClassNames = classnames ( className , 'slds-modal__header' ) ;
30- return (
31- < div className = { hdClassNames } { ... props } >
32- < h2 className = 'slds-text-heading_medium' > { title } </ h2 >
33- { tagline ? < p className = 'slds-m-top_x-small ' > { tagline } </ p > : null }
34- { closeButton ? (
35- < Button
36- type = 'icon-inverse'
37- className = 'slds-modal__close '
38- icon = 'close '
39- iconSize = 'large '
40- alt = 'Close '
41- inverse
42- onClick = { this . onClose }
43- />
44- ) : null }
45- </ div >
46- ) ;
47- }
48- }
31+ /**
32+ *
33+ */
34+ export const ModalHeader : FC < ModalHeaderProps > = ( props_ ) => {
35+ const {
36+ className ,
37+ title ,
38+ tagline ,
39+ closeButton ,
40+ onClose : onClose_ ,
41+ ... rprops
42+ } = props_ ;
43+ const { onHide : onHideModal } = useContext ( ModalHandlersContext ) ;
44+ const onClose = useCallback ( ( ) => {
45+ onClose_ ?. ( ) ;
46+ onHideModal ?. ( ) ;
47+ } , [ onHideModal , onClose_ ] ) ;
48+ const hdClassNames = classnames ( className , 'slds-modal__header' ) ;
49+ return (
50+ < div className = { hdClassNames } { ... rprops } >
51+ < h2 className = 'slds-text-heading_medium ' > { title } </ h2 >
52+ { tagline ? < p className = 'slds-m-top_x-small' > { tagline } </ p > : null }
53+ { closeButton ? (
54+ < Button
55+ type = 'icon-inverse '
56+ className = 'slds-modal__close '
57+ icon = 'close '
58+ iconSize = 'large '
59+ alt = 'Close'
60+ inverse
61+ onClick = { onClose }
62+ />
63+ ) : null }
64+ </ div >
65+ ) ;
66+ } ;
4967
68+ /**
69+ *
70+ */
5071export type ModalContentProps = {
5172 className ?: string ;
5273} ;
5374
54- export const ModalContent : React . FC < ModalContentProps > = ( {
75+ /**
76+ *
77+ */
78+ export const ModalContent : FC < ModalContentProps > = ( {
5579 className,
5680 children,
5781 ...props
@@ -64,12 +88,18 @@ export const ModalContent: React.FC<ModalContentProps> = ({
6488 ) ;
6589} ;
6690
91+ /**
92+ *
93+ */
6794export type ModalFooterProps = {
6895 className ?: string ;
6996 directional ?: boolean ;
7097} ;
7198
72- export const ModalFooter : React . FC < ModalFooterProps > = ( {
99+ /**
100+ *
101+ */
102+ export const ModalFooter : FC < ModalFooterProps > = ( {
73103 className,
74104 directional,
75105 children,
@@ -85,6 +115,9 @@ export const ModalFooter: React.FC<ModalFooterProps> = ({
85115 ) ;
86116} ;
87117
118+ /**
119+ *
120+ */
88121export type ModalSize = 'large' ;
89122
90123export type ModalProps = {
@@ -94,57 +127,40 @@ export type ModalProps = {
94127 onHide ?: ( ) => void ;
95128} & HTMLAttributes < HTMLDivElement > ;
96129
97- export class Modal extends Component < ModalProps > {
98- static Header = ModalHeader ;
99-
100- static Content = ModalContent ;
101-
102- static Footer = ModalFooter ;
103-
104- constructor ( props : Readonly < ModalProps > ) {
105- super ( props ) ;
106-
107- this . renderChildComponent = this . renderChildComponent . bind ( this ) ;
108- }
109-
110- hide ( ) {
111- if ( this . props . onHide ) {
112- this . props . onHide ( ) ;
113- }
114- }
115-
116- renderChildComponent ( comp : any ) {
117- if ( comp . type === ModalHeader ) {
118- return React . cloneElement ( comp , { onClose : this . hide . bind ( this ) } as any ) ;
119- }
120- return comp ;
121- }
122-
123- render ( ) {
124- const { className, opened, children, size, containerStyle, ...props } =
125- this . props ;
126- delete props . onHide ;
127- const modalClassNames = classnames ( className , 'slds-modal' , {
128- 'slds-fade-in-open' : opened ,
129- 'slds-modal_large' : size === 'large' ,
130- } ) ;
131- const backdropClassNames = classnames ( className , 'slds-backdrop' , {
132- 'slds-backdrop_open' : opened ,
133- } ) ;
134- return (
135- < div >
136- < div
137- className = { modalClassNames }
138- aria-hidden = { ! opened }
139- role = 'dialog'
140- { ...props }
141- >
142- < div className = 'slds-modal__container' style = { containerStyle } >
143- { React . Children . map ( children , this . renderChildComponent ) }
144- </ div >
130+ /**
131+ *
132+ */
133+ export const Modal : FC < ModalProps > = ( props ) => {
134+ const {
135+ className,
136+ opened,
137+ children,
138+ size,
139+ containerStyle,
140+ onHide,
141+ ...rprops
142+ } = props ;
143+ const modalClassNames = classnames ( className , 'slds-modal' , {
144+ 'slds-fade-in-open' : opened ,
145+ 'slds-modal_large' : size === 'large' ,
146+ } ) ;
147+ const backdropClassNames = classnames ( className , 'slds-backdrop' , {
148+ 'slds-backdrop_open' : opened ,
149+ } ) ;
150+ const handlers = useMemo ( ( ) => ( { onHide } ) , [ onHide ] ) ;
151+ return (
152+ < ModalHandlersContext . Provider value = { handlers } >
153+ < div
154+ className = { modalClassNames }
155+ aria-hidden = { ! opened }
156+ role = 'dialog'
157+ { ...rprops }
158+ >
159+ < div className = 'slds-modal__container' style = { containerStyle } >
160+ { children }
145161 </ div >
146- < div className = { backdropClassNames } />
147162 </ div >
148- ) ;
149- }
150- }
163+ < div className = { backdropClassNames } />
164+ </ ModalHandlersContext . Provider >
165+ ) ;
166+ } ;
0 commit comments