-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Users/procload/add progressbar as new component #26329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
59c84e6
60c7f67
600337a
607551a
96d4ff3
2480006
209fce1
6dbaf03
be61425
ab8f173
f05ff02
0988572
d8ff717
b682cd6
9532a32
a6acfb8
7de2f2e
d55df45
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "type": "prerelease", | ||
| "comment": "add progressbar as new component", | ||
| "packageName": "@fluentui/web-components", | ||
| "email": "ryan@ryanmerrill.net", | ||
| "dependentChangeType": "patch" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export * from './progress-bar/index.js'; | ||
| export * from './text/index.js'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| import { FluentDesignSystem } from '../fluent-design-system.js'; | ||
| import { definition } from './progress-bar.definition.js'; | ||
|
|
||
| definition.define(FluentDesignSystem.registry); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| export * from './progress-bar.js'; | ||
| export * from './progress-bar.options.js'; | ||
| export { definition as ProgressBarDefinition } from './progress-bar.definition.js'; | ||
| export { styles as ProgressBarStyles } from './progress-bar.styles.js'; | ||
| export { template as ProgressBarTemplate } from './progress-bar.template.js'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { FluentDesignSystem } from '../fluent-design-system.js'; | ||
| import { ProgressBar } from './progress-bar.js'; | ||
| import { styles } from './progress-bar.styles.js'; | ||
| import { template } from './progress-bar.template.js'; | ||
|
|
||
| /** | ||
| * The Fluent ProgressBar Element. | ||
| * | ||
| * | ||
| * @public | ||
| * @remarks | ||
| * HTML Element: \<fluent-progress-bar\> | ||
| */ | ||
| export const definition = ProgressBar.compose({ | ||
| name: `${FluentDesignSystem.prefix}-progress-bar`, | ||
| template, | ||
| styles, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import { ValuesOf } from '@microsoft/fast-foundation'; | ||
|
|
||
| /** | ||
| * ProgressBarThickness Constants | ||
| * @public | ||
| */ | ||
| export const ProgressBarThickness = { | ||
| medium: 'medium', | ||
| large: 'large', | ||
| } as const; | ||
|
|
||
| /** | ||
| * Applies bar thickness to the content | ||
| * @public | ||
| */ | ||
| export type ProgressBarThickness = ValuesOf<typeof ProgressBarThickness>; | ||
|
|
||
| /** | ||
| * ProgressBarShape Constants | ||
| * @public | ||
| */ | ||
| export const ProgressBarShape = { | ||
| rounded: 'rounded', | ||
| rectangular: 'rectangular', | ||
| } as const; | ||
|
|
||
| /** | ||
| * Applies bar shape to the content | ||
| * @public | ||
| */ | ||
| export type ProgressBarShape = ValuesOf<typeof ProgressBarShape>; | ||
|
|
||
| /** | ||
| * ProgressBarValidationState Constants | ||
| * @public | ||
| */ | ||
| export const ProgressBarValidationState = { | ||
| success: 'success', | ||
| warning: 'warning', | ||
| error: 'error', | ||
| } as const; | ||
|
|
||
| /** | ||
| * Applies validation state to the content | ||
| * @public | ||
| */ | ||
| export type ProgressBarValidationState = ValuesOf<typeof ProgressBarValidationState>; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| import { html } from '@microsoft/fast-element'; | ||
| import type { Args, Meta } from '@storybook/html'; | ||
| import { renderComponent } from '../__test__/helpers.js'; | ||
| import type { ProgressBar as FluentProgressBar } from './progress-bar.js'; | ||
| import { ProgressBarShape, ProgressBarThickness, ProgressBarValidationState } from './progress-bar.options.js'; | ||
| import './define.js'; | ||
|
|
||
| type ProgressStoryArgs = Args & FluentProgressBar; | ||
| type ProgressStoryMeta = Meta<ProgressStoryArgs>; | ||
|
|
||
| const storyTemplate = html<ProgressStoryArgs>` | ||
| <fluent-progress-bar | ||
| ?paused=${x => x.paused} | ||
| thickness=${x => x.thickness} | ||
| shape=${x => x.shape} | ||
| min=${x => x.min} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React implementation does not contain
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @chrisdholt Since we're inheriting from a FAST Foundation class, is there a way to restrict these in the Fluent implementation?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @miroslavstastny @procload We should check with edge but it's possible that they have scenarios where they have a "paused" (not disabled...) instance...I think that may have led to us adding. In terms of removing, you can't remove attributes but I do think that With regard to |
||
| max=${x => x.max} | ||
| aria-valuemin=${x => x.min} | ||
| aria-valuemax=${x => x.max} | ||
| aria-valuenow=${x => x.value} | ||
| value=${x => x.value} | ||
| validation-state=${x => x.validationState} | ||
| aria-label="Progress bar" | ||
|
procload marked this conversation as resolved.
Outdated
|
||
| ></fluent-progress-bar> | ||
| `; | ||
|
|
||
| export default { | ||
| title: 'Components/ProgressBar', | ||
| args: { | ||
| min: 0, | ||
| max: 100, | ||
| value: 15, | ||
| thickness: 'medium', | ||
| shape: 'rounded', | ||
| paused: false, | ||
| validationState: '', | ||
| }, | ||
| argTypes: { | ||
| min: { | ||
| control: 'number', | ||
| defaultValue: 0, | ||
| }, | ||
| max: { | ||
| control: 'number', | ||
| defaultValue: 100, | ||
| }, | ||
| value: { | ||
| control: 'number', | ||
| defaultValue: 15, | ||
| }, | ||
| thickness: { | ||
| control: { | ||
| type: 'select', | ||
| }, | ||
| options: Object.keys(ProgressBarThickness), | ||
|
procload marked this conversation as resolved.
Outdated
|
||
| defaultValue: 'medium', | ||
| }, | ||
| shape: { | ||
| options: Object.keys(ProgressBarShape), | ||
| control: { | ||
| type: 'select', | ||
| }, | ||
| defaultValue: 'rounded', | ||
| }, | ||
| paused: { | ||
| control: 'boolean', | ||
| defaultValue: false, | ||
| }, | ||
| validationState: { | ||
| options: Object.keys(ProgressBarValidationState), | ||
| control: { | ||
| type: 'select', | ||
| }, | ||
| defaultValue: '', | ||
| }, | ||
| }, | ||
| } as ProgressStoryMeta; | ||
|
|
||
| export const Progress = renderComponent(storyTemplate).bind({}); | ||
|
|
||
| export const ProgressIndeterminate = renderComponent(html<ProgressStoryArgs>` | ||
| <fluent-progress-bar title="Indeterminate Bar" aria-label="Indeterminate progress bar"></fluent-progress-bar> | ||
| `); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| import { css } from '@microsoft/fast-element'; | ||
| import { display } from '@microsoft/fast-foundation'; | ||
| import { | ||
| borderRadiusMedium, | ||
| colorBrandBackground2, | ||
| colorCompoundBrandBackground, | ||
| colorNeutralBackground6, | ||
| colorPaletteDarkOrangeBackground3, | ||
| colorPaletteGreenBackground3, | ||
| colorPaletteRedBackground3, | ||
| } from '../theme/design-tokens.js'; | ||
|
|
||
| /** Text styles | ||
| * @public | ||
| */ | ||
| export const styles = css` | ||
| ${display('flex')} | ||
|
|
||
| :host { | ||
| --progress-bar-thickness: 2px; | ||
| --progress-bar-radius: ${borderRadiusMedium}; | ||
| --progress-bar-color: ${colorCompoundBrandBackground}; | ||
| --progress-speed: 3s; | ||
| align-items: center; | ||
| height: var(--progress-bar-thickness); | ||
| overflow-x: hidden; | ||
| } | ||
|
|
||
| :host([thickness='large']) { | ||
| --progress-bar-thickness: 4px; | ||
| } | ||
|
|
||
| :host([shape='rectangular']) { | ||
| --progress-bar-radius: 0; | ||
| } | ||
|
|
||
| :host([validation-state='error']) { | ||
| --progress-bar-color: ${colorPaletteRedBackground3}; | ||
| } | ||
|
|
||
| :host([validation-state='warning']) { | ||
| --progress-bar-color: ${colorPaletteDarkOrangeBackground3}; | ||
| } | ||
|
|
||
| :host([validation-state='success']) { | ||
| --progress-bar-color: ${colorPaletteGreenBackground3}; | ||
| } | ||
|
|
||
| .progress { | ||
| background-color: ${colorNeutralBackground6}; | ||
| border-radius: var(--progress-bar-radius); | ||
| width: 100%; | ||
| height: var(--progress-bar-thickness); | ||
| display: flex; | ||
| align-items: center; | ||
| position: relative; | ||
| } | ||
|
|
||
| .determinate { | ||
| background-color: var(--progress-bar-color); | ||
| border-radius: var(--progress-bar-radius); | ||
| height: var(--progress-bar-thickness); | ||
| transition: all 0.2s ease-in-out; | ||
| display: flex; | ||
| } | ||
|
|
||
| .indeterminate { | ||
| height: 6px; | ||
| border-radius: var(--progress-bar-radius); | ||
| display: flex; | ||
| width: 100%; | ||
| position: relative; | ||
| overflow: hidden; | ||
| } | ||
|
|
||
| .indeterminate-indicator-1 { | ||
|
procload marked this conversation as resolved.
|
||
| position: absolute; | ||
| opacity: 0; | ||
| height: 100%; | ||
| background: linear-gradient( | ||
| to right, | ||
| ${colorBrandBackground2} 0%, | ||
| ${colorCompoundBrandBackground} 50%, | ||
| ${colorBrandBackground2} | ||
| ); | ||
| border-radius: var(--progress-bar-radius); | ||
| animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would expect some |
||
| width: 40%; | ||
| animation: indeterminate-1 var(--progress-speed) infinite; | ||
| } | ||
|
|
||
| .indeterminate-indicator-2 { | ||
| position: absolute; | ||
| opacity: 0; | ||
| height: 100%; | ||
| background: linear-gradient( | ||
| to right, | ||
| ${colorBrandBackground2} 0%, | ||
| ${colorCompoundBrandBackground} 50%, | ||
| ${colorBrandBackground2} | ||
| ); | ||
| border-radius: var(--progress-bar-radius); | ||
| animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); | ||
| width: 60%; | ||
| animation: indeterminate-2 var(--progress-speed) infinite; | ||
| } | ||
|
|
||
| :host([paused]) .indeterminate-indicator-1, | ||
| :host([paused]) .indeterminate-indicator-2 { | ||
| animation: none; | ||
| background-color: ${colorNeutralBackground6}; | ||
| width: 100%; | ||
| opacity: 1; | ||
| } | ||
|
|
||
| :host([paused]) .determinate { | ||
| background-color: var(--progress-bar-color); | ||
| } | ||
|
|
||
| @keyframes indeterminate-1 { | ||
| 0% { | ||
| opacity: 1; | ||
| transform: translateX(-100%); | ||
| } | ||
| 70% { | ||
| opacity: 1; | ||
| transform: translateX(300%); | ||
| } | ||
| 70.01% { | ||
| opacity: 0; | ||
| } | ||
| 100% { | ||
| opacity: 0; | ||
| transform: translateX(300%); | ||
| } | ||
| } | ||
| @keyframes indeterminate-2 { | ||
| 0% { | ||
| opacity: 0; | ||
| transform: translateX(-150%); | ||
| } | ||
| 29.99% { | ||
| opacity: 0; | ||
| } | ||
| 30% { | ||
| opacity: 1; | ||
| transform: translateX(-150%); | ||
| } | ||
| 100% { | ||
| transform: translateX(166.66%); | ||
| opacity: 1; | ||
| } | ||
| } | ||
| `; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import type { ElementViewTemplate } from '@microsoft/fast-element'; | ||
| import { progressTemplate } from '@microsoft/fast-foundation'; | ||
| import type { ProgressBar } from './progress-bar.js'; | ||
|
|
||
| export const template: ElementViewTemplate<ProgressBar> = progressTemplate({ | ||
| indeterminateIndicator1: `<span class="indeterminate-indicator-1" part="indeterminate-indicator-1></span>`, | ||
| indeterminateIndicator2: `<span class="indeterminate-indicator-2" part="indeterminate-indicator-2"></span>`, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { attr } from '@microsoft/fast-element'; | ||
| import { FASTProgress } from '@microsoft/fast-foundation'; | ||
| import type { ProgressBarShape, ProgressBarThickness, ProgressBarValidationState } from './progress-bar.options.js'; | ||
|
|
||
| /** | ||
| * The base class used for constructing a fluent-progress-bar custom element | ||
| * @public | ||
| */ | ||
| export class ProgressBar extends FASTProgress { | ||
| /** | ||
| * The thickness of the progress bar | ||
| * | ||
| * @public | ||
| * @remarks | ||
| * HTML Attribute: thickness | ||
| */ | ||
| @attr | ||
| public thickness: ProgressBarThickness = 'medium'; | ||
|
procload marked this conversation as resolved.
Outdated
|
||
|
|
||
| /** | ||
| * The shape of the progress bar | ||
| * @public | ||
| * @remarks | ||
| * HTML Attribute: shape | ||
| */ | ||
| @attr | ||
| public shape: ProgressBarShape = 'rounded'; | ||
|
|
||
| /** | ||
| * The validation state of the progress bar | ||
| * @public | ||
| * @remarks | ||
| * HTML Attribute: validation-state | ||
| */ | ||
| @attr({ attribute: 'validation-state' }) | ||
| public validationState: ProgressBarValidationState | null; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is interesting - @miroslavstastny curious if this is intentionally different than
squaresemantic found in badge, etc. Are we documenting these inconsistencies elsewhere or are some of these known and desired to be "aligned" back to something consistent?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not blocking but if we have an opportunity to do that work now...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My first guess would be "square" means "four equal straight sides and four right angles", which might be the case for
BadgeorAvatarwhere we use it in FUIR9, but we also use it inButtonandImagewhich can render as rectangles.ProgressBaris still unstable in FUIR9, I will discuss with engineers there.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FUIR9 will rename to
squareThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will rename in this implementation.