mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
feat(progress): add parts for more design customization (#22938)
resolves #20062 fixes #21820
This commit is contained in:
@ -844,6 +844,9 @@ ion-progress-bar,prop,value,number,0,false,false
|
||||
ion-progress-bar,css-prop,--background
|
||||
ion-progress-bar,css-prop,--buffer-background
|
||||
ion-progress-bar,css-prop,--progress-background
|
||||
ion-progress-bar,part,progress
|
||||
ion-progress-bar,part,stream
|
||||
ion-progress-bar,part,track
|
||||
|
||||
ion-radio,shadow
|
||||
ion-radio,prop,color,string | undefined,undefined,false,false
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
// Progress bar
|
||||
// --------------------------------------------------
|
||||
// Host has no background by default - this will be added to the progress-buffer-bar
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Host has no background by default - this will be added to the progress-buffer-bar
|
||||
:host {
|
||||
/**
|
||||
* @prop --background: Same as --buffer-background when using a determinate progress bar, otherwise it styles the background of the ion-progress-bar itself.
|
||||
* @prop --progress-background: Color of the progress bar
|
||||
* @prop --buffer-background: Color of the buffer bar
|
||||
* @prop --background: Background of the progress track, or the buffer bar if `buffer` is set
|
||||
* @prop --progress-background: Background of the progress bar representing the current value
|
||||
* @prop --buffer-background: DEPRECATED, use `--background` instead
|
||||
*/
|
||||
--background: #{ion-color(primary, base, 0.3)};
|
||||
--progress-background: #{ion-color(primary, base)};
|
||||
--buffer-background: var(--background);
|
||||
|
||||
display: block;
|
||||
|
||||
position: relative;
|
||||
@ -25,16 +26,6 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:host(.ion-color) {
|
||||
--progress-background: #{current-color(base)};
|
||||
--buffer-background: #{current-color(base, 0.3)};
|
||||
}
|
||||
|
||||
// indeterminate has no progress-buffer-bar, so it will be added to the host
|
||||
:host(.progress-bar-indeterminate) {
|
||||
background: var(--buffer-background);
|
||||
}
|
||||
|
||||
.progress,
|
||||
.progress-indeterminate,
|
||||
.indeterminate-bar-primary,
|
||||
@ -128,27 +119,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Buffer style
|
||||
// --------------------------------------------------
|
||||
// Progress Bar: Buffer Circles
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
.buffer-circles {
|
||||
background: radial-gradient(ellipse at center, var(--buffer-background) 0%, var(--buffer-background) 30%, transparent 30%) repeat-x 5px center;
|
||||
background-image: radial-gradient(ellipse at center, var(--buffer-background) 0%, var(--buffer-background) 30%, transparent 30%);
|
||||
|
||||
/* stylelint-disable property-blacklist */
|
||||
background-repeat: repeat-x;
|
||||
background-position: 5px center;
|
||||
background-size: 10px 10px;
|
||||
/* stylelint-enable property-blacklist */
|
||||
|
||||
z-index: 0;
|
||||
animation: buffering 450ms infinite linear;
|
||||
}
|
||||
|
||||
// Progress Bar: Reversed
|
||||
// ------------------------------------------------------------------------
|
||||
// If reversed is set to true, the animation will be reversed
|
||||
// and the bars starting at the top right
|
||||
// --------------------------------------------------
|
||||
// and the bar will start at the top right
|
||||
|
||||
:host(.progress-bar-reversed) {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
// Progress paused
|
||||
// --------------------------------------------------
|
||||
// Progress Bar: Paused
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
:host(.progress-paused) {
|
||||
.indeterminate-bar-secondary,
|
||||
@ -158,8 +155,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Animation Keyframes
|
||||
// --------------------------------------------------
|
||||
// Progress Bar: Color
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
:host(.ion-color) .progress-buffer-bar {
|
||||
background: #{current-color(base, 0.3)};
|
||||
}
|
||||
|
||||
:host(.ion-color) .buffer-circles {
|
||||
background-image: radial-gradient(ellipse at center, #{current-color(base, 0.3)} 0%, #{current-color(base, 0.3)} 30%, transparent 30%);
|
||||
}
|
||||
|
||||
:host(.ion-color) {
|
||||
.progress,
|
||||
.progress-indeterminate {
|
||||
background: #{current-color(base)};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Progress Bar: Animation Keyframes
|
||||
// ------------------------------------------------------------------------
|
||||
// Source: https://github.com/material-components/material-components-web/blob/master/packages/mdc-linear-progress/_keyframes.scss
|
||||
|
||||
@keyframes primary-indeterminate-translate {
|
||||
@ -259,3 +275,4 @@
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,11 @@ import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
*
|
||||
* @part progress - The progress bar that shows the current value when `type` is `"determinate"` and slides back and forth when `type` is `"indeterminate"`.
|
||||
* @part stream - The animated circles that appear while buffering. This only shows when `buffer` is set and `type` is `"determinate"`.
|
||||
* @part track - The track bar behind the progress bar. If the `buffer` property is set and `type` is `"determinate"` the track will be the
|
||||
* width of the `buffer` value.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-progress-bar',
|
||||
@ -77,10 +82,12 @@ export class ProgressBar implements ComponentInterface {
|
||||
}
|
||||
|
||||
const renderIndeterminate = () => {
|
||||
return [
|
||||
<div class="indeterminate-bar-primary"><span class="progress-indeterminate"></span></div>,
|
||||
<div class="indeterminate-bar-secondary"><span class="progress-indeterminate"></span></div>
|
||||
];
|
||||
return (
|
||||
<div part="track" class="progress-buffer-bar">
|
||||
<div class="indeterminate-bar-primary"><span part="progress" class="progress-indeterminate"></span></div>
|
||||
<div class="indeterminate-bar-secondary"><span part="progress" class="progress-indeterminate"></span></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const renderProgress = (value: number, buffer: number) => {
|
||||
@ -88,7 +95,7 @@ const renderProgress = (value: number, buffer: number) => {
|
||||
const finalBuffer = clamp(0, buffer, 1);
|
||||
|
||||
return [
|
||||
<div class="progress" style={{ transform: `scaleX(${finalValue})` }}></div>,
|
||||
<div part="progress" class="progress" style={{ transform: `scaleX(${finalValue})` }}></div>,
|
||||
/**
|
||||
* Buffer circles with two container to move
|
||||
* the circles behind the buffer progress
|
||||
@ -98,9 +105,9 @@ const renderProgress = (value: number, buffer: number) => {
|
||||
*/
|
||||
<div class={{ 'buffer-circles-container': true, 'ion-hide': finalBuffer === 1 }} style={{ transform: `translateX(${finalBuffer * 100}%)` }}>
|
||||
<div class="buffer-circles-container" style={{ transform: `translateX(-${finalBuffer * 100}%)` }}>
|
||||
<div class="buffer-circles"></div>
|
||||
<div part="stream" class="buffer-circles"></div>
|
||||
</div>
|
||||
</div>,
|
||||
<div class="progress-buffer-bar" style={{ transform: `scaleX(${finalBuffer})` }}></div>,
|
||||
<div part="track" class="progress-buffer-bar" style={{ transform: `scaleX(${finalBuffer})` }}></div>,
|
||||
];
|
||||
};
|
||||
|
||||
@ -1,20 +1,18 @@
|
||||
# ion-progress-bar
|
||||
|
||||
ion-progress-bar is a horizontal progress bar to visualize the progression of an operation and activity. You can choose between two types: `determinate` and `indeterminate`.
|
||||
Progress bars inform users about the status of ongoing processes, such as loading an app, submitting a form, or saving updates. There are two types of progress bars: `determinate` and `indeterminate`.
|
||||
|
||||
## Progress Type
|
||||
|
||||
### Determinate
|
||||
|
||||
If the percentage of an operation is known, you should use the determinate type. This is the default type and the progress is represented by the `value` property.
|
||||
Determinate is the default type. It should be used when the percentage of an operation is known. The progress is represented by setting the `value` property. This can be used to show the progress increasing from 0 to 100% of the track.
|
||||
|
||||
A buffer shows circles as animation to indicate some activity. If the `buffer` property is smaller than 1 you can show the additional buffering progress.
|
||||
If the `buffer` property is set, a buffer stream will show with animated circles to indicate activity. The value of the `buffer` property will also be represented by how much visible track there is. If the value of `buffer` is less than the `value` property, there will be no visible track. If `buffer` is equal to `1` then the buffer stream will be hidden.
|
||||
|
||||
### Indeterminate
|
||||
|
||||
If an operation is in progress and it's not necessary to indicate how long it will take.
|
||||
|
||||
If you add `reversed="true"`, you receive a query which is used to indicate pre-loading.
|
||||
The indeterminate type should be used when it is unknown how long the process will take. The progress bar is not tied to the `value`, instead it continually slides along the track until the process is complete.
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
@ -144,13 +142,22 @@ export default defineComponent({
|
||||
| `value` | `value` | The value determines how much of the active bar should display when the `type` is `"determinate"`. The value should be between [0, 1]. | `number` | `0` |
|
||||
|
||||
|
||||
## Shadow Parts
|
||||
|
||||
| Part | Description |
|
||||
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `"progress"` | The progress bar that shows the current value when `type` is `"determinate"` and slides back and forth when `type` is `"indeterminate"`. |
|
||||
| `"stream"` | The animated circles that appear while buffering. This only shows when `buffer` is set and `type` is `"determinate"`. |
|
||||
| `"track"` | The track bar behind the progress bar. If the `buffer` property is set and `type` is `"determinate"` the track will be the width of the `buffer` value. |
|
||||
|
||||
|
||||
## CSS Custom Properties
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--background` | Same as --buffer-background when using a determinate progress bar, otherwise it styles the background of the ion-progress-bar itself. |
|
||||
| `--buffer-background` | Color of the buffer bar |
|
||||
| `--progress-background` | Color of the progress bar |
|
||||
| ----------------------- | ---------------------------------------------------------------------- |
|
||||
| `--background` | Background of the progress track, or the buffer bar if `buffer` is set |
|
||||
| `--buffer-background` | DEPRECATED, use `--background` instead |
|
||||
| `--progress-background` | Background of the progress bar representing the current value |
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
10
core/src/components/progress-bar/test/standalone/e2e.ts
Normal file
10
core/src/components/progress-bar/test/standalone/e2e.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('progress-bar: standalone', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/progress-bar/test/standalone?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
@ -12,19 +12,171 @@
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
|
||||
|
||||
<body>
|
||||
<h1>Default Progress Bar</h1>
|
||||
<h1>Default Progress Bars</h1>
|
||||
<ion-progress-bar></ion-progress-bar>
|
||||
|
||||
<h1>Default Progress Bar with 50% width</h1>
|
||||
<ion-progress-bar value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar type="indeterminate"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Colorize Progress Bar</h1>
|
||||
<h1>Progress Bar: Colors</h1>
|
||||
<ion-progress-bar color="primary" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="secondary" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="tertiary" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="success" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="warning" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="danger" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="dark" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="light" value="0.5"></ion-progress-bar>
|
||||
|
||||
<h1>Other types</h1>
|
||||
<ion-progress-bar type="indeterminate"></ion-progress-bar>
|
||||
<hr>
|
||||
|
||||
<h1>Default Types</h1>
|
||||
<ion-progress-bar></ion-progress-bar>
|
||||
<ion-progress-bar value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar color="warning" reversed="true" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar buffer="0"></ion-progress-bar>
|
||||
<ion-progress-bar color="danger" type="indeterminate"></ion-progress-bar>
|
||||
<ion-progress-bar type="indeterminate" reversed="true"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Custom: colors by part</h1>
|
||||
<ion-progress-bar class="custom-color-parts"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" buffer="0.9"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" color="warning" reversed="true" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" buffer="0"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" color="danger" type="indeterminate"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" type="indeterminate" reversed="true"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Custom: colors by css variable</h1>
|
||||
<ion-progress-bar class="custom-color-variables"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" color="warning" reversed="true" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" buffer="0"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" color="danger" type="indeterminate"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" type="indeterminate" reversed="true"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Custom border radius</h1>
|
||||
<ion-progress-bar class="custom-border-radius"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-border-radius" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-border-radius" type="indeterminate"></ion-progress-bar>
|
||||
|
||||
<h1>Custom transition</h1>
|
||||
<ion-progress-bar class="random-value" max="100"></ion-progress-bar>
|
||||
<ion-progress-bar class="random-value custom-transition" max="100"></ion-progress-bar>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
let randomValues = document.querySelectorAll('.random-value');
|
||||
|
||||
setInterval(() => {
|
||||
let value = Math.random();
|
||||
|
||||
for (let i = 0; i < randomValues.length; i++) {
|
||||
randomValues[i].value = value;
|
||||
}
|
||||
}, 100);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
|
||||
color: #a1a7b0;
|
||||
|
||||
margin-top: 10px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
hr {
|
||||
background: #eff1f3;
|
||||
border: none;
|
||||
|
||||
height: 1px;
|
||||
|
||||
margin-top: 18px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
ion-progress-bar {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom progress bar color using parts
|
||||
* ------------------------------------------------------
|
||||
* Note: in these examples setting the background on
|
||||
* each element should override the color prop
|
||||
*/
|
||||
|
||||
/* determinate buffer / track and indeterminate track */
|
||||
.custom-color-parts::part(track) {
|
||||
background:rgb(158, 157, 36, 0.2);
|
||||
}
|
||||
|
||||
/* determinate and indeterminate progress background */
|
||||
.custom-color-parts::part(progress) {
|
||||
background: #9e9d24;
|
||||
}
|
||||
|
||||
/* buffer stream (animated circles) */
|
||||
.custom-color-parts::part(stream) {
|
||||
background-image: radial-gradient(ellipse at center, rgb(158, 157, 36, 0.2) 0%, rgb(158, 157, 36, 0.2) 30%, transparent 30%);
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom progress bar color using css variables
|
||||
* ------------------------------------------------------
|
||||
* Note: in this example setting the background via
|
||||
* CSS variables should NOT override the color prop
|
||||
*/
|
||||
.custom-color-variables {
|
||||
--background: rgb(158, 157, 36, 0.2);
|
||||
--progress-background: #9e9d24;
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom progress bar border radius using parts
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
.custom-border-radius {
|
||||
border-radius: 10px;
|
||||
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.custom-border-radius::part(progress) {
|
||||
border-radius: 0 50% 50% 0;
|
||||
}
|
||||
|
||||
.custom-border-radius[type="indeterminate"]::part(progress) {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom transition for fast value changes
|
||||
* ------------------------------------------------------
|
||||
* The first progress bar in the example has the default
|
||||
* transition, while the second has none. This is
|
||||
* apparent because they use the same values.
|
||||
*/
|
||||
.custom-transition::part(progress) {
|
||||
transition: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user