@blotch/angular-lynx 22.2.2 → 22.2.4
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 +47 -23
- package/fesm2022/blotch-angular-lynx-web-glass-ciDHw7Bw.mjs +961 -0
- package/fesm2022/blotch-angular-lynx-web-glass-ciDHw7Bw.mjs.map +1 -0
- package/fesm2022/blotch-angular-lynx.mjs +2426 -831
- package/fesm2022/blotch-angular-lynx.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics/add-i18n/index.js +24 -7
- package/schematics/add-tailwind/index.js +14 -75
- package/schematics/add-tailwind/schema.json +6 -1
- package/schematics/collection.json +1 -1
- package/schematics/migrations/accessibility-traits/index.js +56 -0
- package/schematics/migrations/dev-logs-gitignore/index.js +9 -0
- package/schematics/migrations/extract-i18n-target/index.js +31 -0
- package/schematics/migrations/tailwind-html-templates/index.js +44 -0
- package/schematics/migrations.json +22 -1
- package/schematics/ng-add/index.js +20 -66
- package/schematics/ng-add/schema.json +7 -2
- package/schematics/ng-add/versions.js +8 -2
- package/schematics/utility/dev-logs-gitignore.js +25 -0
- package/schematics/utility/extract-i18n-target.js +58 -0
- package/schematics/utility/tailwind.js +167 -0
- package/types/blotch-angular-lynx.d.ts +950 -350
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TAILWIND_4_STYLESHEET = exports.setUpTailwind = exports.tailwindVersionFor = exports.installedTailwindVersion = void 0;
|
|
4
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const dependency_1 = require("@schematics/angular/utility/dependency");
|
|
6
|
+
const json_file_1 = require("@schematics/angular/utility/json-file");
|
|
7
|
+
const workspace_1 = require("@schematics/angular/utility/workspace");
|
|
8
|
+
const versions_1 = require("../ng-add/versions");
|
|
9
|
+
/**
|
|
10
|
+
* The Tailwind CSS major version the project already depends on, if any. A
|
|
11
|
+
* range such as `^4.1.0` gives 4; `@tailwindcss/postcss`, Tailwind 4's
|
|
12
|
+
* PostCSS plugin, means 4 too.
|
|
13
|
+
*/
|
|
14
|
+
const installedTailwindVersion = (tree) => {
|
|
15
|
+
if (!tree.exists('package.json')) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const { dependencies = {}, devDependencies = {} } = tree.readJson('package.json');
|
|
19
|
+
const all = { ...dependencies, ...devDependencies };
|
|
20
|
+
if (all['@tailwindcss/postcss']) {
|
|
21
|
+
return '4';
|
|
22
|
+
}
|
|
23
|
+
const major = /\d+/.exec(all['tailwindcss'] ?? '')?.[0];
|
|
24
|
+
return major === '3' || major === '4' ? major : undefined;
|
|
25
|
+
};
|
|
26
|
+
exports.installedTailwindVersion = installedTailwindVersion;
|
|
27
|
+
/**
|
|
28
|
+
* The version to set up: the one asked for, else the one the project already
|
|
29
|
+
* has, else 4. An app that `ng new --style=tailwind` made, or one that is
|
|
30
|
+
* already on Tailwind 3, keeps its version, so running `ng add` again never
|
|
31
|
+
* moves it to another.
|
|
32
|
+
*/
|
|
33
|
+
const tailwindVersionFor = (tree, requested) => requested === undefined
|
|
34
|
+
? ((0, exports.installedTailwindVersion)(tree) ?? '4')
|
|
35
|
+
: String(requested);
|
|
36
|
+
exports.tailwindVersionFor = tailwindVersionFor;
|
|
37
|
+
/**
|
|
38
|
+
* Sets Tailwind CSS up in a project: Tailwind 4 as Angular CLI sets it up
|
|
39
|
+
* (`ng new --style=tailwind`), or Tailwind 3 with Lynx's preset.
|
|
40
|
+
*/
|
|
41
|
+
const setUpTailwind = (target, version) => (version === '3' ? setUpTailwind3(target) : setUpTailwind4(target));
|
|
42
|
+
exports.setUpTailwind = setUpTailwind;
|
|
43
|
+
const prefixed = (projectRoot, file) => projectRoot ? `${projectRoot}/${file}` : file;
|
|
44
|
+
/**
|
|
45
|
+
* Tailwind 4, without its Preflight reset, whose rules are for HTML elements
|
|
46
|
+
* (`h1`, `button`, `img`) that a Lynx app doesn't have: Lynx drops most of
|
|
47
|
+
* them, and the web preview would apply them, so the two would differ.
|
|
48
|
+
* Tailwind documents this way of leaving Preflight out.
|
|
49
|
+
*/
|
|
50
|
+
exports.TAILWIND_4_STYLESHEET = `@layer theme, base, components, utilities;
|
|
51
|
+
@import 'tailwindcss/theme.css' layer(theme);
|
|
52
|
+
@import 'tailwindcss/utilities.css' layer(utilities);
|
|
53
|
+
`;
|
|
54
|
+
/** The PostCSS config files Angular CLI reads, and its Tailwind schematic writes. */
|
|
55
|
+
const POSTCSS_CONFIG_FILES = ['.postcssrc.json', 'postcss.config.json'];
|
|
56
|
+
const setUpTailwind4 = ({ projectName, projectRoot, sourceRoot, }) => {
|
|
57
|
+
const installed = (tree) => (0, exports.installedTailwindVersion)(tree) === '4';
|
|
58
|
+
return (0, schematics_1.chain)([
|
|
59
|
+
writeTailwind4Stylesheet(projectName, sourceRoot),
|
|
60
|
+
addTailwindPostcssPlugin(projectRoot),
|
|
61
|
+
(tree) => (0, schematics_1.chain)(['tailwindcss', '@tailwindcss/postcss'].map((name) => (0, dependency_1.addDependency)(name, versions_1.VERSIONS.tailwindcss4, {
|
|
62
|
+
type: dependency_1.DependencyType.Dev,
|
|
63
|
+
install: dependency_1.InstallBehavior.Auto,
|
|
64
|
+
// Keep the version of a project that already has Tailwind 4, as
|
|
65
|
+
// Angular CLI does; replace a Tailwind 3 one.
|
|
66
|
+
existing: installed(tree)
|
|
67
|
+
? dependency_1.ExistingBehavior.Skip
|
|
68
|
+
: dependency_1.ExistingBehavior.Replace,
|
|
69
|
+
}))),
|
|
70
|
+
(tree, context) => {
|
|
71
|
+
const config = ['ts', 'js', 'mjs', 'cjs']
|
|
72
|
+
.map((extension) => prefixed(projectRoot, `tailwind.config.${extension}`))
|
|
73
|
+
.find((file) => tree.exists(file));
|
|
74
|
+
if (config) {
|
|
75
|
+
context.logger.warn(`Tailwind CSS 4 doesn't read ${config}. Move its theme into @theme in the stylesheet, load its plugins with @plugin, and delete it.`);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
]);
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Writes the Tailwind 4 stylesheet: over `styles.css`, or, in a project
|
|
82
|
+
* styled with Sass (which would read Tailwind's `@import`s as its own), to a
|
|
83
|
+
* `tailwind.css` added to the build's styles, as Angular CLI does.
|
|
84
|
+
*/
|
|
85
|
+
const writeTailwind4Stylesheet = (projectName, sourceRoot) => (tree) => {
|
|
86
|
+
const cssPath = `${sourceRoot}/styles.css`;
|
|
87
|
+
if (tree.exists(cssPath) || !tree.exists(`${sourceRoot}/styles.scss`)) {
|
|
88
|
+
writeFile(tree, cssPath, exports.TAILWIND_4_STYLESHEET);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const tailwindPath = `${sourceRoot}/tailwind.css`;
|
|
92
|
+
writeFile(tree, tailwindPath, exports.TAILWIND_4_STYLESHEET);
|
|
93
|
+
return (0, workspace_1.updateWorkspace)((workspace) => {
|
|
94
|
+
const build = workspace.projects.get(projectName)?.targets.get('build');
|
|
95
|
+
if (!build) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const options = (build.options ??= {});
|
|
99
|
+
const styles = options['styles'] ?? [];
|
|
100
|
+
if (!styles.includes(tailwindPath)) {
|
|
101
|
+
options['styles'] = [tailwindPath, ...styles];
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Lists `@tailwindcss/postcss` in the project's PostCSS config, which the
|
|
107
|
+
* build reads, creating `.postcssrc.json` if there's none, as Angular CLI's
|
|
108
|
+
* Tailwind schematic does.
|
|
109
|
+
*/
|
|
110
|
+
const addTailwindPostcssPlugin = (projectRoot) => (tree) => {
|
|
111
|
+
const existing = [...new Set(['', projectRoot])]
|
|
112
|
+
.flatMap((root) => POSTCSS_CONFIG_FILES.map((file) => prefixed(root, file)))
|
|
113
|
+
.find((file) => tree.exists(file));
|
|
114
|
+
if (!existing) {
|
|
115
|
+
tree.create(prefixed(projectRoot, '.postcssrc.json'), `${JSON.stringify({ plugins: { '@tailwindcss/postcss': {} } }, null, 2)}\n`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const config = new json_file_1.JSONFile(tree, existing);
|
|
119
|
+
if (config.get(['plugins', '@tailwindcss/postcss']) === undefined) {
|
|
120
|
+
config.modify(['plugins', '@tailwindcss/postcss'], {});
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const setUpTailwind3 = ({ projectRoot, sourceRoot }) => (0, schematics_1.chain)([
|
|
124
|
+
(tree) => {
|
|
125
|
+
// The build runs Tailwind with this `content`, so it has to take in
|
|
126
|
+
// both inline templates (.ts) and the .html templates `ng generate
|
|
127
|
+
// component` writes by default, as in Angular's own Tailwind setup.
|
|
128
|
+
writeFile(tree, prefixed(projectRoot, 'tailwind.config.ts'), `import type { Config } from 'tailwindcss';
|
|
129
|
+
import preset from '@lynx-js/tailwind-preset';
|
|
130
|
+
|
|
131
|
+
const config: Config = {
|
|
132
|
+
content: ['./src/**/*.{html,ts}'],
|
|
133
|
+
presets: [preset],
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export default config;
|
|
137
|
+
`);
|
|
138
|
+
// Prefer styles.scss if it exists (the user picked SCSS at `ng new`
|
|
139
|
+
// time): overwriting it with .css content would break their other
|
|
140
|
+
// imports.
|
|
141
|
+
//
|
|
142
|
+
// Only @tailwind base + utilities, no @tailwind components. Lynx doesn't
|
|
143
|
+
// support all of Tailwind's component-layer reset rules (button resets
|
|
144
|
+
// that reference focus-visible, form input pseudo-classes), and bundling
|
|
145
|
+
// them in would generate CSS the runtime can't parse, producing
|
|
146
|
+
// diagnostic noise. The base layer ships with @lynx-js/tailwind-preset's
|
|
147
|
+
// own Lynx-compatible normalize rules.
|
|
148
|
+
const scssPath = `${sourceRoot}/styles.scss`;
|
|
149
|
+
writeFile(tree, tree.exists(scssPath) ? scssPath : `${sourceRoot}/styles.css`, '@tailwind base;\n@tailwind utilities;\n');
|
|
150
|
+
},
|
|
151
|
+
(0, dependency_1.addDependency)('tailwindcss', versions_1.VERSIONS.tailwindcss, {
|
|
152
|
+
type: dependency_1.DependencyType.Dev,
|
|
153
|
+
install: dependency_1.InstallBehavior.Auto,
|
|
154
|
+
}),
|
|
155
|
+
(0, dependency_1.addDependency)('@lynx-js/tailwind-preset', versions_1.VERSIONS.tailwindPreset, {
|
|
156
|
+
type: dependency_1.DependencyType.Dev,
|
|
157
|
+
install: dependency_1.InstallBehavior.Auto,
|
|
158
|
+
}),
|
|
159
|
+
]);
|
|
160
|
+
const writeFile = (tree, path, content) => {
|
|
161
|
+
if (tree.exists(path)) {
|
|
162
|
+
tree.overwrite(path, content);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
tree.create(path, content);
|
|
166
|
+
}
|
|
167
|
+
};
|