-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: progress-indicator component (#184)
* feat(progress-indicator): completed progress-indicator component * fix(progress-indicator): code review and fix * fix(progress-indicator): fix storybook control bug and add jsdoc info * fix(progress-indicator): fix jsdoc default values * fix(progress-indicator): fix progress indicator text font
- Loading branch information
1 parent
3491805
commit c359b4d
Showing
7 changed files
with
307 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,8 @@ module.exports = { | |
'input', | ||
'badge', | ||
'tab', | ||
'tooltip' | ||
'tooltip', | ||
'progress-indicator' | ||
], | ||
], | ||
}, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
src/components/progress-indicator/bl-progress-indicator.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
.progress-indicator { | ||
--max: 100; | ||
--value: 0; | ||
--value-color: var(--bl-color-success); | ||
--height: var(--bl-size-2xs); | ||
--radius: var(--bl-size-3xs); | ||
|
||
position: relative; | ||
background-color: var(--bl-color-secondary-background); | ||
height: var(--height); | ||
border-radius: var(--radius); | ||
width: 100%; | ||
} | ||
|
||
.progress-indicator::before { | ||
content: ''; | ||
position: absolute; | ||
height: 100%; | ||
width: calc(100% / var(--max) * var(--value)); | ||
background-color: var(--value-color); | ||
border-radius: var(--radius); | ||
} | ||
|
||
:host([size='small']) .progress-indicator { | ||
--height: var(--bl-size-3xs); | ||
--radius: var(--bl-size-4xs); | ||
} | ||
|
||
:host([size='large']) .progress-indicator { | ||
--height: var(--bl-size-xs); | ||
--radius: 6px; | ||
} | ||
|
||
:host([failed]) .progress-indicator { | ||
--value-color: var(--bl-color-danger); | ||
} |
100 changes: 100 additions & 0 deletions
100
src/components/progress-indicator/bl-progress-indicator.stories.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { html } from 'lit'; | ||
import { ifDefined } from 'lit/directives/if-defined.js'; | ||
import { styleMap } from 'lit/directives/style-map.js'; | ||
import { Meta, Canvas, ArgsTable, Story, Preview, Source } from '@storybook/addon-docs'; | ||
|
||
<Meta | ||
title="Components/Progress Indicator" | ||
component="bl-progress-indicator" | ||
argTypes={{ | ||
size: { | ||
control: { | ||
type: 'select', | ||
options: ['small','medium', 'large'] | ||
}, | ||
type: 'string' | ||
}, | ||
max: { | ||
control: 'text', | ||
type: 'number' | ||
}, | ||
value: { | ||
control: 'text', | ||
type: 'number' | ||
}, | ||
failed: { | ||
control: 'boolean', | ||
}, | ||
}} | ||
/> | ||
|
||
export const ProgressIndicatorTemplate = (args) => html` | ||
<bl-progress-indicator | ||
size='${ifDefined(args.size)}' | ||
max='${ifDefined(args.max)}' | ||
value='${ifDefined(args.value)}' | ||
?failed=${args.failed} | ||
style='${ifDefined(args.styles ? styleMap(args.styles) : undefined)}'></bl-progress-indicator>` | ||
|
||
export const FailedTemplate = (args) => html` | ||
<div> | ||
<p style='color: var(--bl-color-danger); margin: var(--bl-size-3xs); font: var(--bl-font-title-4-regular)'>Upload Failed - Image must not be larger than 3mb.</p>${ProgressIndicatorTemplate({ value:'100', failed:true, ...args })} | ||
</div>`; | ||
|
||
export const WithMaxTemplate = (args) => html` | ||
<div> | ||
<p style='color: var(--bl-color-content-secondary); margin: var(--bl-size-3xs); font: var(--bl-font-title-4-regular)'> Completed Tasks: <b style='color: var(--bl-color-success)'> 5/8 </b></p>${ProgressIndicatorTemplate({ max:'8', value: '5', ...args })} | ||
</div>`; | ||
|
||
# Progress Indicator | ||
|
||
A progress indicator provides feedback about the duration and progression of a process to indicate how long a user will be waiting. | ||
|
||
Progress indicator component used for a long operation or a process that can take a considerable or unknown amount of time. It visually shows the progression of a system operation such as downloading, uploading, loading data, submitting a form, or saving updates. | ||
|
||
|
||
## Basic Usage | ||
|
||
By default, the `max` is 100 and the progress indicator is evaluated over 100. So the `value` must be a valid floating point number between 0 and `max`, or between 0 and 100 if `max` is omitted. | ||
|
||
|
||
<Canvas> | ||
<Story name="Basic Usage" args={{ value: '50' }}> | ||
{ProgressIndicatorTemplate.bind({})} | ||
</Story> | ||
</Canvas> | ||
|
||
You don't have to pass the `value` according to 100 percent. For example, if you have a total of 8 tasks and completed 5 tasks you can pass parameters like `max="8" value="5"`. The progress indicator will divide into 8 parts and 5 parts will be full. | ||
|
||
<Canvas> | ||
<Story name="Usage With Max Value"> | ||
{WithMaxTemplate.bind({})} | ||
</Story> | ||
</Canvas> | ||
|
||
## Progress Indicator Status | ||
The progress indicator appears in success mode (green) by default. But if you need to show fail status for example failed to upload or failed to complete tasks you can pass `failed` parameters. | ||
|
||
<Canvas> | ||
<Story name="Progress Indicator Status"> | ||
{FailedTemplate.bind({})} | ||
</Story> | ||
</Canvas> | ||
|
||
## Progress Indicator Sizes | ||
|
||
We have 3 sizes of progress indicator: `large`, `medium`, `small`. Default size is `medium`. | ||
|
||
<Canvas isColumn> | ||
<Story name="Progress Indicator Small" args={{ size: 'small', value: '45' }}> | ||
{ProgressIndicatorTemplate.bind({})} | ||
</Story> | ||
<Story name="Progress Indicator Medium" args={{ size: 'medium', value: '45' }}> | ||
{ProgressIndicatorTemplate.bind({})} | ||
</Story> | ||
<Story name="Progress Indicator Large" args={{ size: 'large', value: '45' }}> | ||
{ProgressIndicatorTemplate.bind({})} | ||
</Story> | ||
</Canvas> | ||
|
||
<ArgsTable of="bl-progress-indicator" /> |
85 changes: 85 additions & 0 deletions
85
src/components/progress-indicator/bl-progress-indicator.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { assert, elementUpdated, expect, fixture, html } from '@open-wc/testing'; | ||
import BlProgressIndicator from './bl-progress-indicator'; | ||
import type typeOfBlProgressIndicator from './bl-progress-indicator'; | ||
|
||
describe('bl-progress-indicator', () => { | ||
it('should be defined progress indicator instance', () => { | ||
//when | ||
const el = document.createElement('bl-progress-indicator'); | ||
|
||
//then | ||
assert.instanceOf(el, BlProgressIndicator); | ||
}); | ||
|
||
it('should be rendered with default values', async () => { | ||
//when | ||
const el = await fixture<typeOfBlProgressIndicator>( | ||
html`<bl-progress-indicator></bl-progress-indicator>` | ||
); | ||
|
||
//then | ||
assert.shadowDom.equal( | ||
el, | ||
` | ||
<div | ||
class="progress-indicator" | ||
role="progressbar" | ||
aria-valuemax="100" | ||
aria-valuenow="0" | ||
></div> | ||
` | ||
); | ||
}); | ||
|
||
it('should have correct default values', async () => { | ||
//when | ||
const el = await fixture<typeOfBlProgressIndicator>( | ||
html`<bl-progress-indicator></bl-progress-indicator>` | ||
); | ||
|
||
//then | ||
expect(el.size).to.equal('medium'); | ||
expect(el.max).to.equal(100); | ||
expect(el.value).to.equal(0); | ||
expect(el.failed).to.equal(false); | ||
}); | ||
|
||
it('should be rendered with correct size,max,failed,value attributes', async () => { | ||
//when | ||
const el = await fixture<typeOfBlProgressIndicator>( | ||
html`<bl-progress-indicator size="large" max="8" value="3" failed></bl-progress-indicator>` | ||
); | ||
|
||
//then | ||
const wrapper = el.shadowRoot?.querySelector('.progress-indicator') as HTMLDivElement; | ||
const cssMaxVariable = getComputedStyle(wrapper).getPropertyValue('--max'); | ||
const cssValueVariable = getComputedStyle(wrapper).getPropertyValue('--value'); | ||
|
||
expect(el.size).to.eq('large'); | ||
expect(el.max).to.eq(8); | ||
expect(el.value).to.eq(3); | ||
expect(el.failed).to.eq(true); | ||
expect(cssMaxVariable).to.eq('8'); | ||
expect(cssValueVariable).to.eq('3'); | ||
}); | ||
|
||
it('should be rendered with correct size,max,failed,value attributes when size,max,failed,value attributes was changed', async () => { | ||
//given | ||
const el = await fixture<typeOfBlProgressIndicator>( | ||
html`<bl-progress-indicator size="large" max="8" value="3"></bl-progress-indicator>` | ||
); | ||
el.setAttribute('size', 'small'); | ||
el.setAttribute('max', '5'); | ||
el.setAttribute('value', '4'); | ||
el.setAttribute('failed', 'true'); | ||
|
||
//when | ||
await elementUpdated(el); | ||
|
||
//then | ||
expect(el.size).to.eq('small'); | ||
expect(el.max).to.eq(5); | ||
expect(el.value).to.eq(4); | ||
expect(el.failed).to.eq(true); | ||
}); | ||
}); |
82 changes: 82 additions & 0 deletions
82
src/components/progress-indicator/bl-progress-indicator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { CSSResultGroup, html, LitElement, TemplateResult } from 'lit'; | ||
import { customElement, property, query, state } from 'lit/decorators.js'; | ||
import style from './bl-progress-indicator.css'; | ||
|
||
export type ProgressIndicatorSize = 'small' | 'medium' | 'large'; | ||
|
||
/** | ||
* @tag bl-progress-indicator | ||
* @summary Baklava Progress Indicator component | ||
* | ||
* @property {max} [max=100] | ||
* @property {number} [value=0] | ||
*/ | ||
|
||
@customElement('bl-progress-indicator') | ||
export default class BlProgressIndicator extends LitElement { | ||
static get styles(): CSSResultGroup { | ||
return style; | ||
} | ||
|
||
@query('.progress-indicator') private wrapper: HTMLElement; | ||
|
||
/** | ||
* Sets the size | ||
*/ | ||
@property({ type: String }) | ||
size: ProgressIndicatorSize = 'medium'; | ||
|
||
/** | ||
* Sets the status | ||
*/ | ||
@property({ type: Boolean }) | ||
failed = false; | ||
|
||
/** | ||
* Sets the max | ||
*/ | ||
@property({ type: Number }) | ||
get max() { | ||
return this._max; | ||
} | ||
set max(max: number) { | ||
this._max = max; | ||
this.updateCssVariable(); | ||
} | ||
|
||
/** | ||
* Sets the value | ||
*/ | ||
@property({ type: Number }) | ||
get value() { | ||
return this._value; | ||
} | ||
set value(value: number) { | ||
this._value = value; | ||
this.updateCssVariable(); | ||
} | ||
|
||
@state() private _max = 100; | ||
@state() private _value = 0; | ||
|
||
async updateCssVariable() { | ||
await this.updateComplete; | ||
this.wrapper.style.setProperty('--value', `${this.value}`); | ||
this.wrapper.style.setProperty('--max', `${this.max}`); | ||
} | ||
|
||
render(): TemplateResult { | ||
return html`<div | ||
class="progress-indicator" | ||
role="progressbar" | ||
aria-valuemax="${this._max}" | ||
aria-valuenow="${this._value}" | ||
></div>`; | ||
} | ||
} | ||
|
||
declare global { | ||
interface HTMLElementTagNameMap { | ||
'bl-progress-indicator': BlProgressIndicator; | ||
} | ||
} |