Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 08ffea9

Browse filesBrowse files
committed
refactor(CProgress): add a more accessible structure
1 parent aea46e3 commit 08ffea9
Copy full SHA for 08ffea9

File tree

Expand file treeCollapse file tree

5 files changed

+169
-69
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+169
-69
lines changed

‎packages/coreui-react/src/components/progress/CProgress.tsx

Copy file name to clipboardExpand all lines: packages/coreui-react/src/components/progress/CProgress.tsx
+43-8Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import React, { forwardRef, HTMLAttributes } from 'react'
1+
import React, { forwardRef, HTMLAttributes, useContext } from 'react'
22
import PropTypes from 'prop-types'
33
import classNames from 'classnames'
44

5+
import { CProgressStackedContext } from './CProgressStacked'
56
import { CProgressBar, CProgressBarProps } from './CProgressBar'
67

78
export interface CProgressProps
@@ -15,6 +16,12 @@ export interface CProgressProps
1516
* Sets the height of the component. If you set that value the inner `<CProgressBar>` will automatically resize accordingly.
1617
*/
1718
height?: number
19+
/**
20+
* A string of all className you want applied to the <CProgressBar/> component.
21+
*
22+
* @since 4.9.0
23+
*/
24+
progressBarClassName?: string
1825
/**
1926
* Makes progress bar thinner.
2027
*/
@@ -29,9 +36,10 @@ export interface CProgressProps
2936
white?: boolean
3037
}
3138

