Skip to content

Commit

Permalink
Merge branch 'main' into update-axe-core
Browse files Browse the repository at this point in the history
  • Loading branch information
johnhwhite authored Feb 6, 2024
2 parents 4a0ec9a + 55eca8b commit e60aa38
Show file tree
Hide file tree
Showing 45 changed files with 1,327 additions and 521 deletions.
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
# Changelog

## [9.23.0](https://github.com/blackbaud/skyux/compare/9.22.0...9.23.0) (2024-02-05)


### Features

* **components/colorpicker:** add labelText input ([#1968](https://github.com/blackbaud/skyux/issues/1968)) ([f19cb29](https://github.com/blackbaud/skyux/commit/f19cb29d0735177c6939e7a854bd4097d5a71d4b))
* **components/tabs:** add keyboard navigation to vertical tabset ([#1978](https://github.com/blackbaud/skyux/issues/1978)) ([f0ce7d4](https://github.com/blackbaud/skyux/commit/f0ce7d4a4fe1f008239da6ddb0257b0bda67b47d))


### Bug Fixes

* **components/forms:** refactor form errors ([#1981](https://github.com/blackbaud/skyux/issues/1981)) ([f9f0391](https://github.com/blackbaud/skyux/commit/f9f0391411f7c2b70e8a18050b3e8533f0381d3b))

## [10.0.0-alpha.1](https://github.com/blackbaud/skyux/compare/10.0.0-alpha.0...10.0.0-alpha.1) (2024-02-02)


### Features

* **components/autonumeric:** update `autonumeric` to `4.10.4` ([#1974](https://github.com/blackbaud/skyux/issues/1974)) ([06afbcf](https://github.com/blackbaud/skyux/commit/06afbcf120732db11688799ccb930d397b77d8f3))
* **components/colorpicker:** add labelText input ([#1968](https://github.com/blackbaud/skyux/issues/1968)) ([#1979](https://github.com/blackbaud/skyux/issues/1979)) ([f27b176](https://github.com/blackbaud/skyux/commit/f27b176969b6960e681d28dfffe97f1d9ab9178f))
* **components/datetime:** update `moment` to `2.30.1` ([#1975](https://github.com/blackbaud/skyux/issues/1975)) ([5fe13c8](https://github.com/blackbaud/skyux/commit/5fe13c881f2e6e64f9e823d52ebed604d57222ed))
* **components/forms:** add checkbox labelText input ([#1965](https://github.com/blackbaud/skyux/issues/1965)) ([#1966](https://github.com/blackbaud/skyux/issues/1966)) ([44b6f31](https://github.com/blackbaud/skyux/commit/44b6f3152e4681aba1a67cd8b6114a152888234b))
* **components/text-editor:** update `dompurify` to `3.0.8` ([#1973](https://github.com/blackbaud/skyux/issues/1973)) ([81ff0bc](https://github.com/blackbaud/skyux/commit/81ff0bc67ee55a56b034bb3b4f41422ed2d91152))


### Bug Fixes

* **components/packages:** standardize how schematics visit project files ([#1967](https://github.com/blackbaud/skyux/issues/1967)) ([#1970](https://github.com/blackbaud/skyux/issues/1970)) ([24d9190](https://github.com/blackbaud/skyux/commit/24d91903f34c5b83f107fbc454d071880be0849d))
* **sdk/eslint-config:** downgrade `package-json` to `7.0.0` since it only works with ES modules ([#1985](https://github.com/blackbaud/skyux/issues/1985)) ([8b25942](https://github.com/blackbaud/skyux/commit/8b25942d1774d1f089ee5774f748c464facddb0d))

## [9.22.0](https://github.com/blackbaud/skyux/compare/9.21.3...9.22.0) (2024-01-29)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,17 @@ <h2>New member form</h2>
</sky-input-box>
</sky-column>
<sky-column [screenSmall]="12" [screenMedium]="6">
<sky-input-box labelText="Last name" stacked="true">
<input formControlName="lastName" spellcheck="false" type="text" />
<sky-input-box
data-sky-id="input-box-last-name"
labelText="Last name"
stacked="true"
>
<input
class="last-name-input-box"
formControlName="lastName"
spellcheck="false"
type="text"
/>
</sky-input-box>
</sky-column>
</sky-row>
Expand Down Expand Up @@ -69,18 +78,14 @@ <h2>New member form</h2>
<option value="green">Green</option>
<option value="blue">Blue</option>
<option value="purple">Purple</option>
<option value="bird">Bird</option>
<option value="invalid">Invalid Color</option>
</select>
<!-- Custom validator not handled by input box. -->
<div class="sky-error-indicator">
<sky-status-indicator
*ngIf="favoriteColor.errors?.['color'] as colorError"
descriptionType="error"
indicatorType="danger"
>
{{ colorError.message }}
</sky-status-indicator>
</div>
<!-- Custom form error not handled by input box. -->
<sky-form-error
*ngIf="favoriteColor.errors?.['invalid']"
errorName="invalid"
errorText="Invalid Color is not a color"
/>
</sky-input-box>
</sky-column>
</sky-row>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { SkyAppTestUtility } from '@skyux-sdk/testing';
import { SkyInputBoxHarness } from '@skyux/forms/testing';

import { DemoComponent } from './demo.component';
Expand Down Expand Up @@ -40,6 +41,22 @@ describe('Basic input box demo', () => {
});
});

describe('last name field', () => {
it('should have last name required', async () => {
const harness = await setupTest({
dataSkyId: 'input-box-last-name',
});
const inputEl = document.querySelector(
'input.last-name-input-box',
) as HTMLInputElement;
inputEl.value = '';
SkyAppTestUtility.fireDomEvent(inputEl, 'input');
SkyAppTestUtility.fireDomEvent(inputEl, 'blur');

await expectAsync(harness.hasRequiredError()).toBeResolvedTo(true);
});
});

describe('bio field', () => {
it('should have a character limit of 250', async () => {
const harness = await setupTest({
Expand Down Expand Up @@ -71,7 +88,7 @@ describe('Basic input box demo', () => {
});

describe('favorite color field', () => {
it('should not allow bird to be selected', async () => {
it('should not allow invalid color to be selected', async () => {
const harness = await setupTest({
dataSkyId: 'input-box-favorite-color',
});
Expand All @@ -80,19 +97,11 @@ describe('Basic input box demo', () => {
'.input-box-favorite-color-select',
) as HTMLSelectElement;

selectEl.value = 'bird';
selectEl.value = 'invalid';
selectEl.dispatchEvent(new Event('change'));

const customErrors = await harness.getCustomErrors();

expect(customErrors.length).toBe(1);

const birdError = customErrors[0];

await expectAsync(birdError.getDescriptionType()).toBeResolvedTo('error');
await expectAsync(birdError.getIndicatorType()).toBeResolvedTo('danger');
await expectAsync(birdError.getText()).toBeResolvedTo(
'Bird is not a color.',
await expectAsync(harness.hasCustomFormError('invalid')).toBeResolvedTo(
true,
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,8 @@ export class DemoComponent {
constructor() {
this.favoriteColor = new FormControl('none', [
(control): ValidationErrors | null => {
if (control.value === 'bird') {
return {
color: {
invalid: true,
message: 'Bird is not a color.',
},
};
if (control.value === 'invalid') {
return { invalid: true };
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,18 @@

<div id="input-box-form-control-name-error">
<form [formGroup]="errorForm">
<sky-input-box
labelText="Custom error easy mode"
stacked="true"
hintText="type in blue"
>
<input formControlName="customError" type="text" />
<sky-form-error
*ngIf="customError.errors?.['blue']"
errorName="blue"
errorText="Input must be blue."
/>
</sky-input-box>
<sky-input-box
mode="detect"
labelText="Form control by name error with status indicator"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
NgModel,
UntypedFormControl,
UntypedFormGroup,
ValidationErrors,
Validators,
} from '@angular/forms';

Expand All @@ -16,6 +17,8 @@ export class InputBoxComponent implements OnInit, AfterViewInit {

public errorField: UntypedFormControl;

public customError: UntypedFormControl;

public errorForm: UntypedFormGroup;

public errorNgModelValue: string;
Expand All @@ -28,10 +31,23 @@ export class InputBoxComponent implements OnInit, AfterViewInit {
public ngOnInit(): void {
this.errorField = new UntypedFormControl('', [Validators.required]);

this.customError = new UntypedFormControl('', [
(control): ValidationErrors | null => {
console.log(control.value);
if (control.value !== 'blue') {
return { blue: true };
}
return null;
},
Validators.required,
Validators.maxLength(1),
]);

this.errorField.markAsTouched();

this.errorForm = new UntypedFormGroup({
errorFormField: new UntypedFormControl('', [Validators.required]),
customError: this.customError,
});
this.errorAutofillForm = new UntypedFormGroup({
errorAutofillFormField: new UntypedFormControl('', [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ <h2>Vertical tabset</h2>
Group 3 Tab 2 content
</sky-vertical-tab>
</sky-vertical-tabset-group>
<sky-vertical-tab tabHeading="Ungrouped Tab" tabHeaderCount="2">
Ungrouped tab content
</sky-vertical-tab>
</sky-vertical-tabset>
</div>

Expand Down
4 changes: 4 additions & 0 deletions libs/components/forms/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { SkyCheckboxChange } from './lib/modules/checkbox/checkbox-change';
export { SkyCheckboxModule } from './lib/modules/checkbox/checkbox.module';

export { SkyFormErrorsModule } from './lib/modules/form-error/form-errors.module';
export { SkyFormErrorModule } from './lib/modules/form-error/form-error.module';

export { SkyFileAttachmentsModule } from './lib/modules/file-attachment/file-attachments.module';
export { SkyFileItem } from './lib/modules/file-attachment/file-item';
Expand All @@ -29,6 +30,8 @@ export { SkySelectionBoxGridAlignItemsType } from './lib/modules/selection-box/t
export { SkyToggleSwitchModule } from './lib/modules/toggle-switch/toggle-switch.module';
export { SkyToggleSwitchChange } from './lib/modules/toggle-switch/types/toggle-switch-change';

export { SKY_FORM_ERRORS_ENABLED } from './lib/modules/form-error/form-errors-enabled-token';

// Components and directives must be exported to support Angular's "partial" Ivy compiler.
// Obscure names are used to indicate types are not part of the public API.

Expand All @@ -41,6 +44,7 @@ export { SkyFileAttachmentComponent as λ7 } from './lib/modules/file-attachment
export { SkyFileDropComponent as λ8 } from './lib/modules/file-attachment/file-drop.component';
export { SkyFileItemComponent as λ9 } from './lib/modules/file-attachment/file-item.component';
export { SkyFormErrorsComponent as λ21 } from './lib/modules/form-error/form-errors.component';
export { SkyFormErrorComponent as λ22 } from './lib/modules/form-error/form-error.component';
export { SkyInputBoxControlDirective as λ20 } from './lib/modules/input-box/input-box-control.directive';
export { SkyInputBoxComponent as λ10 } from './lib/modules/input-box/input-box.component';
export { SkyRadioGroupComponent as λ11 } from './lib/modules/radio/radio-group.component';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Component } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { expect } from '@skyux-sdk/testing';

import { SkyFormErrorModule } from './form-error.module';
import { SKY_FORM_ERRORS_ENABLED } from './form-errors-enabled-token';
import { SkyFormErrorsModule } from './form-errors.module';

@Component({
standalone: true,
imports: [SkyFormErrorsModule, SkyFormErrorModule],
providers: [{ provide: SKY_FORM_ERRORS_ENABLED, useValue: true }],
template: `
<sky-form-error errorName="required" errorText="This field is required" />
`,
})
class FormErrorWithTokenComponent {}

@Component({
standalone: true,
imports: [SkyFormErrorsModule, SkyFormErrorModule],
template: `
<sky-form-error errorName="required" errorText="This field is required" />
`,
})
class FormErrorWithoutTokenComponent {}

describe('Form error component', () => {
it('renders an error message when form errors enabled token is provided', () => {
const fixture = TestBed.createComponent(FormErrorWithTokenComponent);

fixture.detectChanges();

expect(
fixture.nativeElement.querySelector('.sky-form-error'),
).toBeVisible();
});

it('throws an error when form errors enabled token is not provided', () => {
expect(() =>
TestBed.createComponent(FormErrorWithoutTokenComponent),
).toThrowError(
'The `sky-form-error` component is not supported in the provided context.',
);
});
});
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import { ChangeDetectionStrategy, Component, HostBinding } from '@angular/core';
import { CommonModule } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
Input,
inject,
} from '@angular/core';
import { SkyStatusIndicatorModule } from '@skyux/indicators';

import { SKY_FORM_ERRORS_ENABLED } from './form-errors-enabled-token';

/**
* @internal
* Displays default and custom input error messages for SKY UX form components.
*/
@Component({
selector: 'sky-form-error',
standalone: true,
imports: [SkyStatusIndicatorModule],
imports: [SkyStatusIndicatorModule, CommonModule],
template: `
<sky-status-indicator
*ngIf="formErrors"
class="sky-form-error"
descriptionType="error"
indicatorType="danger"
>
<ng-content />
{{ errorText }}
</sky-status-indicator>
`,
styles: [
Expand All @@ -28,6 +37,27 @@ import { SkyStatusIndicatorModule } from '@skyux/indicators';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SkyFormErrorComponent {
@HostBinding('class')
protected readonly cssClass = 'sky-form-error-indicator';
/**
* The name of the error.
*/
@Input({ required: true })
public errorName!: string;

/**
* The error message to display.
*/
@Input({ required: true })
public errorText!: string;

protected readonly formErrors = inject(SKY_FORM_ERRORS_ENABLED, {
optional: true,
});

constructor() {
if (!this.formErrors) {
throw new Error(
'The `sky-form-error` component is not supported in the provided context.',
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NgModule } from '@angular/core';

import { SkyFormErrorComponent } from './form-error.component';

@NgModule({
imports: [SkyFormErrorComponent],
exports: [SkyFormErrorComponent],
})
export class SkyFormErrorModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { InjectionToken } from '@angular/core';

/**
* @internal
*/
export const SKY_FORM_ERRORS_ENABLED = new InjectionToken<boolean>(
'SKY_FORM_ERRORS_ENABLED',
);
Loading

0 comments on commit e60aa38

Please sign in to comment.