1
1
import React , {
2
- CSSProperties ,
3
- ElementType ,
2
+ createContext ,
4
3
forwardRef ,
5
4
HTMLAttributes ,
6
5
useEffect ,
7
6
useRef ,
8
7
useState ,
9
8
} from 'react'
10
- import { Transition } from 'react-transition-group'
9
+ import { CSSTransition } from 'react-transition-group'
11
10
import PropTypes from 'prop-types'
12
11
import classNames from 'classnames'
13
12
14
13
import { Colors , colorPropType } from '../Types'
15
- import { useForkedRef } from '../../utils/hooks'
16
-
17
- import { CButtonClose } from '../button/CButtonClose'
18
- import { CToastBody } from './CToastBody'
19
- import { CToastHeader } from './CToastHeader'
20
14
21
15
export interface CToastProps extends Omit < HTMLAttributes < HTMLDivElement > , 'title' > {
22
16
/**
@@ -25,10 +19,18 @@ export interface CToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title
25
19
* @default true
26
20
*/
27
21
autohide ?: boolean
22
+ /**
23
+ * A string of all className you want applied to the body wrapper. [docs]
24
+ */
25
+ bodyWrapperClassName ?: string
28
26
/**
29
27
* A string of all className you want applied to the base component. [docs]
30
28
*/
31
29
className ?: string
30
+ /**
31
+ * A string of all className you want applied to the close button. [docs]
32
+ */
33
+ closeButtonClassName ?: string
32
34
/**
33
35
* Sets the color context of the component to one of CoreUI’s themed colors. [docs]
34
36
*
@@ -40,28 +42,10 @@ export interface CToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title
40
42
* Delay hiding the toast (ms). [docs]
41
43
*/
42
44
delay ?: number
43
- /**
44
- * Optionally add a close button to component and allow it to self dismiss. [docs]
45
- *
46
- * @default true
47
- */
48
- dismissible ?: boolean
49
- /**
50
- * Set component's icon. [docs]
51
- */
52
- icon ?: string | ElementType
53
45
/**
54
46
* @ignore
55
47
*/
56
48
key ?: number
57
- /**
58
- * Time node for your component. [docs]
59
- */
60
- time ?: string | ElementType
61
- /**
62
- * Title node for your component. [docs]
63
- */
64
- title ?: string | ElementType
65
49
/**
66
50
* Toggle the visibility of component. [docs]
67
51
*
@@ -74,32 +58,40 @@ export interface CToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title
74
58
onDismiss ?: ( ) => void
75
59
}
76
60
61
+ interface ContextProps extends CToastProps {
62
+ visible ?: boolean
63
+ setVisible : React . Dispatch < React . SetStateAction < boolean | undefined > >
64
+ }
65
+
66
+ export const CToastContext = createContext ( { } as ContextProps )
67
+
77
68
export const CToast = forwardRef < HTMLDivElement , CToastProps > (
78
69
(
79
70
{
80
71
children,
81
72
autohide = true ,
82
- delay = 5000 ,
83
- dismissible = true ,
73
+ bodyWrapperClassName,
84
74
className,
75
+ closeButtonClassName,
85
76
color,
86
- icon ,
77
+ delay = 5000 ,
87
78
key,
88
- time,
89
- title,
90
79
visible = true ,
91
80
onDismiss,
92
81
...rest
93
82
} ,
94
83
ref ,
95
84
) => {
96
85
const [ _visible , setVisible ] = useState ( visible )
97
- const [ height , setHeight ] = useState < number > ( )
98
-
99
- const toastRef = useRef < HTMLDivElement > ( null )
100
- const forkedRef = useForkedRef ( ref , toastRef )
86
+ // const toastRef = useRef<HTMLDivElement>(null)
87
+ // const forkedRef = useForkedRef(ref, toastRef)
101
88
const timeout = useRef < number > ( )
102
89
90
+ const contextValues = {
91
+ visible : _visible ,
92
+ setVisible,
93
+ }
94
+
103
95
//triggered on mount and destroy
104
96
useEffect ( ( ) => ( ) => clearTimeout ( timeout . current ) , [ ] )
105
97
@@ -116,88 +108,37 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
116
108
}
117
109
}
118
110
119
- const duration = 150
120
-
121
- const defaultStyle : CSSProperties = {
122
- transition : `opacity ${ duration } ms linear, height ${ duration } ms linear` ,
123
- opacity : 1 ,
124
- }
125
-
126
- const transitionStyles = {
127
- entering : { opacity : 0 , height : 0 } ,
128
- entered : { opacity : 1 , height : height } ,
129
- exiting : { opacity : 1 , height : height } ,
130
- exited : { opacity : 0 , height : 0 } ,
131
- }
132
-
133
- const onEntering = ( ) => {
134
- toastRef && toastRef . current && setHeight ( toastRef . current . scrollHeight )
135
- }
136
-
137
- const onEntered = ( ) => {
138
- setHeight ( 0 )
139
- }
140
-
141
- const onExit = ( ) => {
142
- toastRef && toastRef . current && setHeight ( toastRef . current . scrollHeight )
143
- onDismiss && onDismiss ( )
144
- }
145
-
146
- const onExiting = ( ) => {
147
- // @ts -expect-error
148
- const reflow = toastRef && toastRef . current && toastRef . current . offsetHeight
149
- setHeight ( 0 )
150
- }
151
-
152
- const onExited = ( ) => {
153
- setHeight ( 0 )
154
- }
155
-
156
111
const _className = classNames (
157
112
'toast fade' ,
158
113
{
159
114
show : _visible ,
160
115
[ `bg-${ color } ` ] : color ,
116
+ 'border-0' : color ,
161
117
} ,
162
118
className ,
163
119
)
164
120
return (
165
- < Transition
121
+ < CSSTransition
166
122
in = { _visible }
167
- timeout = { duration }
168
- onEntering = { onEntering }
169
- onEntered = { onEntered }
170
- onExit = { onExit }
171
- onExiting = { onExiting }
172
- onExited = { onExited }
123
+ timeout = { 250 }
173
124
unmountOnExit
174
125
>
175
- { ( state ) => {
176
- const currentHeight = height === 0 ? null : { height }
177
- return (
178
- < div
179
- className = { _className }
180
- aria-live = "assertive"
181
- aria-atomic = "true"
182
- role = "alert"
183
- style = { { ...defaultStyle , ...transitionStyles [ state ] , ...currentHeight } }
184
- onMouseEnter = { ( ) => clearTimeout ( timeout . current ) }
185
- onMouseLeave = { ( ) => _autohide }
186
- { ...rest }
187
- key = { key }
188
- ref = { forkedRef }
189
- >
190
- { title && (
191
- < CToastHeader icon = { icon } title = { title } time = { time } >
192
- { dismissible && < CButtonClose onClick = { ( ) => setVisible ( false ) } /> }
193
- </ CToastHeader >
194
- ) }
195
- < CToastBody > { children } </ CToastBody >
196
- { ! title && dismissible && < CButtonClose onClick = { ( ) => setVisible ( false ) } /> }
197
- </ div >
198
- )
199
- } }
200
- </ Transition >
126
+ < CToastContext . Provider value = { contextValues } >
127
+ < div
128
+ className = { _className }
129
+ aria-live = "assertive"
130
+ aria-atomic = "true"
131
+ role = "alert"
132
+ onMouseEnter = { ( ) => clearTimeout ( timeout . current ) }
133
+ onMouseLeave = { ( ) => _autohide }
134
+ { ...rest }
135
+ key = { key }
136
+ ref = { ref }
137
+ >
138
+ { children }
139
+ </ div >
140
+ </ CToastContext . Provider >
141
+ </ CSSTransition >
201
142
)
202
143
} ,
203
144
)
@@ -208,12 +149,8 @@ CToast.propTypes = {
208
149
className : PropTypes . string ,
209
150
color : colorPropType ,
210
151
delay : PropTypes . number ,
211
- dismissible : PropTypes . bool ,
212
- icon : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . elementType ] ) ,
213
152
key : PropTypes . number ,
214
153
onDismiss : PropTypes . func ,
215
- time : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . elementType ] ) ,
216
- title : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . elementType ] ) ,
217
154
visible : PropTypes . bool ,
218
155
}
219
156
0 commit comments