Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .bundlewatch.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,35 @@
},
{
"path": "./dist/css/coreui.css",
"maxSize": "73.5 kB"
"maxSize": "74 kB"
},
{
"path": "./dist/css/coreui.min.css",
"maxSize": "69.25 kB"
"maxSize": "69.75 kB"
},
{
"path": "./dist/js/coreui.bundle.js",
"maxSize": "129KB"
"maxSize": "130KB"
},
{
"path": "./dist/js/coreui.bundle.min.js",
"maxSize": "83KB"
"maxSize": "84KB"
},
{
"path": "./dist/js/coreui.esm.js",
"maxSize": "118KB"
"maxSize": "119KB"
},
{
"path": "./dist/js/coreui.esm.min.js",
"maxSize": "85KB"
"maxSize": "86KB"
},
{
"path": "./dist/js/coreui.js",
"maxSize": "119KB"
"maxSize": "120KB"
},
{
"path": "./dist/js/coreui.min.js",
"maxSize": "77KB"
"maxSize": "78KB"
}
],
"ci": {
Expand Down
92 changes: 92 additions & 0 deletions docs/src/content/docs/components/progress.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,25 @@ The class works one level up as well — put it on the `.progress` and every bar

A [`.bg-*` utility](/utilities/background/) still paints a bar, but it sets the fill alone — the label keeps the default foreground colour rather than the one that reads on the fill.

## Gradients

<AddedIn version="6.0.0" />

Set `--cui-progress-bar-bg-image` to paint the bar with a gradient instead of a flat colour. The image is sized to the bar, so the whole gradient is visible at any width and the label keeps the colour set by the theme. Set it on the `.progress` to share one gradient between every bar inside, or on a single `.progress-bar`.

<Example code={`<div class="progress mb-3" style="--cui-progress-bar-bg-image: linear-gradient(to right, #e6412c, #ffb400, #ffe25a)">
<div class="progress-bar" role="progressbar" style="width: 45%" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress" style="--cui-progress-bar-bg-image: linear-gradient(to right, var(--cui-info-base), var(--cui-success-base))">
<div class="progress-bar" role="progressbar" style="width: 70%" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100">70%</div>
</div>`} />

Stripes are a second layer over the gradient, so `.progress-bar-striped` and `.progress-bar-animated` combine with it. Change the stripe pattern itself with `--cui-progress-bar-stripes`, or just its colour with `--cui-progress-bar-stripe-color`.

<Example code={`<div class="progress" style="--cui-progress-bar-bg-image: linear-gradient(to right, #e6412c, #ffb400, #ffe25a)">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 65%" aria-valuenow="65" aria-valuemin="0" aria-valuemax="100"></div>
</div>`} />

## Multiple bars

Include multiple progress bars in a progress component if you need.
Expand All @@ -125,6 +144,43 @@ Include multiple progress bars in a progress component if you need.
</div>
</div>`} />

## Segmented

<AddedIn version="6.0.0" />

Add `.progress-segmented` to a `.progress` or `.progress-stacked` to cut the track into a row of rounded segments. It is a CSS mask over the whole component, so the bar underneath keeps its transition, theme, gradient and stripes; only the rendering changes. Segments are `--cui-progress-segment-min-width` wide (.25rem) and `--cui-progress-segment-gap` apart, as many as fit; set `--cui-progress-segments` instead and the track holds exactly that many, scaled to its width, with the gap staying put.

<Example code={`<div class="progress progress-segmented mb-3" style="height: 3rem; --cui-progress-bar-bg-image: linear-gradient(to right, #e6412c, #ffb400, #ffe25a)">
<div class="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress progress-segmented mb-3">
<div class="progress-bar theme-success" role="progressbar" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress progress-segmented mb-3" style="height: 1.5rem; --cui-progress-segments: 20; --cui-progress-segment-gap: .5rem">
<div class="progress-bar theme-info" role="progressbar" aria-valuenow="30" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress progress-segmented" style="height: 1.5rem; --cui-progress-segment-min-width: 1rem">
<div class="progress-bar theme-danger" role="progressbar" aria-valuenow="30" aria-valuemin="0" aria-valuemax="100"></div>
</div>`} />

The bars above carry no `width`. The Progress plugin picks up every `.progress-segmented` on page load, reads `aria-valuenow`, `aria-valuemin` and `aria-valuemax` from the bar, and sets `--cui-progress-segments-filled` to the number of whole segments the value covers, rounded down; the stylesheet turns that into the bar's width, so the fill always ends on a segment's edge. Change `aria-valuenow` and the bar follows. The plugin also watches the track's width and writes the count that fits above `--cui-progress-segment-min-width` to `--cui-progress-segments-fit`, capped at `--cui-progress-segments` when that is set, and recounts the fill — so a narrow screen shows fewer segments rather than thinner ones, and the last segment is always whole. Without the plugin and without a count, the stylesheet tiles the minimum width and clips whatever is left at the end of the track. Without the plugin, set `--cui-progress-segments-filled` on the bar yourself, or give the bar a `width` as usual and accept a partly coloured segment on the boundary.

<Example code={`<div class="progress progress-segmented mb-3" style="--cui-progress-segments: 10">
<div class="progress-bar" style="--cui-progress-segments-filled: 4"></div>
</div>
<div class="progress progress-segmented" style="--cui-progress-segments: 10">
<div class="progress-bar theme-warning" role="progressbar" style="width: 45%" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100"></div>
</div>`} />

The corners follow `--cui-progress-segment-border-radius`, `--cui-radius-2` by default — a full cap on a segment twice as wide as that, and the same corner on a wider one. The plugin caps it at half the segment and half the track height, as `border-radius` would; the stylesheet alone caps it at half the minimum width. Set it to `0px` for square segments, or anything in between. The value feeds the mask's `calc()`, so it has to be a length — a unitless `0` drops the whole mask.

<Example code={`<div class="progress progress-segmented mb-3" style="height: 1.5rem; --cui-progress-segments: 10; --cui-progress-segment-border-radius: 0px">
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress progress-segmented" style="height: 1.5rem; --cui-progress-segments: 10; --cui-progress-segment-border-radius: var(--cui-radius-5)">
<div class="progress-bar theme-warning" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>
</div>`} />

## On a colored surface

Add `.progress-white` to draw the bar in white and the track as translucent white. That way a progress bar sitting on a dark or brand-colored surface stays readable without a color of its own; the bar stays white even under a `.theme-*` class.
Expand Down Expand Up @@ -222,6 +278,38 @@ Or stack a header above the bar, with the value pushed to the end by `.ms-auto`:
</div>
</div>`} />

