Skip to content

Commit e818a28

Browse files
committed
feat(CToast): add animations
1 parent 635de93 commit e818a28

File tree

3 files changed

+63
-37
lines changed

3 files changed

+63
-37
lines changed

docs/4.0/components/toast.mdx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ To encourage extensible and predictable toasts, we recommend a header and body.
3535
Toasts are as flexible as you need and have very little required markup. At a minimum, we require a single element to contain your "toasted" content and strongly encourage a dismiss button.
3636

3737
<Example>
38-
<CToast title="CoreUI for React.js" autohide={false}>
38+
<CToast title="CoreUI for React.js" autohide={false} visible={true}>
3939
<CToastHeader close>
4040
<svg
4141
className="rounded me-2"
@@ -56,7 +56,7 @@ Toasts are as flexible as you need and have very little required markup. At a mi
5656
</Example>
5757

5858
```jsx
59-
<CToast title="CoreUI for React.js" autohide={false}>
59+
<CToast title="CoreUI for React.js" autohide={false} visible={true}>
6060
<CToastHeader close>
6161
<svg
6262
className="rounded me-2"
@@ -147,7 +147,7 @@ return (
147147
Toasts are slightly translucent to blend in with what's below them.
148148

149149
<Example className="bg-dark border-0">
150-
<CToast title="CoreUI for React.js" autohide={false}>
150+
<CToast title="CoreUI for React.js" autohide={false} visible={true}>
151151
<CToastHeader close>
152152
<svg
153153
className="rounded me-2"
@@ -168,7 +168,7 @@ Toasts are slightly translucent to blend in with what's below them.
168168
</Example>
169169

170170
```jsx
171-
<CToast title="CoreUI for React.js" autohide={false}>
171+
<CToast title="CoreUI for React.js" autohide={false} visible={true}>
172172
<CToastHeader close>
173173
<svg
174174
className="rounded me-2"
@@ -194,7 +194,7 @@ You can stack toasts by wrapping them in a toast container, which will verticall
194194

195195
<Example>
196196
<CToaster>
197-
<CToast title="CoreUI for React.js" autohide={false}>
197+
<CToast title="CoreUI for React.js" autohide={false} visible={true}>
198198
<CToastHeader close>
199199
<svg
200200
className="rounded me-2"
@@ -212,7 +212,7 @@ You can stack toasts by wrapping them in a toast container, which will verticall
212212
</CToastHeader>
213213
<CToastBody>Hello, world! This is a toast message.</CToastBody>
214214
</CToast>
215-
<CToast title="CoreUI for React.js" autohide={false}>
215+
<CToast title="CoreUI for React.js" autohide={false} visible={true}>
216216
<CToastHeader close>
217217
<svg
218218
className="rounded me-2"
@@ -235,7 +235,7 @@ You can stack toasts by wrapping them in a toast container, which will verticall
235235

236236
```jsx
237237
<CToaster>
238-
<CToast title="CoreUI for React.js" autohide={false}>
238+
<CToast title="CoreUI for React.js" autohide={false} visible={true}>
239239
<CToastHeader close>
240240
<svg
241241
className="rounded me-2"
@@ -253,7 +253,7 @@ You can stack toasts by wrapping them in a toast container, which will verticall
253253
</CToastHeader>
254254
<CToastBody>Hello, world! This is a toast message.</CToastBody>
255255
</CToast>
256-
<CToast title="CoreUI for React.js" autohide={false}>
256+
<CToast title="CoreUI for React.js" autohide={false} visible={true}>
257257
<CToastHeader close>
258258
<svg
259259
className="rounded me-2"
@@ -279,7 +279,7 @@ You can stack toasts by wrapping them in a toast container, which will verticall
279279
Customize your toasts by removing sub-components, tweaking them with [utilities](https://coreui.io/docs/4.0/utilities/api), or by adding your own markup. Here we've created a simpler toast by removing the default `<CToastHeader>`, adding a custom hide icon from [CoreUI Icons](https://icons.coreui.io), and using some [flexbox utilities](https://coreui.io/docs/4.0/utilities/flex) to adjust the layout.
280280

281281
<Example>
282-
<CToast autohide={false} className="align-items-center">
282+
<CToast autohide={false} visible={true} className="align-items-center">
283283
<div className="d-flex">
284284
<CToastBody>Hello, world! This is a toast message.</CToastBody>
285285
<CToastClose className="me-2 m-auto" />
@@ -288,7 +288,7 @@ Customize your toasts by removing sub-components, tweaking them with [utilities]
288288
</Example>
289289

290290
```jsx
291-
<CToast autohide={false} className="align-items-center">
291+
<CToast autohide={false} visible={true} className="align-items-center">
292292
<div className="d-flex">
293293
<CToastBody>Hello, world! This is a toast message.</CToastBody>
294294
<CToastClose className="me-2 m-auto" />
@@ -299,7 +299,7 @@ Customize your toasts by removing sub-components, tweaking them with [utilities]
299299
Alternatively, you can also add additional controls and components to toasts.
300300

301301
<Example>
302-
<CToast autohide={false}>
302+
<CToast autohide={false} visible={true}>
303303
<CToastBody>
304304
Hello, world! This is a toast message.
305305
<div className="mt-2 pt-2 border-top">
@@ -315,7 +315,7 @@ Alternatively, you can also add additional controls and components to toasts.
315315
</Example>
316316

