@eagami/ui 4.5.0 → 4.6.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 +9 -1
- package/package.json +22 -4
- package/schematics/collection.json +9 -0
- package/schematics/ng-add/index.js +64 -0
- package/schematics/ng-add/schema.js +2 -0
- package/schematics/ng-add/schema.json +16 -0
- package/schematics/ng-add/utils.js +53 -0
- package/schematics/package.json +3 -0
package/README.md
CHANGED
|
@@ -25,6 +25,14 @@
|
|
|
25
25
|
|
|
26
26
|
## Installation
|
|
27
27
|
|
|
28
|
+
The quickest way is the schematic, which installs the package and registers the global stylesheet and fonts for you:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
ng add @eagami/ui
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Prefer to wire it up by hand? Install the package:
|
|
35
|
+
|
|
28
36
|
```bash
|
|
29
37
|
npm install @eagami/ui
|
|
30
38
|
# or
|
|
@@ -33,7 +41,7 @@ pnpm add @eagami/ui
|
|
|
33
41
|
yarn add @eagami/ui
|
|
34
42
|
```
|
|
35
43
|
|
|
36
|
-
|
|
44
|
+
Then add the global stylesheet to your `angular.json`:
|
|
37
45
|
|
|
38
46
|
```json
|
|
39
47
|
"styles": ["node_modules/@eagami/ui/src/styles/eagami-ui.scss"]
|
package/package.json
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eagami/ui",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "Lightweight, accessible Angular UI component library built on CSS custom properties",
|
|
3
|
+
"version": "4.6.0",
|
|
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",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"angular",
|
|
9
|
+
"angular-components",
|
|
9
10
|
"ui",
|
|
11
|
+
"components",
|
|
10
12
|
"component-library",
|
|
11
13
|
"design-system",
|
|
12
|
-
"accessible"
|
|
14
|
+
"accessible",
|
|
15
|
+
"a11y",
|
|
16
|
+
"dark-mode",
|
|
17
|
+
"theming",
|
|
18
|
+
"icons",
|
|
19
|
+
"signals",
|
|
20
|
+
"standalone",
|
|
21
|
+
"typescript",
|
|
22
|
+
"css-variables"
|
|
13
23
|
],
|
|
14
24
|
"homepage": "https://eagami.com/ui",
|
|
15
25
|
"repository": {
|
|
@@ -41,5 +51,13 @@
|
|
|
41
51
|
"default": "./fesm2022/eagami-ui.mjs"
|
|
42
52
|
}
|
|
43
53
|
},
|
|
44
|
-
"type": "module"
|
|
54
|
+
"type": "module",
|
|
55
|
+
"files": [
|
|
56
|
+
"fesm2022",
|
|
57
|
+
"types",
|
|
58
|
+
"src/styles",
|
|
59
|
+
"schematics",
|
|
60
|
+
"README.md"
|
|
61
|
+
],
|
|
62
|
+
"schematics": "./schematics/collection.json"
|
|
45
63
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ngAdd = ngAdd;
|
|
4
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const workspace_1 = require("@schematics/angular/utility/workspace");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
function ngAdd(options) {
|
|
8
|
+
return (0, schematics_1.chain)([registerStylesheet(options), registerFonts(options), logNextSteps()]);
|
|
9
|
+
}
|
|
10
|
+
function registerStylesheet(options) {
|
|
11
|
+
return (0, workspace_1.updateWorkspace)(workspace => {
|
|
12
|
+
const { project } = findProject(workspace, options.project);
|
|
13
|
+
const build = project.targets.get('build');
|
|
14
|
+
if (!build) {
|
|
15
|
+
throw new schematics_1.SchematicsException('No "build" target found; cannot register the Eagami UI stylesheet.');
|
|
16
|
+
}
|
|
17
|
+
build.options ??= {};
|
|
18
|
+
const existing = build.options['styles'];
|
|
19
|
+
const styles = Array.isArray(existing) ? existing : [];
|
|
20
|
+
build.options['styles'] = (0, utils_1.withEagamiStyle)(styles);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function registerFonts(options) {
|
|
24
|
+
return async (tree, context) => {
|
|
25
|
+
const workspace = await (0, workspace_1.getWorkspace)(tree);
|
|
26
|
+
const { name, project } = findProject(workspace, options.project);
|
|
27
|
+
const indexPath = (0, utils_1.resolveIndexPath)(project.targets.get('build')?.options?.['index']);
|
|
28
|
+
if (!indexPath) {
|
|
29
|
+
context.logger.warn(`No index.html found for project "${name}"; add the Eagami UI fonts manually.`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const current = tree.read(indexPath);
|
|
33
|
+
if (!current) {
|
|
34
|
+
context.logger.warn(`Could not read "${indexPath}"; add the Eagami UI fonts manually.`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const html = current.toString('utf-8');
|
|
38
|
+
const updated = (0, utils_1.withEagamiFonts)(html);
|
|
39
|
+
if (updated !== html) {
|
|
40
|
+
tree.overwrite(indexPath, updated);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function logNextSteps() {
|
|
45
|
+
return (_tree, context) => {
|
|
46
|
+
context.logger.info('Eagami UI is set up: the global stylesheet and fonts are registered.');
|
|
47
|
+
context.logger.info('Optional: call provideEagamiUi() in app.config.ts for a custom brand palette or extra locales.');
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function findProject(workspace, name) {
|
|
51
|
+
if (name) {
|
|
52
|
+
const project = workspace.projects.get(name);
|
|
53
|
+
if (!project) {
|
|
54
|
+
throw new schematics_1.SchematicsException(`Project "${name}" not found in the workspace.`);
|
|
55
|
+
}
|
|
56
|
+
return { name, project };
|
|
57
|
+
}
|
|
58
|
+
for (const [projectName, project] of workspace.projects) {
|
|
59
|
+
if (project.extensions['projectType'] === 'application') {
|
|
60
|
+
return { name: projectName, project };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new schematics_1.SchematicsException('No application project found to set up Eagami UI.');
|
|
64
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "eagami-ui-ng-add",
|
|
4
|
+
"title": "Eagami UI ng-add schematic",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"project": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "The project to set up Eagami UI in.",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "projectName"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"additionalProperties": false
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Pure, dependency-free transforms for the ng-add schematic. Kept separate from
|
|
3
|
+
// index.ts (which pulls in @angular-devkit) so the unit tests compile under the
|
|
4
|
+
// Angular test build without dragging Node-only schematics APIs into the bundle.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.EAGAMI_FONT_LINKS = exports.EAGAMI_STYLE_PATH = void 0;
|
|
7
|
+
exports.styleEntryMatches = styleEntryMatches;
|
|
8
|
+
exports.withEagamiStyle = withEagamiStyle;
|
|
9
|
+
exports.hasEagamiFonts = hasEagamiFonts;
|
|
10
|
+
exports.withEagamiFonts = withEagamiFonts;
|
|
11
|
+
exports.resolveIndexPath = resolveIndexPath;
|
|
12
|
+
exports.EAGAMI_STYLE_PATH = 'node_modules/@eagami/ui/src/styles/eagami-ui.scss';
|
|
13
|
+
exports.EAGAMI_FONT_LINKS = [
|
|
14
|
+
'<link rel="preconnect" href="https://fonts.googleapis.com" />',
|
|
15
|
+
'<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />',
|
|
16
|
+
'<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=Syne:wght@400;500;600;700&display=swap" />',
|
|
17
|
+
];
|
|
18
|
+
// Unique to our Google Fonts request, so it doubles as the idempotency marker
|
|
19
|
+
const FONT_MARKER = 'family=DM+Sans';
|
|
20
|
+
function styleEntryMatches(entry, path) {
|
|
21
|
+
return typeof entry === 'string' ? entry === path : entry.input === path;
|
|
22
|
+
}
|
|
23
|
+
function withEagamiStyle(styles) {
|
|
24
|
+
if (styles.some(style => styleEntryMatches(style, exports.EAGAMI_STYLE_PATH))) {
|
|
25
|
+
return styles;
|
|
26
|
+
}
|
|
27
|
+
return [exports.EAGAMI_STYLE_PATH, ...styles];
|
|
28
|
+
}
|
|
29
|
+
function hasEagamiFonts(html) {
|
|
30
|
+
return html.includes(FONT_MARKER);
|
|
31
|
+
}
|
|
32
|
+
function withEagamiFonts(html) {
|
|
33
|
+
if (hasEagamiFonts(html)) {
|
|
34
|
+
return html;
|
|
35
|
+
}
|
|
36
|
+
const block = exports.EAGAMI_FONT_LINKS.map(link => ` ${link}`).join('\n');
|
|
37
|
+
const headClose = /([ \t]*)<\/head>/i;
|
|
38
|
+
if (headClose.test(html)) {
|
|
39
|
+
return html.replace(headClose, `${block}\n$1</head>`);
|
|
40
|
+
}
|
|
41
|
+
return `${block}\n${html}`;
|
|
42
|
+
}
|
|
43
|
+
// The build target's `index` option is either a path string or a { input, output } object
|
|
44
|
+
function resolveIndexPath(index) {
|
|
45
|
+
if (typeof index === 'string') {
|
|
46
|
+
return index;
|
|
47
|
+
}
|
|
48
|
+
if (index !== null && typeof index === 'object' && 'input' in index) {
|
|
49
|
+
const input = index.input;
|
|
50
|
+
return typeof input === 'string' ? input : undefined;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|