Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- `six-sidebar-item` : added icon property analog to `six-sidebar-item-group`
- `six-select` : support the use of prefix/suffix slot of the `six-menu-item` to display icons.
- Added support for aria-attributes in JSX typings through upgrade of an underlying library
- When enabled, added automatic `required` flag on input components using `FormControl` and
Comment thread
pennal marked this conversation as resolved.
`Validators.required`. See
[docs](./guide/angular.md#automatic-required-when-using-formcontrol-and-validatorsrequired) for
more details.

### Fixed

Expand Down
51 changes: 51 additions & 0 deletions docs/guide/angular.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,57 @@ This section explains how to configure web-components in an Angular application
@import '@six-group/ui-library/dist/ui-library/ui-library.css';
```

## Configuration

The Angular library provides the ability to customise some of its behaviour when initialising it

### Automatic `required` when using `FormControl` and `Validators.required`

Instead of having to specify the `required` flag property on the component, the flag can be
automatically applied whenever a `FormControl` is used and the `Validators.required` validator is
applied.

So instead of doing:

```
// my-component.component.html
<six-input [formControl]="formControl" [required]="true"></six-input>

// my-component.component.ts
@Component({
...
})
export class MyComponent {
formControl = new FormControl<string>('', Validators.required);
// ...
}
```

when initialising the library pass the `showAsteriskOnRequiredValidator` property like so:

```
UiLibraryAngularModule.forRoot({
showAsteriskOnRequiredValidator: true
})
```

Now your component will apply the required flag automatically, without requiring you to set it
manually:

```
// my-component.component.html
<six-input [formControl]="formControl"></six-input> // <-- [required] prop can be omitted

// my-component.component.ts
@Component({
...
})
export class MyComponent {
formControl = new FormControl<string>('', Validators.required);
// ...
}
```

## Using the Components

The components can be utilized just like any other Angular component. However, there's one caveat:
Expand Down
4 changes: 3 additions & 1 deletion examples/angular/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ import { SettingsComponent } from './pages/settings/settings.component';
RouterModule.forRoot(routes, { useHash: true }),
FormsModule,
ReactiveFormsModule,
UiLibraryAngularModule.forRoot(CustomValidationMessagesService),
UiLibraryAngularModule.forRoot(CustomValidationMessagesService, {
showAsteriskOnRequiredValidator: true,
}),
],
providers: [],
bootstrap: [AppComponent],
Expand Down
1 change: 1 addition & 0 deletions examples/angular/src/app/pages/home/home.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormBuilder, FormControl, Validators } from '@angular/forms';

@Component({
selector: 'app-home',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { AfterViewInit, Directive, ElementRef, HostListener, inject, Injector, OnDestroy } from '@angular/core';
import { AbstractControl, ControlValueAccessor, NgControl } from '@angular/forms';
import { AfterViewInit, Directive, ElementRef, HostListener, Inject, inject, Injector, OnDestroy } from '@angular/core';
import { AbstractControl, ControlValueAccessor, NgControl, Validators } from '@angular/forms';
import { Subscription } from 'rxjs';
import { getLanguage, ValidationError } from '@six-group/ui-library';
import { ValidationMessagesService } from '../services/validation-messages.service';
import { UI_LIBRARY_CONFIG, UiLibraryConfig } from '../ui-library-angular-config';

@Directive()
export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDestroy {
Expand All @@ -11,6 +12,8 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
private initialErrorText?: string;
private validationMessagesService = inject(ValidationMessagesService);

protected config: UiLibraryConfig = inject(UI_LIBRARY_CONFIG);

constructor(
protected injector: Injector,
protected el: ElementRef
Expand Down Expand Up @@ -72,6 +75,11 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
}
element.invalid = invalid;
element.errorText = errorTexts ?? '';

// MARK: Apply configuration passed at init time
Comment thread
pennal marked this conversation as resolved.
Outdated
if (this.config.showAsteriskOnRequiredValidator) {
element.required = this.ngControl.control.hasValidator(Validators.required);
Comment thread
pennal marked this conversation as resolved.
Outdated
}
});
}

Expand Down
11 changes: 11 additions & 0 deletions libraries/ui-library-angular/src/lib/ui-library-angular-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { InjectionToken } from '@angular/core';

export interface UiLibraryConfig {
showAsteriskOnRequiredValidator?: boolean;
Comment thread
pennal marked this conversation as resolved.
Outdated
}

export const DEFAULT_UI_LIBRARY_CONFIG: UiLibraryConfig = {
showAsteriskOnRequiredValidator: false,
};

export const UI_LIBRARY_CONFIG = new InjectionToken<UiLibraryConfig>('UiLibraryConfig');
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
ActiveSidebarItemGroupDirective,
} from './sidebar/active-sidebar.directive';
import { DateValueAccessor } from './control-value-accessors/date-value-accessor';
import { DEFAULT_UI_LIBRARY_CONFIG, UI_LIBRARY_CONFIG, UiLibraryConfig } from './ui-library-angular-config';

@NgModule({
declarations: [
Expand Down Expand Up @@ -111,8 +112,14 @@ import { DateValueAccessor } from './control-value-accessors/date-value-accessor
})
export class UiLibraryAngularModule {
static forRoot<T extends ValidationMessagesService>(
customValidationMessagesService?: Type<T>
customValidationMessagesService?: Type<T>,
config?: UiLibraryConfig
): ModuleWithProviders<UiLibraryAngularModule> {
const mergedConfig: UiLibraryConfig = {
...DEFAULT_UI_LIBRARY_CONFIG,
...config,
};

return {
ngModule: UiLibraryAngularModule,
providers: [
Expand All @@ -122,6 +129,7 @@ export class UiLibraryAngularModule {
multi: true,
},
{ provide: ValidationMessagesService, useClass: customValidationMessagesService ?? ValidationMessagesService },
{ provide: UI_LIBRARY_CONFIG, useValue: mergedConfig },
],
};
}
Expand Down