@hmcts/opal-frontend-common 0.0.110 → 0.0.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-skip-link.mjs +61 -0
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-sortable-table.mjs +2 -2
- package/fesm2022/hmcts-opal-frontend-common-directives-capitalisation.mjs +26 -6
- package/fesm2022/hmcts-opal-frontend-common-services-utils-service.mjs +10 -8
- package/package.json +6 -1
- package/types/hmcts-opal-frontend-common-components-govuk-govuk-skip-link.d.ts +20 -0
- package/types/hmcts-opal-frontend-common-directives-capitalisation.d.ts +16 -0
- package/types/hmcts-opal-frontend-common-services-utils-service.d.ts +8 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { DOCUMENT } from "@angular/common";
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import { ChangeDetectionStrategy, Component, Input, inject } from "@angular/core";
|
|
4
|
+
import { UtilsService } from "@hmcts/opal-frontend-common/services/utils-service";
|
|
5
|
+
var GovukSkipLinkComponent = class GovukSkipLinkComponent {
|
|
6
|
+
document = inject(DOCUMENT);
|
|
7
|
+
utilsService = inject(UtilsService);
|
|
8
|
+
targetId = "main-content";
|
|
9
|
+
linkText = "Skip to main content";
|
|
10
|
+
get href() {
|
|
11
|
+
return `${this.document.location?.pathname ?? ""}#${this.targetId}`;
|
|
12
|
+
}
|
|
13
|
+
onSkipLink(event) {
|
|
14
|
+
event.preventDefault();
|
|
15
|
+
this.utilsService.focusElementById(this.targetId);
|
|
16
|
+
}
|
|
17
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
18
|
+
minVersion: "12.0.0",
|
|
19
|
+
version: "21.2.25",
|
|
20
|
+
ngImport: i0,
|
|
21
|
+
type: GovukSkipLinkComponent,
|
|
22
|
+
deps: [],
|
|
23
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
24
|
+
});
|
|
25
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
26
|
+
minVersion: "14.0.0",
|
|
27
|
+
version: "21.2.25",
|
|
28
|
+
type: GovukSkipLinkComponent,
|
|
29
|
+
isStandalone: true,
|
|
30
|
+
selector: "opal-lib-govuk-skip-link",
|
|
31
|
+
inputs: {
|
|
32
|
+
targetId: "targetId",
|
|
33
|
+
linkText: "linkText"
|
|
34
|
+
},
|
|
35
|
+
ngImport: i0,
|
|
36
|
+
template: "<a class=\"govuk-skip-link\" [href]=\"href\" data-module=\"govuk-skip-link\" (click)=\"onSkipLink($event)\">{{ linkText }}</a>\n",
|
|
37
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
41
|
+
minVersion: "12.0.0",
|
|
42
|
+
version: "21.2.25",
|
|
43
|
+
ngImport: i0,
|
|
44
|
+
type: GovukSkipLinkComponent,
|
|
45
|
+
decorators: [{
|
|
46
|
+
type: Component,
|
|
47
|
+
args: [{
|
|
48
|
+
selector: "opal-lib-govuk-skip-link",
|
|
49
|
+
imports: [],
|
|
50
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
51
|
+
template: "<a class=\"govuk-skip-link\" [href]=\"href\" data-module=\"govuk-skip-link\" (click)=\"onSkipLink($event)\">{{ linkText }}</a>\n"
|
|
52
|
+
}]
|
|
53
|
+
}],
|
|
54
|
+
propDecorators: {
|
|
55
|
+
targetId: [{ type: Input }],
|
|
56
|
+
linkText: [{ type: Input }]
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
export { GovukSkipLinkComponent };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=hmcts-opal-frontend-common-components-govuk-govuk-skip-link.mjs.map
|
|
@@ -331,7 +331,7 @@ var MojSortableTableComponent = class MojSortableTableComponent {
|
|
|
331
331
|
selector: "opal-lib-moj-sortable-table",
|
|
332
332
|
inputs: { tableClasses: "tableClasses" },
|
|
333
333
|
ngImport: i0,
|
|
334
|
-
template: "<table class=\"govuk-table {{ tableClasses }}\" data-module=\"moj-sortable-table\">\n <caption class=\"govuk-table__caption\">\n <ng-content select=\"[caption]\"
|
|
334
|
+
template: "<table class=\"govuk-table {{ tableClasses }}\" data-module=\"moj-sortable-table\">\n <caption class=\"govuk-table__caption\">\n <ng-content select=\"[caption]\">\n <span class=\"govuk-visually-hidden\">Column headers with buttons are sortable</span>\n </ng-content>\n </caption>\n <thead class=\"govuk-table__head\">\n <tr class=\"govuk-table__row\">\n <ng-content select=\"[head]\"></ng-content>\n </tr>\n </thead>\n <tbody class=\"govuk-table__body\">\n <ng-content select=\"[row]\"></ng-content>\n <ng-content select=\"[results]\"></ng-content>\n </tbody>\n</table>\n<ng-content select=\"[status]\"></ng-content>\n",
|
|
335
335
|
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
336
336
|
});
|
|
337
337
|
};
|
|
@@ -345,7 +345,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
345
345
|
args: [{
|
|
346
346
|
selector: "opal-lib-moj-sortable-table",
|
|
347
347
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
348
|
-
template: "<table class=\"govuk-table {{ tableClasses }}\" data-module=\"moj-sortable-table\">\n <caption class=\"govuk-table__caption\">\n <ng-content select=\"[caption]\"
|
|
348
|
+
template: "<table class=\"govuk-table {{ tableClasses }}\" data-module=\"moj-sortable-table\">\n <caption class=\"govuk-table__caption\">\n <ng-content select=\"[caption]\">\n <span class=\"govuk-visually-hidden\">Column headers with buttons are sortable</span>\n </ng-content>\n </caption>\n <thead class=\"govuk-table__head\">\n <tr class=\"govuk-table__row\">\n <ng-content select=\"[head]\"></ng-content>\n </tr>\n </thead>\n <tbody class=\"govuk-table__body\">\n <ng-content select=\"[row]\"></ng-content>\n <ng-content select=\"[results]\"></ng-content>\n </tbody>\n</table>\n<ng-content select=\"[status]\"></ng-content>\n"
|
|
349
349
|
}]
|
|
350
350
|
}],
|
|
351
351
|
propDecorators: { tableClasses: [{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DOCUMENT } from "@angular/common";
|
|
1
2
|
import * as i0 from "@angular/core";
|
|
2
3
|
import { Directive, Input, inject } from "@angular/core";
|
|
3
4
|
import { Subject, takeUntil } from "rxjs";
|
|
@@ -5,15 +6,34 @@ import { UtilsService } from "@hmcts/opal-frontend-common/services/utils-service
|
|
|
5
6
|
var CapitalisationDirective = class CapitalisationDirective {
|
|
6
7
|
destroy$ = new Subject();
|
|
7
8
|
utilsService = inject(UtilsService);
|
|
9
|
+
document = inject(DOCUMENT);
|
|
8
10
|
control;
|
|
11
|
+
captureSelection(value) {
|
|
12
|
+
const activeElement = this.document.activeElement;
|
|
13
|
+
if (activeElement?.tagName !== "INPUT" && activeElement?.tagName !== "TEXTAREA") return null;
|
|
14
|
+
const input = activeElement;
|
|
15
|
+
const { selectionStart, selectionEnd, selectionDirection } = input;
|
|
16
|
+
if (input.value !== value || typeof selectionStart !== "number" || typeof selectionEnd !== "number") return null;
|
|
17
|
+
return {
|
|
18
|
+
input,
|
|
19
|
+
start: this.utilsService.upperCaseAllLetters(value.slice(0, selectionStart)).length,
|
|
20
|
+
end: this.utilsService.upperCaseAllLetters(value.slice(0, selectionEnd)).length,
|
|
21
|
+
direction: selectionDirection ?? "none"
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
capitaliseControlValue(value) {
|
|
25
|
+
if (typeof value === "string" && value.length > 0) {
|
|
26
|
+
const upper = this.utilsService.upperCaseAllLetters(value);
|
|
27
|
+
if (value !== upper) {
|
|
28
|
+
const selection = this.captureSelection(value);
|
|
29
|
+
this.control.setValue(upper, { emitEvent: false });
|
|
30
|
+
if (selection?.input === this.document.activeElement && selection.input.value === upper) selection.input.setSelectionRange(selection.start, selection.end, selection.direction);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
9
34
|
ngOnInit() {
|
|
10
35
|
if (!this.control) return;
|
|
11
|
-
this.control.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((value) =>
|
|
12
|
-
if (typeof value === "string" && value.length > 0) {
|
|
13
|
-
const upper = this.utilsService.upperCaseAllLetters(value);
|
|
14
|
-
if (value !== upper) this.control.setValue(upper, { emitEvent: false });
|
|
15
|
-
}
|
|
16
|
-
});
|
|
36
|
+
this.control.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((value) => this.capitaliseControlValue(value));
|
|
17
37
|
}
|
|
18
38
|
ngOnDestroy() {
|
|
19
39
|
this.destroy$.next();
|
|
@@ -30,15 +30,17 @@ var UtilsService = class UtilsService {
|
|
|
30
30
|
scrollToTop() {
|
|
31
31
|
this.viewportScroller.scrollToPosition([0, 0]);
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
mainContent.focus({ preventScroll: true });
|
|
33
|
+
focusElementById(elementId, options) {
|
|
34
|
+
const element = this.document.getElementById(elementId);
|
|
35
|
+
if (!element) return;
|
|
36
|
+
if (!element.hasAttribute("tabindex")) {
|
|
37
|
+
element.setAttribute("tabindex", "-1");
|
|
38
|
+
element.addEventListener("blur", () => element.removeAttribute("tabindex"), { once: true });
|
|
41
39
|
}
|
|
40
|
+
element.focus(options);
|
|
41
|
+
}
|
|
42
|
+
focusAndScrollToTop() {
|
|
43
|
+
this.focusElementById("main-content", { preventScroll: true });
|
|
42
44
|
this.scrollToTop();
|
|
43
45
|
}
|
|
44
46
|
checkFormValues(form) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hmcts/opal-frontend-common",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.112",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -416,6 +416,11 @@
|
|
|
416
416
|
"types": "./types/hmcts-opal-frontend-common-components-govuk-govuk-select-interfaces.d.ts",
|
|
417
417
|
"default": "./fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-select-interfaces.mjs"
|
|
418
418
|
},
|
|
419
|
+
"./components/govuk/govuk-skip-link": {
|
|
420
|
+
"import": "./fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-skip-link.mjs",
|
|
421
|
+
"types": "./types/hmcts-opal-frontend-common-components-govuk-govuk-skip-link.d.ts",
|
|
422
|
+
"default": "./fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-skip-link.mjs"
|
|
423
|
+
},
|
|
419
424
|
"./components/govuk/govuk-summary-card-list": {
|
|
420
425
|
"import": "./fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-summary-card-list.mjs",
|
|
421
426
|
"types": "./types/hmcts-opal-frontend-common-components-govuk-govuk-summary-card-list.d.ts",
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class GovukSkipLinkComponent {
|
|
3
|
+
private readonly document;
|
|
4
|
+
private readonly utilsService;
|
|
5
|
+
targetId: string;
|
|
6
|
+
linkText: string;
|
|
7
|
+
get href(): string;
|
|
8
|
+
onSkipLink(event: Event): void;
|
|
9
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<GovukSkipLinkComponent, never>;
|
|
10
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<GovukSkipLinkComponent, "opal-lib-govuk-skip-link", never, {
|
|
11
|
+
"targetId": {
|
|
12
|
+
"alias": "targetId";
|
|
13
|
+
"required": false;
|
|
14
|
+
};
|
|
15
|
+
"linkText": {
|
|
16
|
+
"alias": "linkText";
|
|
17
|
+
"required": false;
|
|
18
|
+
};
|
|
19
|
+
}, {}, never, never, true, never>;
|
|
20
|
+
}
|
|
@@ -4,7 +4,23 @@ import { AbstractControl } from "@angular/forms";
|
|
|
4
4
|
export declare class CapitalisationDirective implements OnInit, OnDestroy {
|
|
5
5
|
private readonly destroy$;
|
|
6
6
|
private readonly utilsService;
|
|
7
|
+
private readonly document;
|
|
7
8
|
control: AbstractControl;
|
|
9
|
+
/**
|
|
10
|
+
* Captures the focused input or textarea selection before its value is uppercased.
|
|
11
|
+
* Maps offsets through uppercase prefixes to account for expanding characters, such as ß becoming SS.
|
|
12
|
+
* Defaults missing selection direction to 'none' for document implementations with incomplete selection support.
|
|
13
|
+
*
|
|
14
|
+
* @param value The current control value, which must match the focused input's value.
|
|
15
|
+
* @returns The input and its mapped selection, or null when the value differs or selection is unsupported.
|
|
16
|
+
*/
|
|
17
|
+
private captureSelection;
|
|
18
|
+
/**
|
|
19
|
+
* Uppercases a changed control value while preserving the focused input's selection.
|
|
20
|
+
*
|
|
21
|
+
* @param value The latest value emitted by the form control.
|
|
22
|
+
*/
|
|
23
|
+
private capitaliseControlValue;
|
|
8
24
|
ngOnInit(): void;
|
|
9
25
|
ngOnDestroy(): void;
|
|
10
26
|
static ɵfac: i0.ɵɵFactoryDeclaration<CapitalisationDirective, never>;
|
|
@@ -39,6 +39,14 @@ export declare class UtilsService {
|
|
|
39
39
|
* Utilizes the `viewportScroller` service to scroll to the position [0, 0].
|
|
40
40
|
*/
|
|
41
41
|
scrollToTop(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Moves focus to an element by ID.
|
|
44
|
+
* A temporary tabindex allows a normally non-focusable element to receive programmatic focus.
|
|
45
|
+
*
|
|
46
|
+
* @param elementId - The ID of the element to focus.
|
|
47
|
+
* @param options - Options passed to the element's focus method.
|
|
48
|
+
*/
|
|
49
|
+
focusElementById(elementId: string, options?: FocusOptions): void;
|
|
42
50
|
/**
|
|
43
51
|
* Moves focus to the main content landmark and scrolls the viewport to the top of the page.
|
|
44
52
|
* A temporary tabindex allows the normally non-focusable landmark to receive programmatic focus.
|