@educarehq/solaris-ui 0.3.3 → 0.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/fesm2022/educarehq-solaris-ui.mjs +1563 -911
- package/fesm2022/educarehq-solaris-ui.mjs.map +1 -1
- package/package.json +18 -1
- package/schematics/collection.json +16 -0
- package/schematics/init/fonts.js +18 -0
- package/schematics/init/index.js +77 -0
- package/schematics/init/messages.js +25 -0
- package/schematics/init/providers.js +89 -0
- package/schematics/init/schema.json +54 -0
- package/schematics/init/styles.js +75 -0
- package/schematics/init/workspace.js +45 -0
- package/schematics/ng-add/index.js +66 -0
- package/schematics/ng-add/schema.json +40 -0
- package/schematics/package.json +5 -0
- package/styles/_button.scss +122 -66
- package/styles/_core.scss +13 -37
- package/styles/_dropdown-menu.scss +13 -15
- package/styles/_icon-button.scss +34 -29
- package/styles/_index.scss +3 -2
- package/styles/_input.scss +50 -48
- package/styles/_textarea.scss +65 -59
- package/styles/_theme.scss +80 -46
- package/styles/_toast.scss +2 -2
- package/styles/_tooltip.scss +3 -1
- package/styles/token/border/_border.scss +7 -5
- package/styles/token/border/_index.scss +1 -1
- package/styles/token/color/_dark.scss +81 -78
- package/styles/token/color/_high-contrast.scss +143 -27
- package/styles/token/color/_index.scss +3 -3
- package/styles/token/color/_light.scss +72 -69
- package/styles/token/density/_comfortable.scss +15 -15
- package/styles/token/density/_compact.scss +15 -15
- package/styles/token/density/_index.scss +2 -2
- package/styles/token/focus/_focus.scss +16 -0
- package/styles/token/focus/_index.scss +1 -0
- package/styles/token/glass/_glass.scss +17 -0
- package/styles/token/glass/_index.scss +1 -0
- package/styles/token/motion/_index.scss +2 -2
- package/styles/token/motion/_motion.scss +17 -15
- package/styles/token/motion/_reduced-motion.scss +15 -15
- package/styles/token/opacity/_index.scss +1 -1
- package/styles/token/opacity/_opacity.scss +13 -4
- package/styles/token/radius/_index.scss +1 -1
- package/styles/token/radius/_radius.scss +8 -8
- package/styles/token/shadow/_index.scss +1 -1
- package/styles/token/shadow/_shadow.scss +40 -26
- package/styles/token/spacing/_index.scss +1 -1
- package/styles/token/spacing/_spacing.scss +18 -15
- package/styles/token/typography/_font-family.scss +13 -13
- package/styles/token/typography/_index.scss +2 -2
- package/styles/token/typography/_typography.scss +26 -25
- package/styles/token/z-index/_index.scss +1 -1
- package/styles/token/z-index/_z-index.scss +13 -10
- package/types/educarehq-solaris-ui.d.ts +384 -106
package/package.json
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@educarehq/solaris-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/educarehq/solaris-ui.git",
|
|
8
|
+
"directory": "packages/angular"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"fesm2022",
|
|
15
|
+
"types",
|
|
16
|
+
"styles",
|
|
17
|
+
"schematics",
|
|
18
|
+
"README.md",
|
|
19
|
+
"package.json"
|
|
20
|
+
],
|
|
4
21
|
"peerDependencies": {
|
|
5
22
|
"@angular-devkit/schematics": "^21.0.0",
|
|
6
23
|
"@angular/cdk": "^21.2.0",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
|
|
3
|
+
"schematics": {
|
|
4
|
+
"init": {
|
|
5
|
+
"description": "Sets up @educarehq/solaris-ui styles and providers in an Angular project",
|
|
6
|
+
"factory": "./init/index#init",
|
|
7
|
+
"schema": "./init/schema.json",
|
|
8
|
+
"hidden": true
|
|
9
|
+
},
|
|
10
|
+
"ng-add": {
|
|
11
|
+
"description": "Adds @educarehq/solaris-ui to an Angular project",
|
|
12
|
+
"factory": "./ng-add/index#ngAdd",
|
|
13
|
+
"schema": "./ng-add/schema.json"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFontSizeComment = buildFontSizeComment;
|
|
4
|
+
/**
|
|
5
|
+
* Solaris uses the browser default root font-size (100%, typically 16px).
|
|
6
|
+
* Overriding the root font-size breaks WCAG 1.4.4 Resize Text, so the
|
|
7
|
+
* `default` scale is the only supported strategy.
|
|
8
|
+
*/
|
|
9
|
+
function buildFontSizeComment(options) {
|
|
10
|
+
const scale = options.scale ?? 'default';
|
|
11
|
+
if (scale !== 'default') {
|
|
12
|
+
return `// WARNING: solaris.core() uses the browser default root font-size (100%).
|
|
13
|
+
// Custom root font-size strategies are not supported (WCAG 1.4.4 Resize Text).
|
|
14
|
+
// Requested scale "${scale}" was ignored; default scale applied.`;
|
|
15
|
+
}
|
|
16
|
+
return `// Uses browser default root font-size (100%). All Solaris tokens are
|
|
17
|
+
// calculated at 1rem = 16px. Do NOT override the root font-size.`;
|
|
18
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.init = init;
|
|
4
|
+
const fonts_1 = require("./fonts");
|
|
5
|
+
const messages_1 = require("./messages");
|
|
6
|
+
const providers_1 = require("./providers");
|
|
7
|
+
const styles_1 = require("./styles");
|
|
8
|
+
const workspace_1 = require("./workspace");
|
|
9
|
+
function styleOptions(options) {
|
|
10
|
+
return {
|
|
11
|
+
colorScheme: options.colorScheme,
|
|
12
|
+
density: options.density,
|
|
13
|
+
radius: options.radius,
|
|
14
|
+
motion: options.reducedMotion === 'reduce' ? 'reduce' : 'auto',
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function providerOptions(options) {
|
|
18
|
+
return {
|
|
19
|
+
colorScheme: options.colorScheme,
|
|
20
|
+
density: options.density,
|
|
21
|
+
reducedMotion: options.reducedMotion,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function init(options) {
|
|
25
|
+
return (tree, context) => {
|
|
26
|
+
(0, messages_1.logInfo)(context, 'Setting up Solaris UI...');
|
|
27
|
+
const project = (0, workspace_1.getProject)(tree, options.project);
|
|
28
|
+
const projectRoot = project.root;
|
|
29
|
+
if (!options.skipStyles) {
|
|
30
|
+
// 1. Create editable src/styles/solaris.scss
|
|
31
|
+
const solarisStylePath = (0, styles_1.createSolarisStyleFile)(tree, projectRoot, styleOptions(options));
|
|
32
|
+
(0, messages_1.logChange)(context, `Created style setup file: ${solarisStylePath}`);
|
|
33
|
+
// 2. Import it from the global styles entry
|
|
34
|
+
const globalStylesPath = (0, styles_1.getGlobalStylesPath)(tree, projectRoot);
|
|
35
|
+
if (globalStylesPath) {
|
|
36
|
+
const changed = (0, styles_1.importSolarisStyleFromGlobal)(tree, globalStylesPath, solarisStylePath);
|
|
37
|
+
if (changed) {
|
|
38
|
+
(0, messages_1.logChange)(context, `Imported Solaris styles from ${globalStylesPath}`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
(0, messages_1.logSkip)(context, `Solaris styles already imported in ${globalStylesPath}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
(0, messages_1.logInfo)(context, 'No global styles file found. Import solaris.scss from your global styles entry.');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
(0, messages_1.logSkip)(context, 'Skipping style setup (skipStyles).');
|
|
50
|
+
}
|
|
51
|
+
if (!options.skipProviders) {
|
|
52
|
+
// 3. Add provideSolaris(...) to the application config
|
|
53
|
+
const appConfigPath = (0, providers_1.getAppConfigPath)(tree, projectRoot);
|
|
54
|
+
if (appConfigPath) {
|
|
55
|
+
const changed = (0, providers_1.updateAppConfig)(tree, appConfigPath, providerOptions(options));
|
|
56
|
+
if (changed) {
|
|
57
|
+
(0, messages_1.logChange)(context, `Added provideSolaris(...) to ${appConfigPath}`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
(0, messages_1.logSkip)(context, `provideSolaris already present in ${appConfigPath}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
(0, messages_1.logInfo)(context, 'No app.config.ts found. Add provideSolaris(...) to your application providers.');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
(0, messages_1.logSkip)(context, 'Skipping provider setup (skipProviders).');
|
|
69
|
+
}
|
|
70
|
+
if (!options.skipStyles) {
|
|
71
|
+
const comment = (0, fonts_1.buildFontSizeComment)({});
|
|
72
|
+
(0, messages_1.logInfo)(context, comment);
|
|
73
|
+
}
|
|
74
|
+
(0, messages_1.logSuccess)(context, 'Solaris UI setup complete.');
|
|
75
|
+
return tree;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logInfo = logInfo;
|
|
4
|
+
exports.logChange = logChange;
|
|
5
|
+
exports.logSuccess = logSuccess;
|
|
6
|
+
exports.logSkip = logSkip;
|
|
7
|
+
exports.logError = logError;
|
|
8
|
+
function prefix(message, symbol) {
|
|
9
|
+
return `${symbol} ${message}`;
|
|
10
|
+
}
|
|
11
|
+
function logInfo(context, message) {
|
|
12
|
+
context.logger.info(prefix(message, 'ℹ'));
|
|
13
|
+
}
|
|
14
|
+
function logChange(context, message) {
|
|
15
|
+
context.logger.info(prefix(message, '✏️'));
|
|
16
|
+
}
|
|
17
|
+
function logSuccess(context, message) {
|
|
18
|
+
context.logger.info(prefix(message, '✅'));
|
|
19
|
+
}
|
|
20
|
+
function logSkip(context, message) {
|
|
21
|
+
context.logger.info(prefix(message, '⏭️'));
|
|
22
|
+
}
|
|
23
|
+
function logError(context, message) {
|
|
24
|
+
context.logger.error(prefix(message, '❌'));
|
|
25
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAppConfigPath = getAppConfigPath;
|
|
4
|
+
exports.buildProviderConfig = buildProviderConfig;
|
|
5
|
+
exports.addProvideSolarisImport = addProvideSolarisImport;
|
|
6
|
+
exports.addProvideSolarisToProviders = addProvideSolarisToProviders;
|
|
7
|
+
exports.updateAppConfig = updateAppConfig;
|
|
8
|
+
const APP_CONFIG_CANDIDATES = ['src/app/app.config.ts', 'src/app.config.ts'];
|
|
9
|
+
function getAppConfigPath(tree, projectRoot) {
|
|
10
|
+
for (const candidate of APP_CONFIG_CANDIDATES) {
|
|
11
|
+
const full = projectRoot ? `${projectRoot}/${candidate}` : candidate;
|
|
12
|
+
if (tree.exists(full)) {
|
|
13
|
+
return full;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
function quote(value) {
|
|
19
|
+
return `'${value}'`;
|
|
20
|
+
}
|
|
21
|
+
function buildThemeEntry(options) {
|
|
22
|
+
const themeEntries = [];
|
|
23
|
+
if (options.colorScheme && options.colorScheme !== 'system') {
|
|
24
|
+
themeEntries.push(`colorScheme: ${quote(options.colorScheme)}`);
|
|
25
|
+
}
|
|
26
|
+
if (options.density && options.density !== 'comfortable') {
|
|
27
|
+
themeEntries.push(`density: ${quote(options.density)}`);
|
|
28
|
+
}
|
|
29
|
+
if (options.reducedMotion && options.reducedMotion !== 'auto') {
|
|
30
|
+
themeEntries.push(`reducedMotion: ${quote(options.reducedMotion)}`);
|
|
31
|
+
}
|
|
32
|
+
if (themeEntries.length === 0) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const indented = themeEntries.map((e) => ` ${e}`).join(',\n');
|
|
36
|
+
return ` theme: {\n${indented},\n }`;
|
|
37
|
+
}
|
|
38
|
+
function buildProviderConfig(options) {
|
|
39
|
+
const themeEntry = buildThemeEntry(options);
|
|
40
|
+
const topEntries = themeEntry ? [themeEntry] : [];
|
|
41
|
+
if (topEntries.length === 0) {
|
|
42
|
+
return 'provideSolaris(),';
|
|
43
|
+
}
|
|
44
|
+
const indented = topEntries.map((e) => ` ${e}`).join(',\n');
|
|
45
|
+
return `provideSolaris({\n${indented},\n }),`;
|
|
46
|
+
}
|
|
47
|
+
function addProvideSolarisImport(content, importStatement) {
|
|
48
|
+
if (content.includes(importStatement)) {
|
|
49
|
+
return content;
|
|
50
|
+
}
|
|
51
|
+
const importRegex = /^import\s/gm;
|
|
52
|
+
const matches = [...content.matchAll(importRegex)];
|
|
53
|
+
if (matches.length === 0) {
|
|
54
|
+
return `${importStatement}\n\n${content}`;
|
|
55
|
+
}
|
|
56
|
+
const lastImport = matches[matches.length - 1];
|
|
57
|
+
const lastImportIndex = lastImport.index;
|
|
58
|
+
if (lastImportIndex === undefined) {
|
|
59
|
+
return `${importStatement}\n\n${content}`;
|
|
60
|
+
}
|
|
61
|
+
const importEnd = content.indexOf(';', lastImportIndex) + 1;
|
|
62
|
+
return `${content.slice(0, importEnd)}\n${importStatement}${content.slice(importEnd)}`;
|
|
63
|
+
}
|
|
64
|
+
function addProvideSolarisToProviders(content, providerEntry) {
|
|
65
|
+
if (/provideSolaris\s*\(/.test(content)) {
|
|
66
|
+
return content;
|
|
67
|
+
}
|
|
68
|
+
const providersMatch = content.match(/providers:\s*\[([\s\S]*?)\]/);
|
|
69
|
+
if (providersMatch) {
|
|
70
|
+
const providersContent = providersMatch[1];
|
|
71
|
+
const entry = providersContent.trim().length === 0
|
|
72
|
+
? `\n ${providerEntry}\n `
|
|
73
|
+
: `${providersContent}\n ${providerEntry}`;
|
|
74
|
+
return content.replace(providersMatch[0], `providers: [${entry}]`);
|
|
75
|
+
}
|
|
76
|
+
return content;
|
|
77
|
+
}
|
|
78
|
+
function updateAppConfig(tree, appConfigPath, options) {
|
|
79
|
+
const existingContent = tree.readText(appConfigPath);
|
|
80
|
+
if (/provideSolaris\s*\(/.test(existingContent)) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
const importStatement = `import { provideSolaris } from '@educarehq/solaris-ui';`;
|
|
84
|
+
const providerEntry = buildProviderConfig(options);
|
|
85
|
+
let updated = addProvideSolarisImport(existingContent, importStatement);
|
|
86
|
+
updated = addProvideSolarisToProviders(updated, providerEntry);
|
|
87
|
+
tree.overwrite(appConfigPath, updated);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://educarehq.github.io/solaris-ui/schematics/init.schema.json",
|
|
4
|
+
"title": "Solaris UI init options",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"project": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "The name of the project to add Solaris UI to",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "projectName"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"colorScheme": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"enum": ["light", "dark", "system"],
|
|
17
|
+
"default": "system",
|
|
18
|
+
"description": "Default color scheme",
|
|
19
|
+
"x-prompt": "Which color scheme should Solaris use by default?"
|
|
20
|
+
},
|
|
21
|
+
"density": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"enum": ["comfortable", "compact"],
|
|
24
|
+
"default": "comfortable",
|
|
25
|
+
"description": "Default density",
|
|
26
|
+
"x-prompt": "Which density should Solaris use by default?"
|
|
27
|
+
},
|
|
28
|
+
"radius": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"enum": ["none", "sm", "md", "lg", "xl", "full"],
|
|
31
|
+
"default": "md",
|
|
32
|
+
"description": "Default border radius",
|
|
33
|
+
"x-prompt": "Which border radius should Solaris use by default?"
|
|
34
|
+
},
|
|
35
|
+
"reducedMotion": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"enum": ["auto", "reduce", "no-preference"],
|
|
38
|
+
"default": "auto",
|
|
39
|
+
"description": "Reduced motion preference",
|
|
40
|
+
"x-prompt": "Which reduced-motion preference should Solaris use by default?"
|
|
41
|
+
},
|
|
42
|
+
"skipStyles": {
|
|
43
|
+
"type": "boolean",
|
|
44
|
+
"description": "Skip creating the solaris.scss style setup file",
|
|
45
|
+
"default": false
|
|
46
|
+
},
|
|
47
|
+
"skipProviders": {
|
|
48
|
+
"type": "boolean",
|
|
49
|
+
"description": "Skip adding provideSolaris to the application config",
|
|
50
|
+
"default": false
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"required": []
|
|
54
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SOLARIS_STYLE_PATH = void 0;
|
|
4
|
+
exports.getGlobalStylesPath = getGlobalStylesPath;
|
|
5
|
+
exports.getSolarisStyleContent = getSolarisStyleContent;
|
|
6
|
+
exports.createSolarisStyleFile = createSolarisStyleFile;
|
|
7
|
+
exports.importSolarisStyleFromGlobal = importSolarisStyleFromGlobal;
|
|
8
|
+
exports.SOLARIS_STYLE_PATH = 'src/styles/solaris.scss';
|
|
9
|
+
const STYLE_CANDIDATES = [
|
|
10
|
+
'src/styles.scss',
|
|
11
|
+
'src/styles.sass',
|
|
12
|
+
'src/styles.css',
|
|
13
|
+
'src/style.scss',
|
|
14
|
+
'src/style.sass',
|
|
15
|
+
'src/style.css',
|
|
16
|
+
];
|
|
17
|
+
function getGlobalStylesPath(tree, projectRoot) {
|
|
18
|
+
for (const candidate of STYLE_CANDIDATES) {
|
|
19
|
+
const full = candidate;
|
|
20
|
+
if (tree.exists(full)) {
|
|
21
|
+
return full;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
for (const candidate of STYLE_CANDIDATES) {
|
|
25
|
+
const full = projectRoot ? `${projectRoot}/${candidate}` : candidate;
|
|
26
|
+
if (tree.exists(full)) {
|
|
27
|
+
return full;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function getSolarisStyleContent(options, usePath) {
|
|
33
|
+
const themeConfig = [
|
|
34
|
+
` color-scheme: ${options.colorScheme ?? 'system'},`,
|
|
35
|
+
` density: ${options.density ?? 'comfortable'},`,
|
|
36
|
+
` radius: ${options.radius ?? 'md'},`,
|
|
37
|
+
` motion: ${options.motion ?? 'auto'},`,
|
|
38
|
+
].join('\n');
|
|
39
|
+
return `@use '${usePath}' as solaris;
|
|
40
|
+
|
|
41
|
+
@include solaris.core();
|
|
42
|
+
|
|
43
|
+
@include solaris.theme(
|
|
44
|
+
(
|
|
45
|
+
${themeConfig}
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
50
|
+
function createSolarisStyleFile(tree, projectRoot, options, usePath = '@educarehq/solaris-ui/styles') {
|
|
51
|
+
const fullPath = projectRoot
|
|
52
|
+
? `${projectRoot}/${exports.SOLARIS_STYLE_PATH}`
|
|
53
|
+
: exports.SOLARIS_STYLE_PATH;
|
|
54
|
+
if (tree.exists(fullPath)) {
|
|
55
|
+
return fullPath;
|
|
56
|
+
}
|
|
57
|
+
tree.create(fullPath, getSolarisStyleContent(options, usePath));
|
|
58
|
+
return fullPath;
|
|
59
|
+
}
|
|
60
|
+
function importStatementFor(path) {
|
|
61
|
+
const relative = path
|
|
62
|
+
.replace(/^src\//, './')
|
|
63
|
+
.replace(/\.(scss|sass|css)$/, '');
|
|
64
|
+
return `@use '${relative}';`;
|
|
65
|
+
}
|
|
66
|
+
function importSolarisStyleFromGlobal(tree, globalStylesPath, solarisStylePath) {
|
|
67
|
+
const content = tree.readText(globalStylesPath);
|
|
68
|
+
const importStatement = importStatementFor(solarisStylePath);
|
|
69
|
+
if (content.includes(importStatement)) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
const updated = `${importStatement}\n\n${content}`;
|
|
73
|
+
tree.overwrite(globalStylesPath, updated);
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWorkspace = getWorkspace;
|
|
4
|
+
exports.getProject = getProject;
|
|
5
|
+
exports.getProjectTargetPath = getProjectTargetPath;
|
|
6
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
7
|
+
function stripJsonComments(content) {
|
|
8
|
+
return content
|
|
9
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
10
|
+
.replace(/(^|[^:])\/\/.*$/gm, '$1');
|
|
11
|
+
}
|
|
12
|
+
function getWorkspace(tree) {
|
|
13
|
+
for (const file of ['angular.json', 'workspace.json']) {
|
|
14
|
+
if (tree.exists(file)) {
|
|
15
|
+
try {
|
|
16
|
+
const parsed = JSON.parse(stripJsonComments(tree.readText(file)));
|
|
17
|
+
if (parsed?.projects) {
|
|
18
|
+
return parsed;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
throw new schematics_1.SchematicsException(`Failed to parse ${file}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
function getProject(tree, projectName) {
|
|
29
|
+
const workspace = getWorkspace(tree);
|
|
30
|
+
if (!workspace) {
|
|
31
|
+
throw new schematics_1.SchematicsException('No angular.json or workspace.json found. Run this schematic inside an Angular workspace.');
|
|
32
|
+
}
|
|
33
|
+
const name = projectName ?? workspace.defaultProject;
|
|
34
|
+
if (!name) {
|
|
35
|
+
throw new schematics_1.SchematicsException('No project name provided and no default project found in the workspace.');
|
|
36
|
+
}
|
|
37
|
+
const project = workspace.projects[name];
|
|
38
|
+
if (!project) {
|
|
39
|
+
throw new schematics_1.SchematicsException(`Project "${name}" not found in the workspace.`);
|
|
40
|
+
}
|
|
41
|
+
return { name, root: project.root ?? '', projectType: project.projectType };
|
|
42
|
+
}
|
|
43
|
+
function getProjectTargetPath(tree, projectName) {
|
|
44
|
+
return getProject(tree, projectName).root;
|
|
45
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ngAdd = ngAdd;
|
|
4
|
+
const index_1 = require("../init/index");
|
|
5
|
+
const styles_1 = require("../init/styles");
|
|
6
|
+
const workspace_1 = require("../init/workspace");
|
|
7
|
+
const messages_1 = require("../init/messages");
|
|
8
|
+
const COMPONENT_STYLES = [
|
|
9
|
+
'button',
|
|
10
|
+
'icon-button',
|
|
11
|
+
'input',
|
|
12
|
+
'textarea',
|
|
13
|
+
'popover',
|
|
14
|
+
'tooltip',
|
|
15
|
+
'toast',
|
|
16
|
+
'dropdown-menu',
|
|
17
|
+
];
|
|
18
|
+
function removeOldComponentImports(content) {
|
|
19
|
+
const lines = content.split('\n');
|
|
20
|
+
const kept = [];
|
|
21
|
+
for (const line of lines) {
|
|
22
|
+
const trimmed = line.trim();
|
|
23
|
+
// Remove @use of individual component stylesheets
|
|
24
|
+
const componentMatch = trimmed.match(/^@use\s+['"]@educarehq\/solaris-ui\/styles\/(\w+)['"]\s*;?\s*$/);
|
|
25
|
+
if (componentMatch && COMPONENT_STYLES.includes(componentMatch[1])) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
// Remove @use of the old _components shortcut
|
|
29
|
+
if (/^@use\s+['"]@educarehq\/solaris-ui\/styles\/components['"]\s*;?\s*$/.test(trimmed)) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
kept.push(line);
|
|
33
|
+
}
|
|
34
|
+
return kept.join('\n');
|
|
35
|
+
}
|
|
36
|
+
function cleanLegacyStyleImports(tree, context, projectRoot) {
|
|
37
|
+
const stylesPath = (0, styles_1.getGlobalStylesPath)(tree, projectRoot);
|
|
38
|
+
if (!stylesPath) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const content = tree.readText(stylesPath);
|
|
42
|
+
const cleaned = removeOldComponentImports(content);
|
|
43
|
+
if (cleaned !== content) {
|
|
44
|
+
tree.overwrite(stylesPath, cleaned);
|
|
45
|
+
(0, messages_1.logChange)(context, `Removed legacy Solaris style imports from ${stylesPath}`);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
(0, messages_1.logSkip)(context, `No legacy Solaris style imports in ${stylesPath}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function ngAdd(options) {
|
|
52
|
+
return (tree, context) => {
|
|
53
|
+
const project = (0, workspace_1.getProject)(tree, options.project);
|
|
54
|
+
// Clean up legacy individual component style imports before delegating.
|
|
55
|
+
cleanLegacyStyleImports(tree, context, project.root);
|
|
56
|
+
const initOptions = {
|
|
57
|
+
project: project.name,
|
|
58
|
+
colorScheme: options.colorScheme,
|
|
59
|
+
density: options.density,
|
|
60
|
+
radius: options.radius,
|
|
61
|
+
reducedMotion: options.reducedMotion,
|
|
62
|
+
};
|
|
63
|
+
const initRule = (0, index_1.init)(initOptions);
|
|
64
|
+
return initRule(tree, context);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://educarehq.github.io/solaris-ui/schematics/ng-add.schema.json",
|
|
4
|
+
"title": "Solaris UI ng-add options",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"project": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "The name of the project to add Solaris UI to",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "projectName"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"colorScheme": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"enum": ["light", "dark", "system"],
|
|
17
|
+
"default": "system",
|
|
18
|
+
"description": "Default color scheme"
|
|
19
|
+
},
|
|
20
|
+
"density": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"enum": ["comfortable", "compact"],
|
|
23
|
+
"default": "comfortable",
|
|
24
|
+
"description": "Default density"
|
|
25
|
+
},
|
|
26
|
+
"radius": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"enum": ["none", "sm", "md", "lg", "xl", "full"],
|
|
29
|
+
"default": "md",
|
|
30
|
+
"description": "Default border radius"
|
|
31
|
+
},
|
|
32
|
+
"reducedMotion": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"enum": ["auto", "reduce", "no-preference"],
|
|
35
|
+
"default": "auto",
|
|
36
|
+
"description": "Reduced motion preference"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"required": []
|
|
40
|
+
}
|