32-
// TODO: update markup and add '.progress-stacked' in v5
3339
export const CProgress = forwardRef<HTMLDivElement, CProgressProps>(
34-
({ children, className, height, thin, value = 0, white, ...rest }, ref) => {
40+
({ children, className, height, progressBarClassName, thin, value, white, ...rest }, ref) => {
41+
const { stacked } = useContext(CProgressStackedContext)
42+
3543
return (
3644
<div
3745
className={classNames(
@@ -42,15 +50,41 @@ export const CProgress = forwardRef<HTMLDivElement, CProgressProps>(
4250
},
4351
className,
4452
)}
45-
style={height ? { height: `${height}px` } : {}}
53+
{...(value !== undefined && {
54+
role: 'progressbar',
55+
'aria-valuenow': value,
56+
'aria-valuemin': 0,
57+
'aria-valuemax': 100,
58+
})}
59+
style={{
60+
...(height ? { height: `${height}px` } : {}),
61+
...(stacked ? { width: `${value}%` } : {}),
62+
}}
4663
ref={ref}
4764
>
48-
{value ? (
49-
<CProgressBar value={value} {...rest}>
65+
{React.Children.toArray(children).some(
66+
// @ts-expect-error displayName is set in the CProgressBar component
67+
(child) => child.type && child.type.displayName === 'CProgressBar',
68+
) ? (
69+
React.Children.map(children, (child) => {
70+
// @ts-expect-error displayName is set in the CProgressBar component
71+
if (React.isValidElement(child) && child.type.displayName === 'CProgressBar') {
72+
return React.cloneElement(child, {
73+
...(value && { value: value }),
74+
...rest,
75+
})
76+
}
77+
78+
return
79+
})
80+
) : (
81+
<CProgressBar
82+
{...(progressBarClassName && { className: progressBarClassName })}
83+
value={value}
84+
{...rest}
85+
>
5086
{children}
5187
</CProgressBar>
52-
) : (
53-
children
5488
)}
5589
</div>
5690
)
@@ -61,6 +95,7 @@ CProgress.propTypes = {
6195
children: PropTypes.node,
6296
className: PropTypes.string,
6397
height: PropTypes.number,
98+
progressBarClassName: PropTypes.string,
6499
thin: PropTypes.bool,
65100
value: PropTypes.number,
66101
white: PropTypes.bool,

‎packages/coreui-react/src/components/progress/CProgressBar.tsx

Copy file name to clipboardExpand all lines: packages/coreui-react/src/components/progress/CProgressBar.tsx
+5-6Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import React, { forwardRef, HTMLAttributes } from 'react'
1+
import React, { forwardRef, HTMLAttributes, useContext } from 'react'
22
import PropTypes from 'prop-types'
33
import classNames from 'classnames'
44

5+
import { CProgressStackedContext } from './CProgressStacked'
56
import { colorPropType } from '../../props'
67
import type { Colors } from '../../types'
78

@@ -32,6 +33,8 @@ export interface CProgressBarProps extends HTMLAttributes<HTMLDivElement> {
3233

3334
export const CProgressBar = forwardRef<HTMLDivElement, CProgressBarProps>(
3435
({ children, animated, className, color, value = 0, variant, ...rest }, ref) => {
36+
const { stacked } = useContext(CProgressStackedContext)
37+
3538
return (
3639
<div
3740
className={classNames(
@@ -43,11 +46,7 @@ export const CProgressBar = forwardRef<HTMLDivElement, CProgressBarProps>(
4346
},
4447
className,
4548
)}
46-
role="progressbar"
47-
style={{ width: `${value}%` }}
48-
aria-valuenow={value}
49-
aria-valuemin={0}
50-
aria-valuemax={100}
49+
{...(!stacked && { style: { width: `${value}%` } })}
5150
{...rest}
5251
ref={ref}
5352
>
+39Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { createContext, forwardRef, HTMLAttributes } from 'react'
2+
import PropTypes from 'prop-types'
3+
import classNames from 'classnames'
4+
5+
export interface CProgressStackedProps extends HTMLAttributes<HTMLDivElement> {
6+
/**
7+
* A string of all className you want applied to the component.
8+
*/
9+
className?: string
10+
}
11+
12+
export interface CProgressStackedContextProps {
13+
stacked?: boolean
14+
}
15+
16+
export const CProgressStackedContext = createContext({} as CProgressStackedContextProps)
17+
18+
export const CProgressStacked = forwardRef<HTMLDivElement, CProgressStackedProps>(
19+
({ children, className, ...rest }, ref) => {
20+
return (
21+
<div className={classNames('progress-stacked', className)} ref={ref} {...rest}>
22+
<CProgressStackedContext.Provider
23+
value={{
24+
stacked: true,
25+
}}
26+
>
27+
{children}
28+
</CProgressStackedContext.Provider>
29+
</div>
30+
)
31+
},
32+
)
33+
34+
CProgressStacked.propTypes = {
35+
children: PropTypes.node,
36+
className: PropTypes.string,
37+
}
38+
39+
CProgressStacked.displayName = 'CProgressStacked'
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { CProgress } from './CProgress'
22
import { CProgressBar } from './CProgressBar'
3+
import { CProgressStacked } from './CProgressStacked'
34

4-
export { CProgress, CProgressBar }
5+
export { CProgress, CProgressBar, CProgressStacked }

‎packages/docs/content/components/progress.mdx

Copy file name to clipboardExpand all lines: packages/docs/content/components/progress.mdx
+80-54Lines changed: 80 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ route: /components/progress
77
other_frameworks: progress
88
---
99

10-
import { CProgress, CProgressBar, CButton } from '@coreui/react/src/index'
10+
import { CButton, CProgress, CProgressBar, CProgressStacked } from '@coreui/react/src/index'
1111

1212
## Example
1313

@@ -16,42 +16,49 @@ Progress components are built with two HTML elements, some CSS to set the width,
1616
## Basic usage
1717

1818
```jsx preview
19-
<CProgress className="mb-3">
20-
<CProgressBar value={0}/>
21-
</CProgress>
22-
<CProgress className="mb-3">
23-
<CProgressBar value={25}/>
24-
</CProgress>
25-
<CProgress className="mb-3">
26-
<CProgressBar value={50}/>
27-
</CProgress>
28-
<CProgress className="mb-3">
29-
<CProgressBar value={75}/>
30-
</CProgress>
31-
<CProgress className="mb-3">
32-
<CProgressBar value={100}/>
33-
</CProgress>
19+
<CProgress value={0} />
20+
<CProgress value={25} />
21+
<CProgress value={50} />
22+
<CProgress value={75} />
23+
<CProgress value={100} />
3424
```
3525

3626
## Labels
3727

3828
Add labels to your progress bars by placing text within the `<CProgressBar>`.
3929

4030
```jsx preview
41-
<CProgress className="mb-3">
42-
<CProgressBar value={25}>25%</CProgressBar>
31+
<CProgress value={25}>25%</CProgress>
32+
```
33+
34+
Please note that the default setting for the content within the `<CProgressBar />` is to be limited by the `overflow: hidden property`, preventing it from extending beyond the bar's boundaries. If the progress bar is shorter than its label, the content will be truncated and could be difficult to read. To modify this behavior, you can utilize the `.overflow-visible` class from the overflow utilities. However, it is important to specify a specific text color to ensure readability. It's worth noting that this approach currently does not consider color modes.
35+
36+
```jsx preview
37+
<CProgress value={10}>
38+
<CProgressBar className="overflow-visible text-dark px-2" color="success">Long label text for the progress bar, set to a dark color</CProgressBar>
4339
</CProgress>
4440
```
4541

42+
Since **v4.9.0** you can also use the `progressBarClassName` property directly on the `<CProgress />` component to achieve the same.
43+
44+
```jsx
45+
<CProgress progressBarClassName="overflow-visible text-dark px-2" color="success" value={10}>Long label text for the progress bar, set to a dark color</CProgress>
46+
```
47+
4648
## Height
4749

4850
We only set a `height` value on the `<CProgress>`, so if you change that value the inner `<CProgressBar>` will automatically resize accordingly.
4951

5052
```jsx preview
51-
<CProgress height={1} className="mb-3">
53+
<CProgress height={1} value={25} />
54+
<CProgress height={20} value={25} />
55+
```
56+
57+
```jsx preview
58+
<CProgress height={1}>
5259
<CProgressBar value={25}></CProgressBar>
5360
</CProgress>
54-
<CProgress height={20} className="mb-3">
61+
<CProgress height={20}>
5562
<CProgressBar value={25}></CProgressBar>
5663
</CProgress>
5764
```
@@ -61,26 +68,60 @@ We only set a `height` value on the `<CProgress>`, so if you change that value t
6168
Use `color` prop to change the appearance of individual progress bars.
6269

6370
```jsx preview
64-
<CProgress className="mb-3">
65-
<CProgressBar color="success" value={25}/>
71+
<CProgress color="success" value={25} />
72+
<CProgress color="info" value={50} />
73+
<CProgress color="warning" value={75} />
74+
<CProgress color="danger" value={100} />
75+
```
76+
77+
Ensure that when you incorporate labels into progress bars featuring a custom background color, you also select an appropriate text color to ensure readability and maintain adequate contrast for the labels.
78+
79+
```jsx preview
80+
<CProgress color="success" value={25}>
81+
<CProgressBar>25%</CProgressBar>
6682
</CProgress>
67-
<CProgress className="mb-3">
68-
<CProgressBar color="info" value={50}/>
83+
<CProgress color="info" value={50}>
84+
<CProgressBar className="text-dark">50%</CProgressBar>
6985
</CProgress>
70-
<CProgress className="mb-3">
71-
<CProgressBar color="warning" value={75}/>
86+
<CProgress color="warning" value={75}>
87+
<CProgressBar className="text-dark">75%</CProgressBar>
7288
</CProgress>
73-
<CProgress className="mb-3">
74-
<CProgressBar color="danger" value={100}/>
89+
<CProgress color="danger" value={100}>
90+
<CProgressBar>100%</CProgressBar>
7591
</CProgress>
7692
```
7793

94+
Since **v4.9.0** you can also use the `progressBarClassName` property directly on the `<CProgress />` component to achieve the same.
95+
96+
```jsx
97+
<CProgress color="success" value={25}>25%</CProgress>
98+
<CProgress color="info" progressBarClassName="text-dark" value={50}>50%</CProgress>
99+
<CProgress color="warning" progressBarClassName="text-dark" value={75}>75%</CProgress>
100+
<CProgress color="danger" value={100}>100%</CProgress>
101+
```
102+
78103
## Multiple bars
79104

80-
Include multiple progress bars in a progress component if you need.
105+
Include multiple progress bars in a progress component if you need. In **v4.9.0**
106+
107+
<Callout color="info" title="New markup in v4.9.0">
108+
In version 4.9.0, we introduced a new `<CProgressStacked>` component to more logically wrap multiple progress bars into a single stacked progress bar. The previous structure will continue to work until the next major version.
109+
</Callout>
110+
111+
112+
**New markup**
81113

82114
```jsx preview
83-
<CProgress className="mb-3">
115+
<CProgressStacked>
116+
<CProgress value={15} />
117+
<CProgress color="success" value={30} />
118+
<CProgress color="info" value={20} />
119+
</CProgressStacked>
120+
```
121+
122+
**Previous markup**
123+
```jsx
124+
<CProgress>
84125
<CProgressBar value={15} />
85126
<CProgressBar color="success" value={30} />
86127
<CProgressBar color="info" value={20} />
@@ -92,37 +133,22 @@ Include multiple progress bars in a progress component if you need.
92133
Add `variant="striped"` to any `<CProgressBar>` to apply a stripe via CSS gradient over the progress bar's background color.
93134

94135
```jsx preview
95-
<CProgress className="mb-3">
96-
<CProgressBar color="success" variant="striped" value={25}/>
97-
</CProgress>
98-
<CProgress className="mb-3">
99-
<CProgressBar color="info" variant="striped" value={50}/>
100-
</CProgress>
101-
<CProgress className="mb-3">
102-
<CProgressBar color="warning" variant="striped" value={75}/>
103-
</CProgress>
104-
<CProgress className="mb-3">
105-
<CProgressBar color="danger" variant="striped" value={100}/>
106-
</CProgress>
136+
<CProgress color="success" variant="striped" value={25} />
137+
<CProgress color="info" variant="striped" value={50} />
138+
<CProgress color="warning" variant="striped" value={75} />
139+
<CProgress color="danger" variant="striped" value={100} />
107140
```
108141

142+
109143
## Animated stripes
110144

111145
The striped gradient can also be animated. Add `animated` property to `<CProgressBar>` to animate the stripes right to left via CSS3 animations.
112146

113147
```jsx preview
114-
<CProgress className="mb-3">
115-
<CProgressBar color="success" variant="striped" animated value={25}/>
116-
</CProgress>
117-
<CProgress className="mb-3">
118-
<CProgressBar color="info" variant="striped" animated value={50}/>
119-
</CProgress>
120-
<CProgress className="mb-3">
121-
<CProgressBar color="warning" variant="striped" animated value={75}/>
122-
</CProgress>
123-
<CProgress className="mb-3">
124-
<CProgressBar color="danger" variant="striped" animated value={100}/>
125-
</CProgress>
148+
<CProgress color="success" variant="striped" animated value={25} />
149+
<CProgress color="info" variant="striped" animated value={50} />
150+
<CProgress color="warning" variant="striped" animated value={75} />
151+
<CProgress color="danger" variant="striped" animated value={100} />
126152
```
127153

128154
## Customizing

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.