ACS-8434: progress component (#9960)

This commit is contained in:
Denys Vuika 2024-07-23 09:53:25 -04:00 committed by GitHub
parent 537a81df64
commit 5165fd1433
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 299 additions and 4 deletions

View File

@ -81,10 +81,11 @@ for more information about installing and using the source code.
A collection of Angular components for generic use.
| Name | Description |
|-----------------------------------------------|------------------------------|
| [Avatar](core/components/avatar.component.md) | Displays user avatars. |
| [Button](core/components/button.component.md) | A standard button component. |
| Name | Description |
|---------------------------------------------------|------------------------------|
| [Avatar](core/components/avatar.component.md) | Displays user avatars. |
| [Button](core/components/button.component.md) | A standard button component. |
| [Progress](core/components/progress.component.md) | A progress bar component. |
### Components

View File

@ -0,0 +1 @@
../../../lib/core/src/lib/progress/progress.component.md

View File

@ -0,0 +1,23 @@
<ng-container [ngSwitch]="variant">
<ng-container *ngSwitchDefault>
<mat-progress-bar
[mode]="$any(mode)"
[value]="value"
[color]="color"
[attr.aria-label]="ariaLabel"
[attr.aria-hidden]="ariaHidden"
[attr.data-automation-id]="testId">
</mat-progress-bar>
</ng-container>
<ng-container *ngSwitchCase="'spinner'">
<mat-progress-spinner
[mode]="$any(mode)"
[value]="value"
[color]="color"
[attr.aria-label]="ariaLabel"
[attr.aria-hidden]="ariaHidden"
[attr.data-automation-id]="testId">
</mat-progress-spinner>
</ng-container>
</ng-container>

View File

@ -0,0 +1,79 @@
# Progress Component
`standalone`, `component`
The Progress component is a simple component that can be used to display progress bars.
## Usage
```html
<adf-progress [value]="50"></adf-progress>
```
### Variant
The progress bar supports the following variants:
- bar (default)
- spinner
```html
<adf-progress variant="bar" [value]="50"></adf-progress>
<adf-progress variant="spinner" [value]="50"></adf-progress>
```
### Mode
The progress bar supports the following modes:
- For progress spinner, the mode can be either `indeterminate` or `determinate`.
- For progress bar, the mode can be either `determinate`, `indeterminate`, `buffer`, or `query`.
> For the spinner variant, setting the mode to unsupported values will default to `indeterminate`.
Example:
```html
<adf-progress [value]="50" mode="determinate"></adf-progress>
<adf-progress [value]="50" mode="indeterminate"></adf-progress>
```
### Color
The progress bar supports the following colors:
- default
- primary
- accent
- warn
```html
<adf-progress [value]="50" color="primary"></adf-progress>
<adf-progress [value]="50" color="accent"></adf-progress>
<adf-progress [value]="50" color="warn"></adf-progress>
```
## API
Import the following standalone components:
```typescript
import { ProgressComponent } from '@alfresco/adf-core';
```
## Properties
| Name | Type | Default | Description |
|-----------|-----------------|-----------------|-----------------------------------------------------------|
| `variant` | ProgressVariant | `bar` | The progress bar variant. |
| `value` | number | | The value of the progress bar. |
| `color` | ProgressColor | | The color of the progress bar. |
| `mode` | ProgressMode | `indeterminate` | The mode of the progress bar. |
| `testId` | string | | The button test id (uses `data-automation-id` attribute). |
### Accessibility
The button component has been designed to be accessible. The following attributes are available:
- `ariaLabel`: The button aria label.
- `ariaHidden`: Whether the button should be hidden from the accessibility tree.

View File

@ -0,0 +1,103 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatProgressBarHarness } from '@angular/material/progress-bar/testing';
import { ProgressComponent } from './progress.component';
describe('ProgressComponent', () => {
let component: ProgressComponent;
let fixture: ComponentFixture<ProgressComponent>;
let loader: HarnessLoader;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MatProgressBarModule, MatProgressSpinnerModule, NoopAnimationsModule, ProgressComponent]
}).compileComponents();
fixture = TestBed.createComponent(ProgressComponent);
loader = TestbedHarnessEnvironment.loader(fixture);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should default to bar variant and indeterminate mode', () => {
expect(component.variant).toBe('bar');
expect(component.mode).toBe('indeterminate');
});
it('should change mode to determinate when value is set', () => {
component.value = 50;
expect(component.mode).toBe('determinate');
});
it('should not change mode if variant is spinner and an invalid mode is set', () => {
component.variant = 'spinner';
component.mode = 'query'; // Invalid for spinner
expect(component.mode).toBe('indeterminate');
});
it('should accept buffer mode when variant is bar', () => {
component.variant = 'bar';
component.mode = 'buffer';
expect(component.mode).toBe('buffer');
});
it('should ignore setting value to undefined', () => {
component.value = 50;
component.value = undefined;
expect(component.value).toBeUndefined();
expect(component.mode).toBe('determinate'); // Mode remains unchanged
});
it('should apply ariaLabel if provided', async () => {
const testLabel = 'Progress Label';
component.ariaLabel = testLabel;
fixture.detectChanges();
const progress = await loader.getHarness(MatProgressBarHarness);
const host = await progress.host();
expect(await host.getAttribute('aria-label')).toBe(testLabel);
});
it('should hide from accessibility tree if ariaHidden is true', async () => {
component.ariaHidden = true;
fixture.detectChanges();
const progress = await loader.getHarness(MatProgressBarHarness);
const host = await progress.host();
expect(await host.getAttribute('aria-hidden')).toBe('true');
});
it('should set testId if provided', () => {
const testId = 'progress-test-id';
component.testId = testId;
fixture.detectChanges();
const progressBarElement = fixture.nativeElement.querySelector(`[data-automation-id="${testId}"]`);
expect(progressBarElement).not.toBeNull();
});
});