317317
```jsx
318-
<CToast autohide={false}>
318+
<CToast autohide={false} visible={true}>
319319
<CToastBody>
320320
Hello, world! This is a toast message.
321321
<div className="mt-2 pt-2 border-top">
@@ -335,7 +335,7 @@ Alternatively, you can also add additional controls and components to toasts.
335335
Building on the above example, you can create different toast color schemes with our [color](https://coreui.io/docs/4.0/utilities/colors) and [background](https://coreui.io/docs/4.0//utilities/background) utilities. Here we've set `color="primary"` and added `.text-white` class to the `<Ctoast>`, and then set `white` property to our close button. For a crisp edge, we remove the default border with `.border-0`.
336336

337337
<Example>
338-
<CToast autohide={false} color="primary" className="text-white align-items-center">
338+
<CToast autohide={false} visible={true} color="primary" className="text-white align-items-center">
339339
<div className="d-flex">
340340
<CToastBody>Hello, world! This is a toast message.</CToastBody>
341341
<CToastClose className="me-2 m-auto" white />
@@ -344,7 +344,7 @@ Building on the above example, you can create different toast color schemes with
344344
</Example>
345345

346346
```jsx
347-
<CToast autohide={false} color="primary" className="text-white align-items-center">
347+
<CToast autohide={false} visible={true} color="primary" className="text-white align-items-center">
348348
<div className="d-flex">
349349
<CToastBody>Hello, world! This is a toast message.</CToastBody>
350350
<CToastClose className="me-2 m-auto" white />

src/components/toast/CToast.tsx

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ import classNames from 'classnames'
1313
import { Colors, colorPropType } from '../Types'
1414

1515
export interface CToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
16+
/**
17+
* Apply a CSS fade transition to the toast. [docs]
18+
*
19+
* @default true
20+
*/
21+
animation?: boolean
1622
/**
1723
* Auto hide the toast. [docs]
1824
*
@@ -43,8 +49,6 @@ export interface CToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title
4349
key?: number
4450
/**
4551
* Toggle the visibility of component. [docs]
46-
*
47-
* @default true
4852
*/
4953
visible?: boolean
5054
/**
@@ -64,21 +68,26 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
6468
(
6569
{
6670
children,
71+
animation = true,
6772
autohide = true,
6873
className,
6974
color,
7075
delay = 5000,
7176
index,
7277
key,
73-
visible = true,
78+
visible = false,
7479
onDismiss,
7580
...rest
7681
},
7782
ref,
7883
) => {
79-
const [_visible, setVisible] = useState(visible)
84+
const [_visible, setVisible] = useState(false)
8085
const timeout = useRef<number>()
8186

87+
useEffect(() => {
88+
setVisible(visible)
89+
}, [visible])
90+
8291
const contextValues = {
8392
visible: _visible,
8493
setVisible,
@@ -101,42 +110,59 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
101110
}
102111

103112
const _className = classNames(
104-
'toast fade',
113+
'toast',
105114
{
106-
show: _visible,
115+
fade: animation,
107116
[`bg-${color}`]: color,
108117
'border-0': color,
109118
},
110119
className,
111120
)
121+
122+
const getTransitionClass = (state: string) => {
123+
return state === 'entering'
124+
? 'showing'
125+
: state === 'entered'
126+
? 'show'
127+
: state === 'exiting'
128+
? 'showing'
129+
: 'fade'
130+
}
131+
112132
return (
113133
<CSSTransition
114134
in={_visible}
115135
timeout={250}
116-
onExit={() => onDismiss && onDismiss(index ? index : null)}
136+
onExited={() => onDismiss && onDismiss(index ? index : null)}
117137
unmountOnExit
118138
>
119-
<CToastContext.Provider value={contextValues}>
120-
<div
121-
className={_className}
122-
aria-live="assertive"
123-
aria-atomic="true"
124-
role="alert"
125-
onMouseEnter={() => clearTimeout(timeout.current)}
126-
onMouseLeave={() => _autohide}
127-
{...rest}
128-
key={key}
129-
ref={ref}
130-
>
131-
{children}
132-
</div>
133-
</CToastContext.Provider>
139+
{(state) => {
140+
const transitionClass = getTransitionClass(state)
141+
return (
142+
<CToastContext.Provider value={contextValues}>
143+
<div
144+
className={classNames(_className, transitionClass)}
145+
aria-live="assertive"
146+
aria-atomic="true"
147+
role="alert"
148+
onMouseEnter={() => clearTimeout(timeout.current)}
149+
onMouseLeave={() => _autohide}
150+
{...rest}
151+
key={key}
152+
ref={ref}
153+
>
154+
{children}
155+
</div>
156+
</CToastContext.Provider>
157+
)
158+
}}
134159
</CSSTransition>
135160
)
136161
},
137162
)
138163

139164
CToast.propTypes = {
165+
animation: PropTypes.bool,
140166
autohide: PropTypes.bool,
141167
children: PropTypes.node,
142168
className: PropTypes.string,

src/components/toast/CToaster.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const CToaster = forwardRef<HTMLDivElement, CToasterProps>(
6969
return toasts.length > 0 || children ? (
7070
<div className={_className} {...rest} ref={ref}>
7171
{children}
72-
{toasts.map((toast) => toast)}
72+
{toasts.map((toast) => React.cloneElement(toast, { visible: true }))}
7373
</div>
7474
) : null
7575
}

0 commit comments

Comments
 (0)