## Usage

<AddedIn version="6.0.0" />

The plugin only runs on `.progress-segmented`; a plain `.progress` is CSS only and never gets an instance.

### Via data attributes

Every `.progress-segmented` is initialized on page load — no toggle attribute needed. The bar's `aria-valuenow`, `aria-valuemin` and `aria-valuemax` are the value; leave `width` off the bar. `--cui-progress-segment-min-width` sets how many segments fit, and `--cui-progress-segments`, when set, caps that; both are read from the stylesheet, so set them on the element or on a parent.

```html
<div class="progress progress-segmented">
<div class="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100"></div>
</div>
```

### Via JavaScript

```js
const element = document.querySelector('.progress-segmented')
const progress = new coreui.Progress(element)
```

### Methods

| Method | Description |
| --- | --- |
| `update` | Recomputes the segment count and the filled segments. The plugin already watches the bar's `aria-*` attributes and the track's width, so this is for a change of the tokens made from script. |
| `dispose` | Destroys the instance and removes the variables it set. |
| `getInstance` | Static method which allows you to get the Progress instance associated to a DOM element, you can use it like this: `coreui.Progress.getInstance(element)` |
| `getOrCreateInstance` | Static method which returns a Progress instance associated to a DOM element or create a new one in case it wasn't initialized. You can use it like this: `coreui.Progress.getOrCreateInstance(element)` |

## Customizing

### CSS variables
Expand All @@ -230,6 +318,10 @@ Progress bars use local CSS variables on `.progress` for enhanced real-time cust

<ScssDocs file="scss/_progress.scss" capture="progress-css-vars" />

`.progress-segmented` adds the segment geometry:

<ScssDocs file="scss/_progress.scss" capture="progress-segmented-css-vars" />

### Sass variables

<DeprecatedIn version="6.0.0" />
Expand Down
24 changes: 24 additions & 0 deletions docs/src/content/docs/migration/v6.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2133,6 +2133,30 @@ Multi Select's option indicators moved with it — they render as a decorative
`.theme-*` class, as the variant is meant for dark and brand-coloured
surfaces.

- **Gradient bars.** `--cui-progress-bar-bg-image` (default `none`) paints the
bar with an image on top of its colour, so a gradient is one variable on the
`.progress` or the bar. The stripes moved to their own tokens for the same
reason: `--cui-progress-bar-stripes` holds the pattern and
`--cui-progress-bar-stripe-color` its colour, and `.progress-bar-striped`
layers the pattern over the image. The `progress-bar-stripes` keyframes now
shift only the first background layer, so the image underneath stays put.

- **`.progress-segmented`.** A mask that cuts a `.progress` or
`.progress-stacked` into a row of rounded segments, `--cui-progress-segment-min-width`
wide and `--cui-progress-segment-gap` apart — or exactly `--cui-progress-segments`
of them when that is set — with corners from
`--cui-progress-segment-border-radius` (`--cui-radius-2` by default, `0px`
for square). Everything under the mask — transition, theme,
gradient, stripes — behaves as before.

- **New `Progress` plugin.** Initialized on every `.progress-segmented`, it
reads the bar's `aria-valuenow`, `aria-valuemin` and `aria-valuemax` and sets
`--cui-progress-segments-filled`, which the stylesheet turns into the bar's
width, so the fill ends on a whole segment. It also counts how many segments
of `--cui-progress-segment-min-width` fit the track, capped at
`--cui-progress-segments` when set, and follows the track as it resizes. Bars that keep an inline `width` are not touched.
`coreui.Progress` is exported next to the other plugins.

#### Spinner

- <span class="badge text-danger-emphasis bg-danger-subtle">Breaking</span>
Expand Down
2 changes: 2 additions & 0 deletions js/index.umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import NumberInput from './src/number-input.js'
import PasswordInput from './src/password-input.js'
import PasswordStrength from './src/password-strength.js'
import Popover from './src/popover.js'
import Progress from './src/progress.js'
import Range from './src/range.js'
import RangeSlider from './src/range-slider.js'
import Rating from './src/rating.js'
Expand Down Expand Up @@ -77,6 +78,7 @@ export default {
PasswordInput,
PasswordStrength,
Popover,
Progress,
Range,
RangeSlider,
Rating,
Expand Down
1 change: 1 addition & 0 deletions js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export { default as OTPInput } from './otp-input.js'
export { default as PasswordInput } from './password-input.js'
export { default as PasswordStrength } from './password-strength.js'
export { default as Popover } from './popover.js'
export { default as Progress } from './progress.js'
export { default as Range } from './range.js'
export { default as RangeSlider } from './range-slider.js'
export { default as Rating } from './rating.js'
Expand Down
Loading
Loading