@eagami/ui 5.75.0 → 5.77.0
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/README.md +13 -1
- package/fesm2022/eagami-ui-router.mjs +124 -0
- package/fesm2022/eagami-ui-router.mjs.map +1 -0
- package/fesm2022/eagami-ui.mjs +4 -4
- package/fesm2022/eagami-ui.mjs.map +1 -1
- package/package.json +13 -2
- package/router/package.json +4 -0
- package/schematics/collection.json +1 -1
- package/schematics/ng-add/index.js +14 -2
- package/src/styles/_mixins.scss +5 -4
- package/types/eagami-ui-router.d.ts +54 -0
- package/types/eagami-ui.d.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eagami/ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.77.0",
|
|
4
4
|
"description": "Lightweight, accessible, themeable Angular UI component library and icon set built on CSS custom properties",
|
|
5
5
|
"author": "Michal Wiraszka <michal@eagami.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,13 @@
|
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@angular/common": "^21.0.0 || ^22.0.0",
|
|
35
35
|
"@angular/core": "^21.0.0 || ^22.0.0",
|
|
36
|
-
"@angular/forms": "^21.0.0 || ^22.0.0"
|
|
36
|
+
"@angular/forms": "^21.0.0 || ^22.0.0",
|
|
37
|
+
"@angular/router": "^21.0.0 || ^22.0.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"@angular/router": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
37
43
|
},
|
|
38
44
|
"dependencies": {},
|
|
39
45
|
"engines": {
|
|
@@ -49,6 +55,10 @@
|
|
|
49
55
|
"types": "./types/eagami-ui.d.ts",
|
|
50
56
|
"default": "./fesm2022/eagami-ui.mjs"
|
|
51
57
|
},
|
|
58
|
+
"./router": {
|
|
59
|
+
"types": "./types/eagami-ui-router.d.ts",
|
|
60
|
+
"default": "./fesm2022/eagami-ui-router.mjs"
|
|
61
|
+
},
|
|
52
62
|
"./testing": {
|
|
53
63
|
"types": "./types/eagami-ui-testing.d.ts",
|
|
54
64
|
"default": "./fesm2022/eagami-ui-testing.mjs"
|
|
@@ -61,6 +71,7 @@
|
|
|
61
71
|
"src/styles",
|
|
62
72
|
"schematics",
|
|
63
73
|
"testing",
|
|
74
|
+
"router",
|
|
64
75
|
"README.md"
|
|
65
76
|
],
|
|
66
77
|
"schematics": "./schematics/collection.json"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schematics": {
|
|
3
3
|
"ng-add": {
|
|
4
|
-
"description": "Set up Eagami UI: register the global stylesheet
|
|
4
|
+
"description": "Set up Eagami UI: register the global stylesheet, the fonts, and provideStaleBuildReload() in an Angular workspace.",
|
|
5
5
|
"factory": "./ng-add/index#ngAdd",
|
|
6
6
|
"schema": "./ng-add/schema.json"
|
|
7
7
|
}
|
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ngAdd = ngAdd;
|
|
4
4
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const utility_1 = require("@schematics/angular/utility");
|
|
5
6
|
const workspace_1 = require("@schematics/angular/utility/workspace");
|
|
6
7
|
const utils_1 = require("./utils");
|
|
7
8
|
function ngAdd(options) {
|
|
8
|
-
return (0, schematics_1.chain)([
|
|
9
|
+
return (0, schematics_1.chain)([
|
|
10
|
+
registerStylesheet(options),
|
|
11
|
+
registerFonts(options),
|
|
12
|
+
registerStaleBuildReload(options),
|
|
13
|
+
logNextSteps(),
|
|
14
|
+
]);
|
|
9
15
|
}
|
|
10
16
|
function registerStylesheet(options) {
|
|
11
17
|
return (0, workspace_1.updateWorkspace)(workspace => {
|
|
@@ -41,9 +47,15 @@ function registerFonts(options) {
|
|
|
41
47
|
}
|
|
42
48
|
};
|
|
43
49
|
}
|
|
50
|
+
function registerStaleBuildReload(options) {
|
|
51
|
+
return async (tree) => {
|
|
52
|
+
const { name } = findProject(await (0, workspace_1.getWorkspace)(tree), options.project);
|
|
53
|
+
return (0, utility_1.addRootProvider)(name, ({ code, external }) => code `${external('provideStaleBuildReload', '@eagami/ui/router')}()`);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
44
56
|
function logNextSteps() {
|
|
45
57
|
return (_tree, context) => {
|
|
46
|
-
context.logger.info('Eagami UI is set up: the global stylesheet and fonts are registered.');
|
|
58
|
+
context.logger.info('Eagami UI is set up: the global stylesheet and fonts are registered, and provideStaleBuildReload() reloads a tab left open across a deploy into the new build.');
|
|
47
59
|
context.logger.info('Optional: call provideEagamiUi() in app.config.ts for a custom brand palette or extra locales.');
|
|
48
60
|
};
|
|
49
61
|
}
|
package/src/styles/_mixins.scss
CHANGED
|
@@ -11,19 +11,20 @@ $target-size-min: 24px;
|
|
|
11
11
|
// transparent, so it reads the same on any surface, however coloured. Pass a full
|
|
12
12
|
// box-shadow value to draw a halo instead, such as an error ring; box-shadow is
|
|
13
13
|
// dropped in forced-colors (Windows High Contrast) mode, so a real outline stands
|
|
14
|
-
// in for it there.
|
|
15
|
-
|
|
14
|
+
// in for it there. Pass `$offset` to move the outline's gap, which a negative
|
|
15
|
+
// value turns inward.
|
|
16
|
+
@mixin focus-ring($ring: null, $offset: 2px) {
|
|
16
17
|
@if $ring {
|
|
17
18
|
outline: none;
|
|
18
19
|
box-shadow: $ring;
|
|
19
20
|
} @else {
|
|
20
21
|
outline: var(--border-width-medium) solid var(--color-border-focus);
|
|
21
|
-
outline-offset:
|
|
22
|
+
outline-offset: $offset;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
@media (forced-colors: active) {
|
|
25
26
|
outline: 2px solid Highlight;
|
|
26
|
-
outline-offset:
|
|
27
|
+
outline-offset: $offset;
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { EnvironmentProviders, InjectionToken } from "@angular/core";
|
|
2
|
+
/**
|
|
3
|
+
* How a reload into the current build turned out:
|
|
4
|
+
*
|
|
5
|
+
* - `'recovered'`: the reloaded page opened
|
|
6
|
+
* - `'failed-after-reload'`: the reloaded page failed to open too, so the error is left to surface
|
|
7
|
+
* - `'stayed'`: the visitor chose to stay when the browser asked them to confirm leaving
|
|
8
|
+
*/
|
|
9
|
+
type StaleBuildReloadOutcome = 'recovered' | 'failed-after-reload' | 'stayed';
|
|
10
|
+
interface StaleBuildReloadReport {
|
|
11
|
+
outcome: StaleBuildReloadOutcome;
|
|
12
|
+
/** The path that failed to open, without its query or fragment. */
|
|
13
|
+
route: string;
|
|
14
|
+
/** The `version` configured in the build that failed to open the page. */
|
|
15
|
+
fromVersion?: string;
|
|
16
|
+
/** The `version` configured in the build making the report. */
|
|
17
|
+
toVersion?: string;
|
|
18
|
+
}
|
|
19
|
+
interface StaleBuildReloadConfig {
|
|
20
|
+
/** The app's version, carried across the reload so a report names both builds. */
|
|
21
|
+
version?: string;
|
|
22
|
+
/** Called once per reload with how it turned out, for example to log it. */
|
|
23
|
+
onReport?: (report: StaleBuildReloadReport) => void;
|
|
24
|
+
}
|
|
25
|
+
declare const LOAD_PAGE: InjectionToken<(url: string, replace: boolean) => void>;
|
|
26
|
+
/**
|
|
27
|
+
* Whether `error` is a failed page load that `provideStaleBuildReload()` has
|
|
28
|
+
* already answered by reloading. Error reporters can drop it, since the
|
|
29
|
+
* reload's outcome reaches `onReport` instead:
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* Sentry.init({
|
|
33
|
+
* beforeSend: (event, hint) =>
|
|
34
|
+
* isStaleBuildReloadError(hint.originalException) ? null : event,
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function isStaleBuildReloadError(error: unknown): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Loads the current build in full when the code of a page being opened fails
|
|
41
|
+
* to load, which is what a tab still running a build that a deploy has since
|
|
42
|
+
* replaced runs into. The reload opens the page the visitor asked for, and
|
|
43
|
+
* stops after one attempt if the new build fails as well.
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* bootstrapApplication(AppComponent, {
|
|
47
|
+
* providers: [provideRouter(routes), provideStaleBuildReload()],
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* Does nothing during server rendering.
|
|
52
|
+
*/
|
|
53
|
+
export declare function provideStaleBuildReload(config?: StaleBuildReloadConfig): EnvironmentProviders;
|
|
54
|
+
export type { StaleBuildReloadConfig, StaleBuildReloadOutcome, StaleBuildReloadReport };
|
package/types/eagami-ui.d.ts
CHANGED
|
@@ -1967,7 +1967,10 @@ export type ButtonAlign = 'start' | 'center' | 'end';
|
|
|
1967
1967
|
* while preserving the rendered width. Chrome is tunable per instance via
|
|
1968
1968
|
* `--ea-button-padding`, `--ea-button-min-height` and `--ea-button-radius`,
|
|
1969
1969
|
* which is how an icon-only button comes down to little more than its glyph
|
|
1970
|
-
* and how a call-to-action becomes a pill
|
|
1970
|
+
* and how a call-to-action becomes a pill, and `--ea-button-focus-ring-offset`
|
|
1971
|
+
* moves the focus ring's gap, which a negative length draws inside a button
|
|
1972
|
+
* packed too tightly among others for the ring to fit around it. For
|
|
1973
|
+
* navigation, put
|
|
1971
1974
|
* `ButtonLinkComponent` on an anchor instead (`<a eaButtonLink href="...">`):
|
|
1972
1975
|
* it takes the same styling inputs and keeps real link behaviour.
|
|
1973
1976
|
*/
|