diff --git a/.eslintrc-overrides.json b/.eslintrc-overrides.json index 897244ae8d..760848e394 100644 --- a/.eslintrc-overrides.json +++ b/.eslintrc-overrides.json @@ -47,9 +47,11 @@ "@angular-eslint/template/interactive-supports-focus": ["warn"], "@angular-eslint/template/label-has-associated-control": ["warn"], "@angular-eslint/template/no-any": ["error"], - "@angular-eslint/template/no-call-expression": ["warn"], "@angular-eslint/template/no-distracting-elements": ["warn"], - "@angular-eslint/template/no-inline-styles": ["warn"], + "@angular-eslint/template/no-inline-styles": [ + "warn", + { "allowBindToStyle": true, "allowNgStyle": true } + ], "@angular-eslint/template/no-interpolation-in-attributes": ["warn"], "@angular-eslint/template/no-positive-tabindex": ["warn"], "@angular-eslint/template/prefer-control-flow": ["warn"], diff --git a/apps/code-examples/src/app/code-examples/popovers/popover/basic/demo.component.html b/apps/code-examples/src/app/code-examples/popovers/popover/basic/demo.component.html index 9d0678350f..f05093a97e 100644 --- a/apps/code-examples/src/app/code-examples/popovers/popover/basic/demo.component.html +++ b/apps/code-examples/src/app/code-examples/popovers/popover/basic/demo.component.html @@ -1,27 +1,14 @@ - - - + {{ popoverBody }} diff --git a/libs/components/ag-grid/src/lib/modules/ag-grid/cell-validator/ag-grid-cell-validator-tooltip.component.html b/libs/components/ag-grid/src/lib/modules/ag-grid/cell-validator/ag-grid-cell-validator-tooltip.component.html index e5f03341aa..d56ac0e672 100644 --- a/libs/components/ag-grid/src/lib/modules/ag-grid/cell-validator/ag-grid-cell-validator-tooltip.component.html +++ b/libs/components/ag-grid/src/lib/modules/ag-grid/cell-validator/ag-grid-cell-validator-tooltip.component.html @@ -1,4 +1,5 @@
{ }); const helpSvc = TestBed.inject(SkyHelpService); const helpSpy = spyOn(helpSvc, 'openHelp'); + fixture.componentInstance.helpKey = 'helpKey.html'; fixture.componentInstance.helpPopoverContent = undefined; fixture.detectChanges(); diff --git a/libs/components/forms/testing/src/checkbox/fixtures/checkbox-harness-test.component.html b/libs/components/forms/testing/src/checkbox/fixtures/checkbox-harness-test.component.html index 4e73af1d6d..7beee2d7ce 100644 --- a/libs/components/forms/testing/src/checkbox/fixtures/checkbox-harness-test.component.html +++ b/libs/components/forms/testing/src/checkbox/fixtures/checkbox-harness-test.component.html @@ -29,7 +29,7 @@ [labelHidden]="hidePhoneLabel" data-sky-id="my-phone-checkbox" formControlName="phone" - helpKey="helpKey.html" + [helpKey]="helpKey" helpPopoverContent="(xxx)xxx-xxxx" helpPopoverTitle="Format" labelText="Phone" diff --git a/libs/components/forms/testing/src/field-group/field-group-harness.spec.ts b/libs/components/forms/testing/src/field-group/field-group-harness.spec.ts index 609bf08fd8..9d85e45bed 100644 --- a/libs/components/forms/testing/src/field-group/field-group-harness.spec.ts +++ b/libs/components/forms/testing/src/field-group/field-group-harness.spec.ts @@ -155,6 +155,8 @@ describe('Field group harness', () => { const helpSvc = TestBed.inject(SkyHelpService); const helpSpy = spyOn(helpSvc, 'openHelp'); + fixture.componentInstance.helpKey = 'helpKey.html'; + await fieldGroupHarness.clickHelpInline(); fixture.detectChanges(); await fixture.whenStable(); diff --git a/libs/components/forms/testing/src/field-group/fixtures/field-group.component.fixture.ts b/libs/components/forms/testing/src/field-group/fixtures/field-group.component.fixture.ts index db6afcefac..1e7b5a63a1 100644 --- a/libs/components/forms/testing/src/field-group/fixtures/field-group.component.fixture.ts +++ b/libs/components/forms/testing/src/field-group/fixtures/field-group.component.fixture.ts @@ -32,7 +32,7 @@ export class FieldGroupComponent { public headingHidden = false; public headingLevel: SkyFieldGroupHeadingLevel = 3; public headingStyle: SkyFieldGroupHeadingStyle = 3; - public helpKey: string | undefined = 'helpKey.html'; + public helpKey: string | undefined; public helpPopoverContent: string | undefined = 'Popover content'; public helpPopoverTitle = 'Popover title'; diff --git a/libs/components/forms/testing/src/input-box/fixtures/input-box-harness-test.component.ts b/libs/components/forms/testing/src/input-box/fixtures/input-box-harness-test.component.ts index 2ccb14552c..1b2aefaafb 100644 --- a/libs/components/forms/testing/src/input-box/fixtures/input-box-harness-test.component.ts +++ b/libs/components/forms/testing/src/input-box/fixtures/input-box-harness-test.component.ts @@ -21,7 +21,7 @@ export class InputBoxHarnessTestComponent { public easyModeDisabled = false; public easyModeHelpContent: string | TemplateRef | undefined = 'Help content'; - public easyModeHelpKey: string | undefined = 'helpKey.html'; + public easyModeHelpKey: string | undefined; public easyModeHelpTitle = 'Help title'; public easyModeLabel: string | undefined = 'Last name (easy mode)'; public easyModeStacked = false; diff --git a/libs/components/forms/testing/src/input-box/input-box-harness.spec.ts b/libs/components/forms/testing/src/input-box/input-box-harness.spec.ts index 89c76e06c4..474b518d23 100644 --- a/libs/components/forms/testing/src/input-box/input-box-harness.spec.ts +++ b/libs/components/forms/testing/src/input-box/input-box-harness.spec.ts @@ -144,11 +144,13 @@ describe('Input box harness', () => { ); }); - it('should open help popover and widget when clicked', async () => { + it('should open widget when clicked', async () => { const { fixture, inputBoxHarness } = await setupTest({ dataSkyId: DATA_SKY_ID_EASY_MODE, }); + fixture.componentInstance.easyModeHelpKey = 'helpKey.html'; + const helpSvc = TestBed.inject(SkyHelpService); const helpSpy = spyOn(helpSvc, 'openHelp'); @@ -156,7 +158,6 @@ describe('Input box harness', () => { fixture.detectChanges(); await fixture.whenStable(); - await expectAsync(inputBoxHarness.getHelpPopoverContent()).toBeResolved(); expect(helpSpy).toHaveBeenCalledWith({ helpKey: 'helpKey.html' }); }); diff --git a/libs/components/help-inline/src/lib/modules/help-inline/aria-label.pipe.ts b/libs/components/help-inline/src/lib/modules/help-inline/aria-label.pipe.ts new file mode 100644 index 0000000000..5a8d27b66c --- /dev/null +++ b/libs/components/help-inline/src/lib/modules/help-inline/aria-label.pipe.ts @@ -0,0 +1,32 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +/** + * Sets the value of `aria-label` for inline help buttons. + * @internal + */ +@Pipe({ + name: 'skyHelpInlineAriaLabel', + standalone: true, +}) +export class SkyHelpInlineAriaLabelPipe implements PipeTransform { + public transform( + ariaLabel: string | undefined, + labelText: string | undefined, + labelledBy: string | undefined, + defaultAriaLabel: string | undefined, + ): string | undefined { + if (labelledBy) { + return; + } + + if (labelText) { + return labelText; + } + + if (ariaLabel) { + return ariaLabel; + } + + return defaultAriaLabel; + } +} diff --git a/libs/components/help-inline/src/lib/modules/help-inline/button-help-key.component.ts b/libs/components/help-inline/src/lib/modules/help-inline/button-help-key.component.ts new file mode 100644 index 0000000000..cf0a32676c --- /dev/null +++ b/libs/components/help-inline/src/lib/modules/help-inline/button-help-key.component.ts @@ -0,0 +1,63 @@ +import { CommonModule } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + inject, + input, + output, +} from '@angular/core'; +import { SKY_HELP_GLOBAL_OPTIONS, SkyHelpService } from '@skyux/core'; + +/** + * @internal + */ +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule], + selector: 'sky-help-inline-help-key-button', + standalone: true, + styleUrls: [ + './help-inline.default.component.scss', + './help-inline.modern.component.scss', + ], + template: ` + + `, +}) +export class SkyHelpInlineHelpKeyButtonComponent { + public actionClick = output(); + public ariaLabel = input(); + public ariaLabelledby = input(); + public helpKey = input.required(); + + protected readonly globalOptions = inject(SKY_HELP_GLOBAL_OPTIONS, { + optional: true, + }); + + protected readonly helpSvc = inject(SkyHelpService, { optional: true }); + + protected openHelpKey(): void { + this.actionClick.emit(); + + this.helpSvc?.openHelp({ + helpKey: this.helpKey(), + }); + } +} diff --git a/libs/components/help-inline/src/lib/modules/help-inline/button-popover.component.ts b/libs/components/help-inline/src/lib/modules/help-inline/button-popover.component.ts new file mode 100644 index 0000000000..7f69048438 --- /dev/null +++ b/libs/components/help-inline/src/lib/modules/help-inline/button-popover.component.ts @@ -0,0 +1,61 @@ +import { CommonModule } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + TemplateRef, + computed, + input, + output, +} from '@angular/core'; +import { SkyPopoverModule } from '@skyux/popovers'; + +/** + * @internal + */ +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule, SkyPopoverModule], + selector: 'sky-help-inline-popover-button', + standalone: true, + styleUrls: [ + './help-inline.default.component.scss', + './help-inline.modern.component.scss', + ], + template: ` + + + @if (popoverTemplate(); as template) { + + } @else { +

{{ popoverContent() }}

+ } +
+ `, +}) +export class SkyHelpInlinePopoverButtonComponent { + public actionClick = output(); + public ariaControls = input(); + public ariaLabel = input(); + public ariaLabelledby = input(); + public popoverContent = input.required>(); + public popoverTitle = input(); + + protected popoverTemplate = computed(() => { + const value = this.popoverContent(); + + if (value instanceof TemplateRef) { + return value; + } + + return undefined; + }); +} diff --git a/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-controls.pipe.ts b/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-controls.pipe.ts deleted file mode 100644 index e191019af6..0000000000 --- a/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-controls.pipe.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Pipe, PipeTransform, inject } from '@angular/core'; -import { SKY_HELP_GLOBAL_OPTIONS } from '@skyux/core'; - -/** - * @internal - */ -@Pipe({ - name: 'skyHelpInlineAriaControls', - standalone: true, -}) -export class SkyHelpInlineAriaControlsPipe implements PipeTransform { - readonly #helpGlobalOptions = inject(SKY_HELP_GLOBAL_OPTIONS, { - optional: true, - }); - - public transform( - ariaControls: string | undefined, - popoverId: string | undefined, - helpKey: string | undefined, - widgetReadyState: boolean | null, - ): string | undefined { - if (helpKey) { - if (!widgetReadyState) { - return; - } - - if (this.#helpGlobalOptions) { - return this.#helpGlobalOptions.ariaControls; - } - } - - return popoverId || ariaControls; - } -} diff --git a/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-expanded.pipe.ts b/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-expanded.pipe.ts deleted file mode 100644 index 8925370316..0000000000 --- a/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-expanded.pipe.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core'; - -/** - * @internal - */ -@Pipe({ - name: 'skyHelpInlineAriaExpanded', - standalone: true, -}) -export class SkyHelpInlineAriaExpandedPipe implements PipeTransform { - public transform( - ariaExpanded: boolean | undefined, - ariaControls: string | undefined, - isPopoverOpened: boolean | undefined, - ): boolean | null { - return isPopoverOpened ?? (ariaControls ? !!ariaExpanded : null); - } -} diff --git a/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-haspopup.pipe.ts b/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-haspopup.pipe.ts deleted file mode 100644 index b9fc46465c..0000000000 --- a/libs/components/help-inline/src/lib/modules/help-inline/help-inline-aria-haspopup.pipe.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Pipe, PipeTransform, inject } from '@angular/core'; -import { SKY_HELP_GLOBAL_OPTIONS } from '@skyux/core'; - -/** - * @internal - */ -@Pipe({ - name: 'skyHelpInlineAriaHaspopup', - standalone: true, -}) -export class SkyHelpInlineAriaHaspopupPipe implements PipeTransform { - readonly #helpGlobalOptions = inject(SKY_HELP_GLOBAL_OPTIONS, { - optional: true, - }); - - public transform(helpKey: string | undefined): string | undefined { - if (helpKey) { - return this.#helpGlobalOptions?.ariaHaspopup; - } - - return undefined; - } -} diff --git a/libs/components/help-inline/src/lib/modules/help-inline/help-inline.component.html b/libs/components/help-inline/src/lib/modules/help-inline/help-inline.component.html index d5809a3ad3..539810c9e5 100644 --- a/libs/components/help-inline/src/lib/modules/help-inline/help-inline.component.html +++ b/libs/components/help-inline/src/lib/modules/help-inline/help-inline.component.html @@ -1,35 +1,61 @@ - +} + + - - - - @if (popoverTemplate) { - - } @else { -

{{ popoverContent }}

- } -
+
-