View File

@ -0,0 +1,87 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { MatProgressBarModule, ProgressBarMode } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule, ProgressSpinnerMode } from '@angular/material/progress-spinner';
import { CommonModule } from '@angular/common';
import { ThemePalette } from '@angular/material/core';
export type ProgressVariant = 'bar' | 'spinner' | undefined;
export type ProgressMode = ProgressBarMode | ProgressSpinnerMode;
export type ProgressColor = ThemePalette;
@Component({
selector: 'adf-progress',
standalone: true,
imports: [CommonModule, MatProgressBarModule, MatProgressSpinnerModule],
templateUrl: './progress.component.html',
encapsulation: ViewEncapsulation.None
})
export class ProgressComponent {
private _mode: ProgressMode = 'indeterminate';
private _value?: number;
@Input() variant: ProgressVariant = 'bar';
@Input() color?: ProgressColor;
@Input() ariaLabel?: string;
@Input() ariaHidden?: boolean;
@Input() testId?: string;
/**
* The value of the progress bar or spinner.
* Changes the mode to `determinate` if a value is provided.
*
* @returns The progress value
*/
get value(): number | undefined {
return this._value;
}
@Input()
set value(value: number | undefined) {
if (value !== undefined) {
this._mode = 'determinate';
}
this._value = value;
}
/**
* The progress bar display mode. Defaults to `indeterminate`.
*
* For progress spinner, the mode can be either `indeterminate` or `determinate`.
* For progress bar, the mode can be either `determinate`, `indeterminate`, `buffer`, or `query`.
*
* @returns The progress mode
*/
get mode(): ProgressMode {
return this._mode;
}
@Input()
set mode(value: ProgressMode) {
if (this.variant === 'spinner') {
if (value === 'indeterminate' || value === 'determinate') {
this._mode = value;
} else {
this._mode = 'indeterminate';
}
} else {
this._mode = value;
}
}
}

View File

@ -18,6 +18,7 @@
export * from './lib/about/index';
export * from './lib/avatar/avatar.component';
export * from './lib/button/button.component';
export * from './lib/progress/progress.component';
export * from './lib/viewer/index';
export * from './lib/toolbar/index';
export * from './lib/pagination/index';