tailjng 0.1.2 → 0.1.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 +32 -9
- package/cli/execute/init-app.js +22 -42
- package/cli/execute/sync-app.js +192 -0
- package/cli/index.js +8 -1
- package/cli/settings/colors-config-utils.js +188 -0
- package/cli/settings/init-packages.js +39 -0
- package/cli/settings/project-utils.js +50 -24
- package/cli/templates/app.generator.js +2 -0
- package/package.json +1 -1
- package/registry/components.json +1 -1
- package/src/colors.safelist.css +28 -3
- package/src/lib/components/colors-config/README.md +38 -0
- package/src/lib/components/colors-config/colors.config.ts +101 -8
- package/src/lib/components/colors-config/colors.safelist.css +29 -7
- package/tailjng-0.1.4.tgz +0 -0
- package/src/lib/components/colors-config/colors-config.component.ts +0 -12
- package/tailjng-0.1.2.tgz +0 -0
package/README.md
CHANGED
|
@@ -134,24 +134,46 @@ import { JAlertToastComponent } from './tailjng/alert/alert-toast/toast-alert.co
|
|
|
134
134
|
<JButton [text]="'Guardar'" classes="primary" [icon]="icons.save" (clicked)="save()" />
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
### Colores — `
|
|
137
|
+
### Colores — `src/app/tailjng/colors/`
|
|
138
138
|
|
|
139
|
-
Las variantes (`primary`, `success_soft`, …) las resuelve **`JColorsService
|
|
139
|
+
Las variantes (`primary`, `success_soft`, …) las resuelve **`JColorsService`**. Tailwind v4 no genera clases solo en runtime, así que cada proyecto tiene una carpeta editable:
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
| Archivo | Para qué |
|
|
142
|
+
|---------|----------|
|
|
143
|
+
| `colors.config.ts` | Lista de variantes (incluye las 77 por defecto) + las tuyas (`brand`, etc.) |
|
|
144
|
+
| `colors.safelist.css` | Clases Tailwind que el build debe generar (`@apply`) |
|
|
142
145
|
|
|
143
|
-
|
|
146
|
+
**`init:app`** y **`sync:app`** crean esa carpeta (sin sobrescribir si ya existe), importan `colors.safelist.css` en `styles.css` y registran `tailjngColorsProvider`.
|
|
147
|
+
|
|
148
|
+
Si falta la carpeta en un proyecto existente:
|
|
144
149
|
|
|
145
150
|
```powershell
|
|
146
|
-
npx tailjng
|
|
151
|
+
npx tailjng sync:app
|
|
152
|
+
# o solo los archivos:
|
|
153
|
+
npx tailjng add colors
|
|
147
154
|
```
|
|
148
155
|
|
|
149
|
-
|
|
156
|
+
**Añadir un color propio** — edita `colors.config.ts` y registra las clases nuevas en el bloque `.__tailjng_custom_colors__` de `colors.safelist.css`:
|
|
150
157
|
|
|
151
|
-
|
|
152
|
-
|
|
158
|
+
```typescript
|
|
159
|
+
// colors.config.ts
|
|
160
|
+
brand: 'bg-indigo-600 text-white hover:bg-indigo-700 border border-indigo-500 shadow-md',
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```css
|
|
164
|
+
/* colors.safelist.css */
|
|
165
|
+
.__tailjng_custom_colors__ {
|
|
166
|
+
@apply bg-indigo-600 text-white hover:bg-indigo-700 border-indigo-500;
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Uso en componentes:
|
|
171
|
+
|
|
172
|
+
```html
|
|
173
|
+
<JButton classes="brand" text="Guardar" />
|
|
174
|
+
```
|
|
153
175
|
|
|
154
|
-
|
|
176
|
+
`init:app` / `sync:app` registran el provider automáticamente. Manualmente en `app.config.ts`:
|
|
155
177
|
|
|
156
178
|
```typescript
|
|
157
179
|
import { tailjngColorsProvider } from './tailjng/colors/colors.config';
|
|
@@ -204,6 +226,7 @@ Pasa `endpoint`, `type="searchable"` o `loadOnInit` según el componente; usa `J
|
|
|
204
226
|
| `npx tailjng init:app` | Prepara proyecto: Tailwind, deps, providers, estilos |
|
|
205
227
|
| `npx tailjng init:app --yes` | Sin prompts interactivos |
|
|
206
228
|
| `npx tailjng init:app --with-components` | init + mode-toggle y alerts |
|
|
229
|
+
| `npx tailjng sync:app` | Tras `npm install tailjng@latest` — solo lo nuevo (estilos, deps, angular.json) |
|
|
207
230
|
| `npx tailjng add <nombre>` | Instala componente + dependencias |
|
|
208
231
|
| `npx tailjng install-all` | Instala los 35 componentes |
|
|
209
232
|
| `npx tailjng list` | Lista registry e indica cuáles ya están instalados |
|
package/cli/execute/init-app.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { execSync } = require('child_process');
|
|
4
3
|
const readline = require('readline');
|
|
5
4
|
const { COLORS } = require('../settings/colors');
|
|
6
5
|
const { addComponent } = require('../component-manager');
|
|
7
6
|
const { getComponentList } = require('../settings/components-list');
|
|
8
7
|
const { buildInitFiles } = require('../templates/app.generator');
|
|
8
|
+
const { RUNTIME_PACKAGES, DEV_PACKAGES, installPackages } = require('../settings/init-packages');
|
|
9
9
|
const {
|
|
10
10
|
findAngularWorkspace,
|
|
11
11
|
readJson,
|
|
@@ -25,25 +25,14 @@ const {
|
|
|
25
25
|
hasTailwindSetup,
|
|
26
26
|
getTailjngSafelistCssImport,
|
|
27
27
|
ensureTailjngSafelistImport,
|
|
28
|
+
alignAngularAnimationsInPackageJson,
|
|
28
29
|
resolveStyleFilePath,
|
|
29
30
|
fileExists,
|
|
30
31
|
} = require('../settings/project-utils');
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
'date-fns': '^4.1.0',
|
|
36
|
-
'exceljs': '^4.4.0',
|
|
37
|
-
'xlsx': '^0.18.5',
|
|
38
|
-
'file-saver': '^2.0.5',
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const DEV_PACKAGES = {
|
|
42
|
-
tailwindcss: '^4.0.9',
|
|
43
|
-
'@tailwindcss/postcss': '^4.0.9',
|
|
44
|
-
postcss: '^8.5.3',
|
|
45
|
-
autoprefixer: '^10.4.20',
|
|
46
|
-
};
|
|
32
|
+
const {
|
|
33
|
+
ensureProjectColorsConfig,
|
|
34
|
+
patchAppConfigColors,
|
|
35
|
+
} = require('../settings/colors-config-utils');
|
|
47
36
|
|
|
48
37
|
/** Solo si pasas --with-components (opcional; no es el flujo normal). */
|
|
49
38
|
const OPTIONAL_BASE_COMPONENTS = ['mode-toggle', 'alert-dialog', 'alert-toast'];
|
|
@@ -80,30 +69,6 @@ function askYesNo(question, defaultYes = true) {
|
|
|
80
69
|
});
|
|
81
70
|
}
|
|
82
71
|
|
|
83
|
-
function installPackages(workspaceRoot, packages, isDev = false) {
|
|
84
|
-
const entries = Object.entries(packages);
|
|
85
|
-
if (entries.length === 0) return;
|
|
86
|
-
|
|
87
|
-
const spec = entries.map(([name, version]) => `${name}@${version}`).join(' ');
|
|
88
|
-
const flag = isDev ? '--save-dev' : '--save';
|
|
89
|
-
console.log(`${COLORS.blue}[tailjng CLI] Installing ${isDev ? 'dev ' : ''}dependencies...${COLORS.reset}`);
|
|
90
|
-
|
|
91
|
-
const run = (extra = '') => {
|
|
92
|
-
execSync(`npm install ${flag} ${extra} ${spec}`.replace(/\s+/g, ' ').trim(), {
|
|
93
|
-
cwd: workspaceRoot,
|
|
94
|
-
stdio: 'inherit',
|
|
95
|
-
shell: true,
|
|
96
|
-
});
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
run();
|
|
101
|
-
} catch {
|
|
102
|
-
console.log(`${COLORS.yellow}[tailjng CLI] Retrying with --legacy-peer-deps...${COLORS.reset}`);
|
|
103
|
-
run('--legacy-peer-deps');
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
72
|
function resolveTargetPath(workspaceRoot, appProject, relativePath, appRootRelative = false) {
|
|
108
73
|
const appRoot = path.join(workspaceRoot, appProject.root || '');
|
|
109
74
|
|
|
@@ -180,12 +145,19 @@ async function runInitApp() {
|
|
|
180
145
|
console.log(`${COLORS.yellow}Install it first: npm install tailjng${COLORS.reset}`);
|
|
181
146
|
}
|
|
182
147
|
|
|
148
|
+
// Siempre alinear @angular/animations con la versión real de @angular/core del proyecto
|
|
149
|
+
const animationsAligned = alignAngularAnimationsInPackageJson(workspaceRoot);
|
|
150
|
+
if (animationsAligned.changed) {
|
|
151
|
+
console.log(`${COLORS.cyan}[tailjng CLI] Aligned @angular/animations → ${animationsAligned.version} (same as @angular/core)${COLORS.reset}`);
|
|
152
|
+
Object.assign(packageJson, readJson(packageJsonPath));
|
|
153
|
+
}
|
|
154
|
+
|
|
183
155
|
if (installDeps) {
|
|
184
156
|
if (tailwindReady) {
|
|
185
157
|
console.log(`${COLORS.cyan}[tailjng CLI] Tailwind already configured — skipping Tailwind/PostCSS packages and .postcssrc.json${COLORS.reset}`);
|
|
186
158
|
}
|
|
187
159
|
|
|
188
|
-
const runtimePackages = resolveRuntimePackages(packageJson, RUNTIME_PACKAGES);
|
|
160
|
+
const runtimePackages = resolveRuntimePackages(packageJson, RUNTIME_PACKAGES, workspaceRoot);
|
|
189
161
|
const devPackages = resolveDevPackages(packageJson, DEV_PACKAGES, tailwindReady);
|
|
190
162
|
const missingRuntime = Object.fromEntries(getMissingPackages(packageJson, runtimePackages, workspaceRoot));
|
|
191
163
|
const missingDev = Object.fromEntries(getMissingPackages(packageJson, devPackages, workspaceRoot));
|
|
@@ -198,6 +170,9 @@ async function runInitApp() {
|
|
|
198
170
|
installPackages(workspaceRoot, missingDev, true);
|
|
199
171
|
}
|
|
200
172
|
|
|
173
|
+
const { appRoot } = resolveAppPaths(workspaceRoot, selectedApp);
|
|
174
|
+
ensureProjectColorsConfig(workspaceRoot, appRoot, overwrite);
|
|
175
|
+
|
|
201
176
|
const hasAppConfig = fileExists(appConfigPath);
|
|
202
177
|
const safelistImport = getTailjngSafelistCssImport(workspaceRoot, primaryStylePath, selectedApp);
|
|
203
178
|
const primaryStyleFullPath = resolveStyleFilePath(workspaceRoot, primaryStylePath, selectedApp);
|
|
@@ -246,6 +221,11 @@ async function runInitApp() {
|
|
|
246
221
|
if (patched.changed) {
|
|
247
222
|
console.log(`${COLORS.green}✔ Patched ${path.relative(workspaceRoot, appConfigPath)}${COLORS.reset}`);
|
|
248
223
|
}
|
|
224
|
+
|
|
225
|
+
const colorsPatched = patchAppConfigColors(appConfigPath, srcRoot);
|
|
226
|
+
if (colorsPatched.changed) {
|
|
227
|
+
console.log(`${COLORS.green}✔ Linked tailjngColorsProvider from src/app/tailjng/colors/${COLORS.reset}`);
|
|
228
|
+
}
|
|
249
229
|
}
|
|
250
230
|
|
|
251
231
|
const indexPatched = patchIndexHtml(indexPath);
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { COLORS } = require('../settings/colors');
|
|
4
|
+
const { RUNTIME_PACKAGES, DEV_PACKAGES, installPackages } = require('../settings/init-packages');
|
|
5
|
+
const { buildPathsJson, buildPathsReadme } = require('../templates/app.generator');
|
|
6
|
+
const {
|
|
7
|
+
findAngularWorkspace,
|
|
8
|
+
readJson,
|
|
9
|
+
getApplicationProjects,
|
|
10
|
+
resolveAppPaths,
|
|
11
|
+
getBuildOptions,
|
|
12
|
+
detectStyleLanguage,
|
|
13
|
+
getPrimaryStyleEntry,
|
|
14
|
+
writeFileSafe,
|
|
15
|
+
ensureTailjngStylesInAngularJson,
|
|
16
|
+
patchIndexHtml,
|
|
17
|
+
patchAppConfig,
|
|
18
|
+
getMissingPackages,
|
|
19
|
+
resolveRuntimePackages,
|
|
20
|
+
resolveDevPackages,
|
|
21
|
+
hasTailwindSetup,
|
|
22
|
+
getTailjngSafelistCssImport,
|
|
23
|
+
ensureTailjngSafelistImport,
|
|
24
|
+
alignAngularAnimationsInPackageJson,
|
|
25
|
+
resolveStyleFilePath,
|
|
26
|
+
fileExists,
|
|
27
|
+
} = require('../settings/project-utils');
|
|
28
|
+
const {
|
|
29
|
+
ensureProjectColorsConfig,
|
|
30
|
+
patchAppConfigColors,
|
|
31
|
+
COLORS_FILES,
|
|
32
|
+
} = require('../settings/colors-config-utils');
|
|
33
|
+
|
|
34
|
+
function resolveTargetPath(workspaceRoot, appProject, relativePath, appRootRelative = false) {
|
|
35
|
+
const appRoot = path.join(workspaceRoot, appProject.root || '');
|
|
36
|
+
|
|
37
|
+
if (appRootRelative) {
|
|
38
|
+
return path.join(appRoot, relativePath);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (relativePath.startsWith('projects/')) {
|
|
42
|
+
return path.join(workspaceRoot, relativePath);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return path.join(workspaceRoot, appProject.sourceRoot, relativePath.replace(/^src\//, ''));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function runSyncApp() {
|
|
49
|
+
const workspace = findAngularWorkspace(process.cwd());
|
|
50
|
+
|
|
51
|
+
if (!workspace) {
|
|
52
|
+
console.error(`${COLORS.red}[tailjng CLI] ERROR: angular.json not found. Run this inside an Angular project.${COLORS.reset}`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const { workspaceRoot, angularJsonPath } = workspace;
|
|
57
|
+
const angularJson = readJson(angularJsonPath);
|
|
58
|
+
const apps = getApplicationProjects(angularJson);
|
|
59
|
+
|
|
60
|
+
if (apps.length === 0) {
|
|
61
|
+
console.error(`${COLORS.red}[tailjng CLI] ERROR: No application project found in angular.json.${COLORS.reset}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const selectedApp = apps[0];
|
|
66
|
+
const { appRoot, srcRoot } = resolveAppPaths(workspaceRoot, selectedApp);
|
|
67
|
+
const buildOptions = getBuildOptions(angularJson, selectedApp.name);
|
|
68
|
+
const styleLanguage = detectStyleLanguage(buildOptions);
|
|
69
|
+
const primaryStylePath = getPrimaryStyleEntry(buildOptions);
|
|
70
|
+
const primaryStyleFullPath = resolveStyleFilePath(workspaceRoot, primaryStylePath, selectedApp);
|
|
71
|
+
const indexPath = path.join(workspaceRoot, buildOptions.index || path.join(selectedApp.sourceRoot, 'index.html'));
|
|
72
|
+
const appConfigPath = path.join(srcRoot, 'app', 'app.config.ts');
|
|
73
|
+
const packageJsonPath = path.join(workspaceRoot, 'package.json');
|
|
74
|
+
const packageJson = fileExists(packageJsonPath) ? readJson(packageJsonPath) : { dependencies: {}, devDependencies: {} };
|
|
75
|
+
const tailwindReady = hasTailwindSetup(workspaceRoot, packageJson, primaryStylePath);
|
|
76
|
+
const installDeps = !process.argv.includes('--no-install');
|
|
77
|
+
const componentsPath = 'src/app/tailjng';
|
|
78
|
+
|
|
79
|
+
console.log(`\n${COLORS.bright}${COLORS.blue}[tailjng CLI] sync:app${COLORS.reset}`);
|
|
80
|
+
console.log(`${COLORS.dim}Updates integration only — does not overwrite your config (environment, providers, styles).${COLORS.reset}`);
|
|
81
|
+
console.log(`${COLORS.dim}Workspace: ${workspaceRoot} | App: ${selectedApp.name}${COLORS.reset}\n`);
|
|
82
|
+
|
|
83
|
+
if (!packageJson.dependencies?.tailjng) {
|
|
84
|
+
console.log(`${COLORS.yellow}[tailjng CLI] WARNING: tailjng is not in package.json. Run: npm install tailjng@latest --legacy-peer-deps${COLORS.reset}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let changes = 0;
|
|
88
|
+
|
|
89
|
+
const animationsAligned = alignAngularAnimationsInPackageJson(workspaceRoot);
|
|
90
|
+
if (animationsAligned.changed) {
|
|
91
|
+
changes += 1;
|
|
92
|
+
console.log(`${COLORS.green}✔ Aligned @angular/animations → ${animationsAligned.version}${COLORS.reset}`);
|
|
93
|
+
Object.assign(packageJson, readJson(packageJsonPath));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (installDeps) {
|
|
97
|
+
const runtimePackages = resolveRuntimePackages(packageJson, RUNTIME_PACKAGES, workspaceRoot);
|
|
98
|
+
const devPackages = resolveDevPackages(packageJson, DEV_PACKAGES, tailwindReady);
|
|
99
|
+
const missingRuntime = Object.fromEntries(getMissingPackages(packageJson, runtimePackages, workspaceRoot));
|
|
100
|
+
const missingDev = Object.fromEntries(getMissingPackages(packageJson, devPackages, workspaceRoot));
|
|
101
|
+
|
|
102
|
+
if (Object.keys(missingRuntime).length > 0) {
|
|
103
|
+
installPackages(workspaceRoot, missingRuntime, false);
|
|
104
|
+
changes += 1;
|
|
105
|
+
console.log(`${COLORS.green}✔ Installed missing runtime packages${COLORS.reset}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (Object.keys(missingDev).length > 0) {
|
|
109
|
+
installPackages(workspaceRoot, missingDev, true);
|
|
110
|
+
changes += 1;
|
|
111
|
+
console.log(`${COLORS.green}✔ Installed missing dev packages${COLORS.reset}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (Object.keys(missingRuntime).length === 0 && Object.keys(missingDev).length === 0) {
|
|
115
|
+
console.log(`${COLORS.dim}↷ Dependencies already satisfied${COLORS.reset}`);
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
console.log(`${COLORS.dim}↷ Skipped dependency install (--no-install)${COLORS.reset}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const pathsJsonPath = resolveTargetPath(workspaceRoot, selectedApp, '.tailjng/paths.json', true);
|
|
122
|
+
if (writeFileSafe(pathsJsonPath, buildPathsJson(componentsPath), false)) {
|
|
123
|
+
changes += 1;
|
|
124
|
+
console.log(`${COLORS.green}✔ Created ${path.relative(workspaceRoot, pathsJsonPath)}${COLORS.reset}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const pathsReadmePath = resolveTargetPath(workspaceRoot, selectedApp, '.tailjng/README.md', true);
|
|
128
|
+
if (writeFileSafe(pathsReadmePath, buildPathsReadme(), false)) {
|
|
129
|
+
changes += 1;
|
|
130
|
+
console.log(`${COLORS.green}✔ Created ${path.relative(workspaceRoot, pathsReadmePath)}${COLORS.reset}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const colorsResult = ensureProjectColorsConfig(workspaceRoot, appRoot, false);
|
|
134
|
+
if (colorsResult.created > 0) {
|
|
135
|
+
changes += colorsResult.created;
|
|
136
|
+
} else if (colorsResult.skipped === COLORS_FILES.length) {
|
|
137
|
+
console.log(`${COLORS.dim}↷ Project colors config already present${COLORS.reset}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const safelistImport = getTailjngSafelistCssImport(workspaceRoot, primaryStylePath, selectedApp);
|
|
141
|
+
const safelistPatched = ensureTailjngSafelistImport(primaryStyleFullPath, safelistImport);
|
|
142
|
+
if (safelistPatched.changed) {
|
|
143
|
+
changes += 1;
|
|
144
|
+
const label = safelistPatched.migrated
|
|
145
|
+
? 'Migrated colors safelist to project folder'
|
|
146
|
+
: 'Added tailjng colors safelist';
|
|
147
|
+
console.log(`${COLORS.green}✔ ${label} → ${path.relative(workspaceRoot, primaryStyleFullPath)}${COLORS.reset}`);
|
|
148
|
+
} else {
|
|
149
|
+
console.log(`${COLORS.dim}↷ Colors safelist already in styles${COLORS.reset}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const stylesPatched = ensureTailjngStylesInAngularJson(angularJsonPath, selectedApp.name, styleLanguage);
|
|
153
|
+
if (stylesPatched.changed) {
|
|
154
|
+
changes += 1;
|
|
155
|
+
console.log(`${COLORS.green}✔ Added node_modules/tailjng/src/styles.css to angular.json${COLORS.reset}`);
|
|
156
|
+
} else {
|
|
157
|
+
console.log(`${COLORS.dim}↷ tailjng styles already in angular.json${COLORS.reset}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (fileExists(appConfigPath)) {
|
|
161
|
+
const patched = patchAppConfig(appConfigPath);
|
|
162
|
+
if (patched.changed) {
|
|
163
|
+
changes += 1;
|
|
164
|
+
console.log(`${COLORS.green}✔ Patched app.config.ts (added tailjngProviders)${COLORS.reset}`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const colorsPatched = patchAppConfigColors(appConfigPath, srcRoot);
|
|
168
|
+
if (colorsPatched.changed) {
|
|
169
|
+
changes += 1;
|
|
170
|
+
console.log(`${COLORS.green}✔ Linked tailjngColorsProvider from src/app/tailjng/colors/${COLORS.reset}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (patchIndexHtml(indexPath)) {
|
|
175
|
+
changes += 1;
|
|
176
|
+
console.log(`${COLORS.green}✔ Patched index.html (body classes)${COLORS.reset}`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
console.log(`\n${COLORS.greenBright}${COLORS.bright}[tailjng CLI] sync:app completed.${COLORS.reset}`);
|
|
180
|
+
console.log(`${COLORS.dim}Changes applied: ${changes}${COLORS.reset}`);
|
|
181
|
+
|
|
182
|
+
if (changes === 0) {
|
|
183
|
+
console.log(`${COLORS.cyan}Project already up to date with this tailjng version.${COLORS.reset}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
console.log(`\n${COLORS.dim}Tip: update UI components with ${COLORS.cyan}npx tailjng add <name>${COLORS.reset}${COLORS.dim} (asks before overwrite).${COLORS.reset}\n`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
runSyncApp().catch((error) => {
|
|
190
|
+
console.error(`${COLORS.red}[tailjng CLI] sync:app failed:${COLORS.reset}`, error);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
});
|
package/cli/index.js
CHANGED
|
@@ -18,6 +18,11 @@ async function main() {
|
|
|
18
18
|
return
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
if (command === "sync:app") {
|
|
22
|
+
require("./execute/sync-app")
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
if (command === "add") {
|
|
22
27
|
const componentName = args[1]
|
|
23
28
|
if (!componentName) {
|
|
@@ -53,8 +58,10 @@ function showHelp() {
|
|
|
53
58
|
console.log(`${COLORS.bright}${COLORS.blue}tailjng CLI${COLORS.reset} v${getPackageVersion(__dirname)}
|
|
54
59
|
|
|
55
60
|
${COLORS.bright}Project setup${COLORS.reset}
|
|
56
|
-
${COLORS.cyan}npx tailjng init:app${COLORS.reset}
|
|
61
|
+
${COLORS.cyan}npx tailjng init:app${COLORS.reset} First-time setup (Tailwind, providers, styles)
|
|
57
62
|
${COLORS.cyan}npx tailjng init:app --with-components${COLORS.reset} init:app + mode-toggle and alerts
|
|
63
|
+
${COLORS.cyan}npx tailjng sync:app${COLORS.reset} Update integration after npm upgrade (no overwrite)
|
|
64
|
+
${COLORS.cyan}npx tailjng sync:app --no-install${COLORS.reset} sync:app without npm install
|
|
58
65
|
|
|
59
66
|
${COLORS.bright}Components${COLORS.reset} ${COLORS.dim}(run from your Angular app directory)${COLORS.reset}
|
|
60
67
|
${COLORS.cyan}npx tailjng add${COLORS.reset} ${COLORS.dim}<name>${COLORS.reset} Install one component + dependencies
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { COLORS } = require('./colors');
|
|
4
|
+
const { writeFileSafe } = require('./project-utils');
|
|
5
|
+
|
|
6
|
+
const COLORS_SOURCE_REL = 'src/lib/components/colors-config';
|
|
7
|
+
const COLORS_FILES = ['colors.config.ts', 'colors.safelist.css', 'README.md'];
|
|
8
|
+
|
|
9
|
+
function getProjectColorsDir(appRoot) {
|
|
10
|
+
return path.join(appRoot, 'src', 'app', 'tailjng', 'colors');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function resolveTailjngPackageRoot(workspaceRoot) {
|
|
14
|
+
const fromNodeModules = path.join(workspaceRoot, 'node_modules', 'tailjng', COLORS_SOURCE_REL);
|
|
15
|
+
if (fs.existsSync(fromNodeModules)) {
|
|
16
|
+
return path.join(workspaceRoot, 'node_modules', 'tailjng');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const fromMonorepo = path.join(workspaceRoot, 'projects', 'tailjng', COLORS_SOURCE_REL);
|
|
20
|
+
if (fs.existsSync(fromMonorepo)) {
|
|
21
|
+
return path.join(workspaceRoot, 'projects', 'tailjng');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getColorsSafelistImportLine(workspaceRoot, styleEntry, appProject) {
|
|
28
|
+
const appRoot = path.join(workspaceRoot, appProject.root || '');
|
|
29
|
+
const colorsSafelist = path.join(getProjectColorsDir(appRoot), 'colors.safelist.css');
|
|
30
|
+
|
|
31
|
+
let stylePath;
|
|
32
|
+
if (path.isAbsolute(styleEntry)) {
|
|
33
|
+
stylePath = styleEntry;
|
|
34
|
+
} else if (styleEntry.startsWith('projects/')) {
|
|
35
|
+
stylePath = path.join(workspaceRoot, styleEntry);
|
|
36
|
+
} else {
|
|
37
|
+
stylePath = path.join(appRoot, styleEntry);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const targetSafelist = fs.existsSync(colorsSafelist)
|
|
41
|
+
? colorsSafelist
|
|
42
|
+
: path.join(workspaceRoot, 'node_modules', 'tailjng', 'src', 'colors.safelist.css');
|
|
43
|
+
|
|
44
|
+
let rel = path.relative(path.dirname(stylePath), targetSafelist).split(path.sep).join('/');
|
|
45
|
+
if (!rel.startsWith('.')) rel = `./${rel}`;
|
|
46
|
+
return `@import "${rel}";`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function ensureProjectColorsConfig(workspaceRoot, appRoot, overwrite = false) {
|
|
50
|
+
const packageRoot = resolveTailjngPackageRoot(workspaceRoot);
|
|
51
|
+
if (!packageRoot) {
|
|
52
|
+
console.log(`${COLORS.yellow}[tailjng CLI] WARNING: tailjng package not found — skip colors config copy${COLORS.reset}`);
|
|
53
|
+
return { created: 0, skipped: 0, colorsDir: getProjectColorsDir(appRoot) };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const sourceDir = path.join(packageRoot, COLORS_SOURCE_REL);
|
|
57
|
+
const colorsDir = getProjectColorsDir(appRoot);
|
|
58
|
+
let created = 0;
|
|
59
|
+
let skipped = 0;
|
|
60
|
+
|
|
61
|
+
for (const file of COLORS_FILES) {
|
|
62
|
+
const src = path.join(sourceDir, file);
|
|
63
|
+
const dest = path.join(colorsDir, file);
|
|
64
|
+
if (!fs.existsSync(src)) continue;
|
|
65
|
+
|
|
66
|
+
const content = fs.readFileSync(src, 'utf8');
|
|
67
|
+
if (writeFileSafe(dest, content, overwrite)) {
|
|
68
|
+
created += 1;
|
|
69
|
+
console.log(`${COLORS.green}✔ Created ${path.relative(workspaceRoot, dest)}${COLORS.reset}`);
|
|
70
|
+
} else {
|
|
71
|
+
skipped += 1;
|
|
72
|
+
console.log(`${COLORS.dim}↷ Skipped (exists) ${path.relative(workspaceRoot, dest)}${COLORS.reset}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { created, skipped, colorsDir };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function ensureColorsSafelistImport(styleFilePath, importLine) {
|
|
80
|
+
if (!fs.existsSync(styleFilePath)) return { changed: false };
|
|
81
|
+
|
|
82
|
+
let content = fs.readFileSync(styleFilePath, 'utf8');
|
|
83
|
+
const projectImport = /tailjng\/colors\/colors\.safelist\.css/;
|
|
84
|
+
const npmImport = /node_modules\/tailjng\/src\/colors\.safelist\.css/;
|
|
85
|
+
const anySafelistImport = /@import\s+"[^"]*colors\.safelist\.css";?/;
|
|
86
|
+
|
|
87
|
+
if (projectImport.test(content)) {
|
|
88
|
+
return { changed: false };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (npmImport.test(content) && projectImport.test(importLine)) {
|
|
92
|
+
content = content.replace(anySafelistImport, importLine);
|
|
93
|
+
fs.writeFileSync(styleFilePath, content, 'utf8');
|
|
94
|
+
return { changed: true, migrated: true };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (content.includes('colors.safelist.css')) {
|
|
98
|
+
return { changed: false };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const tailwindMatch = content.match(/@(?:import|use)\s+"tailwindcss";?/);
|
|
102
|
+
if (tailwindMatch) {
|
|
103
|
+
const insertAt = tailwindMatch.index + tailwindMatch[0].length;
|
|
104
|
+
content = `${content.slice(0, insertAt)}\n${importLine}\n${content.slice(insertAt)}`;
|
|
105
|
+
} else {
|
|
106
|
+
content = `${importLine}\n${content}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
fs.writeFileSync(styleFilePath, content, 'utf8');
|
|
110
|
+
return { changed: true };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function patchTailjngProvidersColors(providersPath) {
|
|
114
|
+
if (!fs.existsSync(providersPath)) return { changed: false };
|
|
115
|
+
|
|
116
|
+
let content = fs.readFileSync(providersPath, 'utf8');
|
|
117
|
+
if (content.includes('tailjngColorsProvider') || content.includes('../tailjng/colors/colors.config')) {
|
|
118
|
+
return { changed: false };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const lines = content.split('\n');
|
|
122
|
+
let lastImport = -1;
|
|
123
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
124
|
+
if (lines[i].startsWith('import ')) lastImport = i;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const importLine = "import { tailjngColorsProvider } from '../tailjng/colors/colors.config';";
|
|
128
|
+
if (lastImport === -1) {
|
|
129
|
+
content = `${importLine}\n${content}`;
|
|
130
|
+
} else {
|
|
131
|
+
lines.splice(lastImport + 1, 0, importLine);
|
|
132
|
+
content = lines.join('\n');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (content.includes('export const tailjngProviders = [')) {
|
|
136
|
+
content = content.replace(
|
|
137
|
+
/export const tailjngProviders = \[/,
|
|
138
|
+
'export const tailjngProviders = [\n tailjngColorsProvider,',
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
fs.writeFileSync(providersPath, content, 'utf8');
|
|
143
|
+
return { changed: true };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function patchAppConfigColors(appConfigPath, srcRoot) {
|
|
147
|
+
const providersPath = path.join(srcRoot, 'app', 'config', 'tailjng.providers.ts');
|
|
148
|
+
if (fs.existsSync(providersPath)) {
|
|
149
|
+
return patchTailjngProvidersColors(providersPath);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!fs.existsSync(appConfigPath)) return { changed: false };
|
|
153
|
+
|
|
154
|
+
let content = fs.readFileSync(appConfigPath, 'utf8');
|
|
155
|
+
if (content.includes('tailjngColorsProvider') || content.includes('./tailjng/colors/colors.config')) {
|
|
156
|
+
return { changed: false };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const lines = content.split('\n');
|
|
160
|
+
let lastImport = -1;
|
|
161
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
162
|
+
if (lines[i].startsWith('import ')) lastImport = i;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const importLine = "import { tailjngColorsProvider } from './tailjng/colors/colors.config';";
|
|
166
|
+
if (lastImport === -1) {
|
|
167
|
+
content = `${importLine}\n${content}`;
|
|
168
|
+
} else {
|
|
169
|
+
lines.splice(lastImport + 1, 0, importLine);
|
|
170
|
+
content = lines.join('\n');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (content.includes('providers: [')) {
|
|
174
|
+
content = content.replace(/providers:\s*\[/, 'providers: [\n tailjngColorsProvider,');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
fs.writeFileSync(appConfigPath, content, 'utf8');
|
|
178
|
+
return { changed: true };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
module.exports = {
|
|
182
|
+
getProjectColorsDir,
|
|
183
|
+
getColorsSafelistImportLine,
|
|
184
|
+
ensureProjectColorsConfig,
|
|
185
|
+
ensureColorsSafelistImport,
|
|
186
|
+
patchAppConfigColors,
|
|
187
|
+
COLORS_FILES,
|
|
188
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
const { COLORS } = require('./colors');
|
|
3
|
+
|
|
4
|
+
const RUNTIME_PACKAGES = {
|
|
5
|
+
'lucide-angular': '^0.525.0',
|
|
6
|
+
'@ng-icons/lucide': '>=32.0.0',
|
|
7
|
+
'date-fns': '^4.1.0',
|
|
8
|
+
'exceljs': '^4.4.0',
|
|
9
|
+
'xlsx': '^0.18.5',
|
|
10
|
+
'file-saver': '^2.0.5',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const DEV_PACKAGES = {
|
|
14
|
+
tailwindcss: '^4.0.9',
|
|
15
|
+
'@tailwindcss/postcss': '^4.0.9',
|
|
16
|
+
postcss: '^8.5.3',
|
|
17
|
+
autoprefixer: '^10.4.20',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function installPackages(workspaceRoot, packages, isDev = false) {
|
|
21
|
+
const entries = Object.entries(packages);
|
|
22
|
+
if (entries.length === 0) return;
|
|
23
|
+
|
|
24
|
+
const spec = entries.map(([name, version]) => `${name}@${version}`).join(' ');
|
|
25
|
+
const flag = isDev ? '--save-dev' : '--save';
|
|
26
|
+
console.log(`${COLORS.blue}[tailjng CLI] Installing ${isDev ? 'dev ' : ''}dependencies...${COLORS.reset}`);
|
|
27
|
+
|
|
28
|
+
execSync(`npm install ${flag} --legacy-peer-deps ${spec}`.replace(/\s+/g, ' ').trim(), {
|
|
29
|
+
cwd: workspaceRoot,
|
|
30
|
+
stdio: 'inherit',
|
|
31
|
+
shell: true,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
RUNTIME_PACKAGES,
|
|
37
|
+
DEV_PACKAGES,
|
|
38
|
+
installPackages,
|
|
39
|
+
};
|
|
@@ -77,29 +77,13 @@ function resolveStyleFilePath(workspaceRoot, styleEntry, appProject) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function getTailjngSafelistCssImport(workspaceRoot, styleEntry, appProject) {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
let rel = path.relative(path.dirname(stylePath), safelistPath).split(path.sep).join('/');
|
|
83
|
-
if (!rel.startsWith('.')) rel = `./${rel}`;
|
|
84
|
-
return `@import "${rel}";`;
|
|
80
|
+
const { getColorsSafelistImportLine } = require('./colors-config-utils');
|
|
81
|
+
return getColorsSafelistImportLine(workspaceRoot, styleEntry, appProject);
|
|
85
82
|
}
|
|
86
83
|
|
|
87
84
|
function ensureTailjngSafelistImport(styleFilePath, importLine) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
let content = fs.readFileSync(styleFilePath, 'utf8');
|
|
91
|
-
if (content.includes('colors.safelist.css')) return { changed: false };
|
|
92
|
-
|
|
93
|
-
const tailwindMatch = content.match(/@(?:import|use)\s+"tailwindcss";?/);
|
|
94
|
-
if (tailwindMatch) {
|
|
95
|
-
const insertAt = tailwindMatch.index + tailwindMatch[0].length;
|
|
96
|
-
content = `${content.slice(0, insertAt)}\n${importLine}\n${content.slice(insertAt)}`;
|
|
97
|
-
} else {
|
|
98
|
-
content = `${importLine}\n${content}`;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
fs.writeFileSync(styleFilePath, content, 'utf8');
|
|
102
|
-
return { changed: true };
|
|
85
|
+
const { ensureColorsSafelistImport } = require('./colors-config-utils');
|
|
86
|
+
return ensureColorsSafelistImport(styleFilePath, importLine);
|
|
103
87
|
}
|
|
104
88
|
|
|
105
89
|
function ensureTailjngStylesInAngularJson(angularJsonPath, projectName, styleLanguage) {
|
|
@@ -244,15 +228,56 @@ function getMergedDependencies(packageJson) {
|
|
|
244
228
|
return { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
245
229
|
}
|
|
246
230
|
|
|
247
|
-
|
|
248
|
-
|
|
231
|
+
function getInstalledPackageVersion(workspaceRoot, name) {
|
|
232
|
+
const pkgPath = path.join(workspaceRoot, 'node_modules', ...name.split('/'), 'package.json');
|
|
233
|
+
if (!fs.existsSync(pkgPath)) return null;
|
|
234
|
+
try {
|
|
235
|
+
return JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version;
|
|
236
|
+
} catch {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function resolveAngularAnimationsSpec(packageJson, workspaceRoot) {
|
|
242
|
+
const deps = getMergedDependencies(packageJson);
|
|
243
|
+
const coreInstalled = workspaceRoot ? getInstalledPackageVersion(workspaceRoot, '@angular/core') : null;
|
|
244
|
+
if (coreInstalled) return `^${coreInstalled}`;
|
|
245
|
+
if (deps['@angular/core']) return deps['@angular/core'];
|
|
246
|
+
return '^19.2.0';
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** Corrige @angular/animations para usar la misma versión que @angular/core del proyecto. */
|
|
250
|
+
function alignAngularAnimationsInPackageJson(workspaceRoot) {
|
|
251
|
+
const pkgPath = path.join(workspaceRoot, 'package.json');
|
|
252
|
+
if (!fs.existsSync(pkgPath)) return { changed: false };
|
|
253
|
+
|
|
254
|
+
const pkg = readJson(pkgPath);
|
|
255
|
+
const deps = pkg.dependencies || {};
|
|
256
|
+
const coreInstalled = getInstalledPackageVersion(workspaceRoot, '@angular/core');
|
|
257
|
+
const coreSpec = deps['@angular/core'];
|
|
258
|
+
|
|
259
|
+
// Preferir versión instalada (ej. 19.2.25); si no, la misma entrada que core en package.json
|
|
260
|
+
const aligned = coreInstalled ? `^${coreInstalled}` : coreSpec;
|
|
261
|
+
if (!aligned) return { changed: false };
|
|
262
|
+
|
|
263
|
+
if (!deps['@angular/animations']) return { changed: false };
|
|
264
|
+
if (deps['@angular/animations'] === aligned) return { changed: false };
|
|
265
|
+
|
|
266
|
+
deps['@angular/animations'] = aligned;
|
|
267
|
+
pkg.dependencies = deps;
|
|
268
|
+
writeJson(pkgPath, pkg);
|
|
269
|
+
return { changed: true, version: aligned };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Alinea @angular/animations con la versión instalada de @angular/core (evita ERESOLVE 19.2.0 vs 19.2.25). */
|
|
273
|
+
function resolveRuntimePackages(packageJson, basePackages, workspaceRoot = null) {
|
|
249
274
|
const packages = { ...basePackages };
|
|
250
275
|
const deps = getMergedDependencies(packageJson);
|
|
251
276
|
|
|
252
277
|
if (deps['@angular/animations']) {
|
|
253
278
|
delete packages['@angular/animations'];
|
|
254
|
-
} else if (deps['@angular/core']) {
|
|
255
|
-
packages['@angular/animations'] =
|
|
279
|
+
} else if (deps['@angular/core'] || (workspaceRoot && getInstalledPackageVersion(workspaceRoot, '@angular/core'))) {
|
|
280
|
+
packages['@angular/animations'] = resolveAngularAnimationsSpec(packageJson, workspaceRoot);
|
|
256
281
|
}
|
|
257
282
|
|
|
258
283
|
return packages;
|
|
@@ -327,6 +352,7 @@ module.exports = {
|
|
|
327
352
|
getMergedDependencies,
|
|
328
353
|
resolveRuntimePackages,
|
|
329
354
|
resolveDevPackages,
|
|
355
|
+
alignAngularAnimationsInPackageJson,
|
|
330
356
|
hasTailwindSetup,
|
|
331
357
|
fileExists,
|
|
332
358
|
};
|
package/package.json
CHANGED
package/registry/components.json
CHANGED
package/src/colors.safelist.css
CHANGED
|
@@ -1,4 +1,29 @@
|
|
|
1
|
-
/* AUTO-GENERATED — do not edit. Run: node scripts/generate-colors-safelist.mjs */
|
|
2
|
-
/*
|
|
1
|
+
/* AUTO-GENERATED — do not edit blocks 1-N. Run: node scripts/generate-colors-safelist.mjs */
|
|
2
|
+
/* npm fallback — prefer src/app/tailjng/colors/colors.safelist.css in projects */
|
|
3
3
|
|
|
4
|
-
@
|
|
4
|
+
@layer utilities {
|
|
5
|
+
.__tailjng_colors_safelist_1__ {
|
|
6
|
+
@apply bg-accent/40 bg-background bg-background/80 bg-black/5 bg-blue-50 bg-blue-500 bg-blue-500/10 bg-cyan-500 bg-cyan-500/10 bg-dark-background bg-gray-50 bg-gray-500 bg-gray-500/10 bg-green-50 bg-green-500 bg-green-500/10 bg-none bg-orange-500 bg-orange-500/10 bg-pink-500 bg-pink-500/10 bg-primary bg-primary/10 bg-primary/80 bg-purple-50 bg-purple-500 bg-purple-500/10 bg-red-50 bg-red-500 bg-red-500/10 bg-teal-500 bg-teal-500/10 bg-transparent bg-white bg-yellow-50 bg-yellow-600 bg-yellow-600/10 border border-blue-300 border-blue-500 border-blue-500/20 border-border border-cyan-300 border-cyan-500 border-cyan-500/20 border-dark-border border-dark-border/20 border-gray-400 border-gray-500 border-gray-500/20;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.__tailjng_colors_safelist_2__ {
|
|
10
|
+
@apply border-green-300 border-green-500 border-green-500/20 border-orange-300 border-orange-500 border-orange-500/20 border-pink-300 border-pink-500 border-pink-500/20 border-primary border-primary/20 border-primary/30 border-purple-300 border-purple-400 border-purple-500 border-purple-500/20 border-red-400 border-red-500 border-red-500/20 border-teal-300 border-teal-500 border-teal-500/20 border-transparent border-yellow-500 border-yellow-600 border-yellow-600/20 dark:bg-[#15181e] dark:bg-[#15241f] dark:bg-[#1a1a24] dark:bg-[#1f1c1a] dark:bg-[#21181c] dark:bg-[#241732] dark:bg-dark-accent/30 dark:bg-dark-background dark:bg-dark-background/80 dark:bg-foreground dark:bg-input dark:bg-input/15 dark:bg-input/80 dark:bg-white/10 dark:border-blue-300 dark:border-blue-600 dark:border-border dark:border-border/20 dark:border-cyan-300 dark:border-cyan-600 dark:border-dark-border dark:border-gray-400 dark:border-gray-600 dark:border-green-300;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.__tailjng_colors_safelist_3__ {
|
|
14
|
+
@apply dark:border-green-600 dark:border-input dark:border-input/30 dark:border-input/40 dark:border-orange-300 dark:border-orange-600 dark:border-pink-300 dark:border-pink-600 dark:border-purple-300 dark:border-purple-400 dark:border-purple-600 dark:border-red-400 dark:border-red-600 dark:border-teal-300 dark:border-teal-600 dark:border-transparent dark:border-yellow-500 dark:border-yellow-700 dark:hover:bg-blue-500/15 dark:hover:bg-blue-600/10 dark:hover:bg-border/10 dark:hover:bg-cyan-500/15 dark:hover:bg-cyan-600/10 dark:hover:bg-dark-accent/40 dark:hover:bg-dark-accent/50 dark:hover:bg-dark-background dark:hover:bg-gray-500/15 dark:hover:bg-gray-600/10 dark:hover:bg-green-500/15 dark:hover:bg-green-600/10 dark:hover:bg-input dark:hover:bg-input/15 dark:hover:bg-input/25 dark:hover:bg-input/60 dark:hover:bg-input/80 dark:hover:bg-orange-500/15 dark:hover:bg-orange-600/10 dark:hover:bg-pink-500/15 dark:hover:bg-pink-600/10 dark:hover:bg-purple-500/15 dark:hover:bg-purple-600/10 dark:hover:bg-red-500/15 dark:hover:bg-red-600/10 dark:hover:bg-teal-500/15 dark:hover:bg-teal-600/10 dark:hover:bg-white/10 dark:hover:bg-white/15 dark:hover:bg-yellow-600/15 dark:hover:bg-yellow-700/10 dark:hover:text-white;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.__tailjng_colors_safelist_4__ {
|
|
18
|
+
@apply dark:text-blue-400 dark:text-border dark:text-cyan-400 dark:text-gray-400 dark:text-green-400 dark:text-input dark:text-orange-400 dark:text-pink-400 dark:text-purple-400 dark:text-red-400 dark:text-teal-400 dark:text-white dark:text-yellow-400 hover:bg-accent hover:bg-accent/60 hover:bg-accent/70 hover:bg-background hover:bg-black/10 hover:bg-black/5 hover:bg-blue-500/10 hover:bg-blue-500/20 hover:bg-blue-600 hover:bg-cyan-500/10 hover:bg-cyan-500/20 hover:bg-cyan-600 hover:bg-dark-accent/50 hover:bg-dark-border/10 hover:bg-gray-500/10 hover:bg-gray-500/20 hover:bg-gray-600 hover:bg-green-500/10 hover:bg-green-500/20 hover:bg-green-600 hover:bg-orange-500/10 hover:bg-orange-500/20 hover:bg-orange-600 hover:bg-pink-500/10 hover:bg-pink-500/20 hover:bg-pink-600 hover:bg-primary hover:bg-primary/10 hover:bg-primary/20 hover:bg-primary/80 hover:bg-purple-500/10 hover:bg-purple-500/20 hover:bg-purple-600 hover:bg-red-500/10 hover:bg-red-500/20 hover:bg-red-600 hover:bg-teal-500/10;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.__tailjng_colors_safelist_5__ {
|
|
22
|
+
@apply hover:bg-teal-500/20 hover:bg-teal-600 hover:bg-yellow-600/10 hover:bg-yellow-600/20 hover:bg-yellow-700 shadow-md shadow-sm text-black text-blue-500 text-blue-600 text-cyan-500 text-cyan-600 text-dark-border text-gray-500 text-gray-600 text-green-500 text-green-600 text-orange-500 text-orange-600 text-pink-500 text-pink-600 text-primary text-purple-500 text-purple-600 text-red-500 text-red-600 text-teal-500 text-teal-600 text-white text-yellow-500 text-yellow-600 text-yellow-700;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* ── Tus colores custom: descomenta y añade clases Tailwind ── */
|
|
26
|
+
.__tailjng_custom_colors__ {
|
|
27
|
+
/* @apply bg-indigo-600 text-white hover:bg-indigo-700; */
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Colores Tailjng — configuración del proyecto
|
|
2
|
+
|
|
3
|
+
Carpeta generada por `init:app`, `sync:app` o `npx tailjng add colors`.
|
|
4
|
+
|
|
5
|
+
## Archivos
|
|
6
|
+
|
|
7
|
+
| Archivo | Para qué |
|
|
8
|
+
|---------|----------|
|
|
9
|
+
| `colors.config.ts` | Variantes (`primary`, `success_soft`, …) + las tuyas (`brand`, etc.) |
|
|
10
|
+
| `colors.safelist.css` | Clases Tailwind que el build debe generar (`@apply`) |
|
|
11
|
+
|
|
12
|
+
## Añadir un color propio
|
|
13
|
+
|
|
14
|
+
**1.** En `colors.config.ts`:
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
brand: 'bg-indigo-600 text-white hover:bg-indigo-700 border border-indigo-500 shadow-md',
|
|
18
|
+
brand_soft: 'bg-indigo-500/10 text-indigo-600 border border-indigo-500/20 shadow-sm',
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**2.** En `colors.safelist.css`, dentro del bloque `@layer utilities`:
|
|
22
|
+
|
|
23
|
+
```css
|
|
24
|
+
.__tailjng_custom_colors__ {
|
|
25
|
+
@apply bg-indigo-600 text-white hover:bg-indigo-700 border-indigo-500 bg-indigo-500/10 text-indigo-600;
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**3.** Uso en componentes:
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<JButton classes="brand" text="Guardar" />
|
|
33
|
+
<JBadge classes="brand_soft" value="N" />
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Provider
|
|
37
|
+
|
|
38
|
+
`app.config.ts` debe incluir `tailjngColorsProvider` (lo añade `init:app` / `sync:app`).
|
|
@@ -1,19 +1,112 @@
|
|
|
1
1
|
import { TAILJNG_COLORS_CONFIG } from 'tailjng';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Variantes de color
|
|
5
|
-
* Uso en componentes: classes="
|
|
4
|
+
* Variantes de color — edita las existentes o añade las tuyas al final.
|
|
5
|
+
* Uso en componentes: classes="primary" | classes="success_soft" | classes="brand"
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Si añades variantes nuevas con clases Tailwind nuevas, regístralas también
|
|
8
|
+
* en colors.safelist.css (bloque .__tailjng_custom_colors__).
|
|
9
9
|
*/
|
|
10
|
-
export const
|
|
10
|
+
export const colorVariants: Record<string, string> = {
|
|
11
|
+
|
|
12
|
+
primary: 'bg-primary dark:bg-input text-white dark:text-white hover:bg-primary/80 dark:hover:bg-input/60 dark:hover:text-white shadow-md border border-dark-border dark:border-border',
|
|
13
|
+
primary_soft: 'bg-primary/10 dark:bg-input/15 text-primary dark:text-input hover:bg-primary/20 dark:hover:bg-input/25 border border-primary/20 dark:border-input/30 shadow-sm',
|
|
14
|
+
primary_outline: 'bg-transparent text-primary dark:text-input border border-primary dark:border-input hover:bg-primary/10 dark:hover:bg-input/15 shadow-sm',
|
|
15
|
+
primary_ghost: 'bg-transparent text-primary dark:text-input hover:bg-primary/10 dark:hover:bg-input/15 border border-transparent dark:border-transparent',
|
|
16
|
+
primary_light: 'bg-primary/80 dark:bg-input/80 text-white hover:bg-primary dark:hover:bg-input border border-primary/30 dark:border-input/40 shadow-md',
|
|
17
|
+
primary_dark: 'bg-primary text-white dark:bg-input hover:bg-primary/80 dark:hover:bg-input/80 border border-dark-border dark:border-border shadow-md',
|
|
18
|
+
|
|
19
|
+
primary_secondary: 'bg-none text-dark-border dark:text-border border border-dark-border dark:border-border hover:bg-dark-border/10 dark:hover:bg-border/10 shadow-md',
|
|
20
|
+
|
|
21
|
+
secondary: 'bg-background dark:bg-dark-background text-black border border-dark-border dark:border-border dark:text-white hover:bg-accent dark:hover:bg-dark-accent/50',
|
|
22
|
+
secondary_soft: 'bg-accent/40 dark:bg-dark-accent/30 text-black dark:text-white border border-border dark:border-dark-border hover:bg-accent/70 dark:hover:bg-dark-accent/50 shadow-sm',
|
|
23
|
+
secondary_outline: 'bg-transparent text-black dark:text-white border border-border dark:border-dark-border hover:bg-accent dark:hover:bg-dark-accent/40 shadow-sm',
|
|
24
|
+
secondary_ghost: 'bg-transparent text-black dark:text-white hover:bg-accent/60 dark:hover:bg-dark-accent/40 border border-transparent dark:border-transparent',
|
|
25
|
+
secondary_light: 'bg-background/80 dark:bg-dark-background/80 text-black dark:text-white border border-border dark:border-dark-border hover:bg-background dark:hover:bg-dark-background shadow-sm',
|
|
26
|
+
secondary_dark: 'bg-dark-background text-white border border-dark-border hover:bg-dark-accent/50 shadow-md',
|
|
27
|
+
|
|
28
|
+
success: 'bg-green-500 hover:bg-green-600 text-white border border-green-300 dark:border-green-300 shadow-md',
|
|
29
|
+
success_secondary: 'bg-none text-green-500 border border-green-500 dark:border-green-600 hover:bg-green-500/10 dark:hover:bg-green-600/10 shadow-md',
|
|
30
|
+
success_soft: 'bg-green-500/10 text-green-600 dark:text-green-400 border border-green-500/20 hover:bg-green-500/20 dark:hover:bg-green-500/15 shadow-sm',
|
|
31
|
+
success_outline: 'bg-transparent text-green-500 border border-green-500 hover:bg-green-500/10 shadow-sm',
|
|
32
|
+
success_ghost: 'bg-transparent text-green-500 hover:bg-green-500/10 border border-transparent dark:border-transparent',
|
|
33
|
+
|
|
34
|
+
info: 'bg-blue-500 hover:bg-blue-600 text-white border border-blue-300 dark:border-blue-300 shadow-md',
|
|
35
|
+
info_secondary: 'bg-none text-blue-500 border border-blue-500 dark:border-blue-600 hover:bg-blue-500/10 dark:hover:bg-blue-600/10 shadow-md',
|
|
36
|
+
info_soft: 'bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/20 hover:bg-blue-500/20 dark:hover:bg-blue-500/15 shadow-sm',
|
|
37
|
+
info_outline: 'bg-transparent text-blue-500 border border-blue-500 hover:bg-blue-500/10 shadow-sm',
|
|
38
|
+
info_ghost: 'bg-transparent text-blue-500 hover:bg-blue-500/10 border border-transparent dark:border-transparent',
|
|
39
|
+
|
|
40
|
+
warning: 'bg-yellow-600 hover:bg-yellow-700 text-white border border-yellow-500 dark:border-yellow-500 shadow-md',
|
|
41
|
+
warning_secondary: 'bg-none text-yellow-600 border border-yellow-600 dark:border-yellow-700 hover:bg-yellow-600/10 dark:hover:bg-yellow-700/10 shadow-md',
|
|
42
|
+
warning_soft: 'bg-yellow-600/10 text-yellow-700 dark:text-yellow-400 border border-yellow-600/20 hover:bg-yellow-600/20 dark:hover:bg-yellow-600/15 shadow-sm',
|
|
43
|
+
warning_outline: 'bg-transparent text-yellow-600 border border-yellow-600 hover:bg-yellow-600/10 shadow-sm',
|
|
44
|
+
warning_ghost: 'bg-transparent text-yellow-600 hover:bg-yellow-600/10 border border-transparent dark:border-transparent',
|
|
45
|
+
|
|
46
|
+
question: 'bg-purple-500 hover:bg-purple-600 text-white border border-purple-400 dark:border-purple-400 shadow-md',
|
|
47
|
+
question_secondary: 'bg-none text-purple-500 border border-purple-500 dark:border-purple-600 hover:bg-purple-500/10 dark:hover:bg-purple-600/10 shadow-md',
|
|
48
|
+
question_soft: 'bg-purple-500/10 text-purple-600 dark:text-purple-400 border border-purple-500/20 hover:bg-purple-500/20 dark:hover:bg-purple-500/15 shadow-sm',
|
|
49
|
+
question_outline: 'bg-transparent text-purple-500 border border-purple-500 hover:bg-purple-500/10 shadow-sm',
|
|
50
|
+
question_ghost: 'bg-transparent text-purple-500 hover:bg-purple-500/10 border border-transparent dark:border-transparent',
|
|
51
|
+
|
|
52
|
+
error: 'bg-red-500 hover:bg-red-600 text-white border border-red-400 dark:border-red-400 shadow-md',
|
|
53
|
+
error_secondary: 'bg-none text-red-500 border border-red-500 dark:border-red-600 hover:bg-red-500/10 dark:hover:bg-red-600/10 shadow-md',
|
|
54
|
+
error_soft: 'bg-red-500/10 text-red-600 dark:text-red-400 border border-red-500/20 hover:bg-red-500/20 dark:hover:bg-red-500/15 shadow-sm',
|
|
55
|
+
error_outline: 'bg-transparent text-red-500 border border-red-500 hover:bg-red-500/10 shadow-sm',
|
|
56
|
+
error_ghost: 'bg-transparent text-red-500 hover:bg-red-500/10 border border-transparent dark:border-transparent',
|
|
57
|
+
|
|
58
|
+
loading: 'bg-gray-500 hover:bg-gray-600 text-white border border-gray-400 dark:border-gray-400 shadow-md',
|
|
59
|
+
loading_secondary: 'bg-none text-gray-500 border border-gray-500 dark:border-gray-600 hover:bg-gray-500/10 dark:hover:bg-gray-600/10 shadow-md',
|
|
60
|
+
loading_soft: 'bg-gray-500/10 text-gray-600 dark:text-gray-400 border border-gray-500/20 hover:bg-gray-500/20 dark:hover:bg-gray-500/15 shadow-sm',
|
|
61
|
+
loading_outline: 'bg-transparent text-gray-500 border border-gray-500 hover:bg-gray-500/10 shadow-sm',
|
|
62
|
+
loading_ghost: 'bg-transparent text-gray-500 hover:bg-gray-500/10 border border-transparent dark:border-transparent',
|
|
63
|
+
|
|
64
|
+
orange: 'bg-orange-500 hover:bg-orange-600 text-white border border-orange-300 dark:border-orange-300 shadow-md',
|
|
65
|
+
orange_secondary: 'bg-none text-orange-500 border border-orange-500 dark:border-orange-600 hover:bg-orange-500/10 dark:hover:bg-orange-600/10 shadow-md',
|
|
66
|
+
orange_soft: 'bg-orange-500/10 text-orange-600 dark:text-orange-400 border border-orange-500/20 hover:bg-orange-500/20 dark:hover:bg-orange-500/15 shadow-sm',
|
|
67
|
+
orange_outline: 'bg-transparent text-orange-500 border border-orange-500 hover:bg-orange-500/10 shadow-sm',
|
|
68
|
+
orange_ghost: 'bg-transparent text-orange-500 hover:bg-orange-500/10 border border-transparent dark:border-transparent',
|
|
69
|
+
|
|
70
|
+
cyan: 'bg-cyan-500 hover:bg-cyan-600 text-white border border-cyan-300 dark:border-cyan-300 shadow-md',
|
|
71
|
+
cyan_secondary: 'bg-none text-cyan-500 border border-cyan-500 dark:border-cyan-600 hover:bg-cyan-500/10 dark:hover:bg-cyan-600/10 shadow-md',
|
|
72
|
+
cyan_soft: 'bg-cyan-500/10 text-cyan-600 dark:text-cyan-400 border border-cyan-500/20 hover:bg-cyan-500/20 dark:hover:bg-cyan-500/15 shadow-sm',
|
|
73
|
+
cyan_outline: 'bg-transparent text-cyan-500 border border-cyan-500 hover:bg-cyan-500/10 shadow-sm',
|
|
74
|
+
cyan_ghost: 'bg-transparent text-cyan-500 hover:bg-cyan-500/10 border border-transparent dark:border-transparent',
|
|
75
|
+
|
|
76
|
+
purple: 'bg-purple-500 hover:bg-purple-600 text-white border border-purple-300 dark:border-purple-300 shadow-md',
|
|
77
|
+
purple_secondary: 'bg-none text-purple-500 border border-purple-500 dark:border-purple-600 hover:bg-purple-500/10 dark:hover:bg-purple-600/10 shadow-md',
|
|
78
|
+
purple_soft: 'bg-purple-500/10 text-purple-600 dark:text-purple-400 border border-purple-500/20 hover:bg-purple-500/20 dark:hover:bg-purple-500/15 shadow-sm',
|
|
79
|
+
purple_outline: 'bg-transparent text-purple-500 border border-purple-500 hover:bg-purple-500/10 shadow-sm',
|
|
80
|
+
purple_ghost: 'bg-transparent text-purple-500 hover:bg-purple-500/10 border border-transparent dark:border-transparent',
|
|
81
|
+
|
|
82
|
+
teal: 'bg-teal-500 hover:bg-teal-600 text-white border border-teal-300 dark:border-teal-300 shadow-md',
|
|
83
|
+
teal_secondary: 'bg-none text-teal-500 border border-teal-500 dark:border-teal-600 hover:bg-teal-500/10 dark:hover:bg-teal-600/10 shadow-md',
|
|
84
|
+
teal_soft: 'bg-teal-500/10 text-teal-600 dark:text-teal-400 border border-teal-500/20 hover:bg-teal-500/20 dark:hover:bg-teal-500/15 shadow-sm',
|
|
85
|
+
teal_outline: 'bg-transparent text-teal-500 border border-teal-500 hover:bg-teal-500/10 shadow-sm',
|
|
86
|
+
teal_ghost: 'bg-transparent text-teal-500 hover:bg-teal-500/10 border border-transparent dark:border-transparent',
|
|
87
|
+
|
|
88
|
+
pink: 'bg-pink-500 hover:bg-pink-600 text-white border border-pink-300 dark:border-pink-300 shadow-md',
|
|
89
|
+
pink_secondary: 'bg-none text-pink-500 border border-pink-500 dark:border-pink-600 hover:bg-pink-500/10 dark:hover:bg-pink-600/10 shadow-md',
|
|
90
|
+
pink_soft: 'bg-pink-500/10 text-pink-600 dark:text-pink-400 border border-pink-500/20 hover:bg-pink-500/20 dark:hover:bg-pink-500/15 shadow-sm',
|
|
91
|
+
pink_outline: 'bg-transparent text-pink-500 border border-pink-500 hover:bg-pink-500/10 shadow-sm',
|
|
92
|
+
pink_ghost: 'bg-transparent text-pink-500 hover:bg-pink-500/10 border border-transparent dark:border-transparent',
|
|
93
|
+
|
|
94
|
+
green: 'bg-green-500 hover:bg-green-600 text-white border border-green-300 dark:border-green-300 shadow-md',
|
|
95
|
+
green_secondary: 'bg-none text-green-500 border border-green-500 dark:border-green-600 hover:bg-green-500/10 dark:hover:bg-green-600/10 shadow-md',
|
|
96
|
+
green_soft: 'bg-green-500/10 text-green-600 dark:text-green-400 border border-green-500/20 hover:bg-green-500/20 dark:hover:bg-green-500/15 shadow-sm',
|
|
97
|
+
green_outline: 'bg-transparent text-green-500 border border-green-500 hover:bg-green-500/10 shadow-sm',
|
|
98
|
+
green_ghost: 'bg-transparent text-green-500 hover:bg-green-500/10 border border-transparent dark:border-transparent',
|
|
99
|
+
|
|
100
|
+
default: 'text-black dark:text-white shadow-md border border-dark-border dark:border-border',
|
|
101
|
+
default_soft: 'bg-black/5 dark:bg-white/10 text-black dark:text-white border border-dark-border/20 dark:border-border/20 hover:bg-black/10 dark:hover:bg-white/15 shadow-sm',
|
|
102
|
+
default_outline: 'bg-transparent text-black dark:text-white border border-dark-border dark:border-border hover:bg-black/5 dark:hover:bg-white/10 shadow-sm',
|
|
103
|
+
default_ghost: 'bg-transparent text-black dark:text-white hover:bg-black/5 dark:hover:bg-white/10 border border-transparent dark:border-transparent',
|
|
104
|
+
|
|
105
|
+
// ── Custom — añade variantes propias debajo ──
|
|
11
106
|
// brand: 'bg-indigo-600 text-white hover:bg-indigo-700 border border-indigo-500 shadow-md',
|
|
12
107
|
};
|
|
13
108
|
|
|
14
109
|
export const tailjngColorsProvider = {
|
|
15
110
|
provide: TAILJNG_COLORS_CONFIG,
|
|
16
|
-
useValue: {
|
|
17
|
-
variants: customColorVariants,
|
|
18
|
-
},
|
|
111
|
+
useValue: { variants: colorVariants },
|
|
19
112
|
};
|
|
@@ -1,7 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/* AUTO-GENERATED — do not edit blocks 1-N. Run: node scripts/generate-colors-safelist.mjs */
|
|
2
|
+
/* Importar en styles.css DESPUÉS de @import "tailwindcss". */
|
|
3
|
+
|
|
4
|
+
@layer utilities {
|
|
5
|
+
.__tailjng_colors_safelist_1__ {
|
|
6
|
+
@apply bg-accent/40 bg-background bg-background/80 bg-black/5 bg-blue-50 bg-blue-500 bg-blue-500/10 bg-cyan-500 bg-cyan-500/10 bg-dark-background bg-gray-50 bg-gray-500 bg-gray-500/10 bg-green-50 bg-green-500 bg-green-500/10 bg-none bg-orange-500 bg-orange-500/10 bg-pink-500 bg-pink-500/10 bg-primary bg-primary/10 bg-primary/80 bg-purple-50 bg-purple-500 bg-purple-500/10 bg-red-50 bg-red-500 bg-red-500/10 bg-teal-500 bg-teal-500/10 bg-transparent bg-white bg-yellow-50 bg-yellow-600 bg-yellow-600/10 border border-blue-300 border-blue-500 border-blue-500/20 border-border border-cyan-300 border-cyan-500 border-cyan-500/20 border-dark-border border-dark-border/20 border-gray-400 border-gray-500 border-gray-500/20;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.__tailjng_colors_safelist_2__ {
|
|
10
|
+
@apply border-green-300 border-green-500 border-green-500/20 border-orange-300 border-orange-500 border-orange-500/20 border-pink-300 border-pink-500 border-pink-500/20 border-primary border-primary/20 border-primary/30 border-purple-300 border-purple-400 border-purple-500 border-purple-500/20 border-red-400 border-red-500 border-red-500/20 border-teal-300 border-teal-500 border-teal-500/20 border-transparent border-yellow-500 border-yellow-600 border-yellow-600/20 dark:bg-[#15181e] dark:bg-[#15241f] dark:bg-[#1a1a24] dark:bg-[#1f1c1a] dark:bg-[#21181c] dark:bg-[#241732] dark:bg-dark-accent/30 dark:bg-dark-background dark:bg-dark-background/80 dark:bg-foreground dark:bg-input dark:bg-input/15 dark:bg-input/80 dark:bg-white/10 dark:border-blue-300 dark:border-blue-600 dark:border-border dark:border-border/20 dark:border-cyan-300 dark:border-cyan-600 dark:border-dark-border dark:border-gray-400 dark:border-gray-600 dark:border-green-300;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.__tailjng_colors_safelist_3__ {
|
|
14
|
+
@apply dark:border-green-600 dark:border-input dark:border-input/30 dark:border-input/40 dark:border-orange-300 dark:border-orange-600 dark:border-pink-300 dark:border-pink-600 dark:border-purple-300 dark:border-purple-400 dark:border-purple-600 dark:border-red-400 dark:border-red-600 dark:border-teal-300 dark:border-teal-600 dark:border-transparent dark:border-yellow-500 dark:border-yellow-700 dark:hover:bg-blue-500/15 dark:hover:bg-blue-600/10 dark:hover:bg-border/10 dark:hover:bg-cyan-500/15 dark:hover:bg-cyan-600/10 dark:hover:bg-dark-accent/40 dark:hover:bg-dark-accent/50 dark:hover:bg-dark-background dark:hover:bg-gray-500/15 dark:hover:bg-gray-600/10 dark:hover:bg-green-500/15 dark:hover:bg-green-600/10 dark:hover:bg-input dark:hover:bg-input/15 dark:hover:bg-input/25 dark:hover:bg-input/60 dark:hover:bg-input/80 dark:hover:bg-orange-500/15 dark:hover:bg-orange-600/10 dark:hover:bg-pink-500/15 dark:hover:bg-pink-600/10 dark:hover:bg-purple-500/15 dark:hover:bg-purple-600/10 dark:hover:bg-red-500/15 dark:hover:bg-red-600/10 dark:hover:bg-teal-500/15 dark:hover:bg-teal-600/10 dark:hover:bg-white/10 dark:hover:bg-white/15 dark:hover:bg-yellow-600/15 dark:hover:bg-yellow-700/10 dark:hover:text-white;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.__tailjng_colors_safelist_4__ {
|
|
18
|
+
@apply dark:text-blue-400 dark:text-border dark:text-cyan-400 dark:text-gray-400 dark:text-green-400 dark:text-input dark:text-orange-400 dark:text-pink-400 dark:text-purple-400 dark:text-red-400 dark:text-teal-400 dark:text-white dark:text-yellow-400 hover:bg-accent hover:bg-accent/60 hover:bg-accent/70 hover:bg-background hover:bg-black/10 hover:bg-black/5 hover:bg-blue-500/10 hover:bg-blue-500/20 hover:bg-blue-600 hover:bg-cyan-500/10 hover:bg-cyan-500/20 hover:bg-cyan-600 hover:bg-dark-accent/50 hover:bg-dark-border/10 hover:bg-gray-500/10 hover:bg-gray-500/20 hover:bg-gray-600 hover:bg-green-500/10 hover:bg-green-500/20 hover:bg-green-600 hover:bg-orange-500/10 hover:bg-orange-500/20 hover:bg-orange-600 hover:bg-pink-500/10 hover:bg-pink-500/20 hover:bg-pink-600 hover:bg-primary hover:bg-primary/10 hover:bg-primary/20 hover:bg-primary/80 hover:bg-purple-500/10 hover:bg-purple-500/20 hover:bg-purple-600 hover:bg-red-500/10 hover:bg-red-500/20 hover:bg-red-600 hover:bg-teal-500/10;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.__tailjng_colors_safelist_5__ {
|
|
22
|
+
@apply hover:bg-teal-500/20 hover:bg-teal-600 hover:bg-yellow-600/10 hover:bg-yellow-600/20 hover:bg-yellow-700 shadow-md shadow-sm text-black text-blue-500 text-blue-600 text-cyan-500 text-cyan-600 text-dark-border text-gray-500 text-gray-600 text-green-500 text-green-600 text-orange-500 text-orange-600 text-pink-500 text-pink-600 text-primary text-purple-500 text-purple-600 text-red-500 text-red-600 text-teal-500 text-teal-600 text-white text-yellow-500 text-yellow-600 text-yellow-700;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* ── Tus colores custom: descomenta y añade clases Tailwind ── */
|
|
26
|
+
.__tailjng_custom_colors__ {
|
|
27
|
+
/* @apply bg-indigo-600 text-white hover:bg-indigo-700; */
|
|
28
|
+
}
|
|
29
|
+
}
|
|
Binary file
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Component } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Configuración de colores/variantes Tailwind del proyecto (sin UI).
|
|
5
|
-
* Los archivos útiles son colors.config.ts y colors.safelist.css en esta carpeta.
|
|
6
|
-
*/
|
|
7
|
-
@Component({
|
|
8
|
-
selector: 'j-colors-config',
|
|
9
|
-
standalone: true,
|
|
10
|
-
template: '',
|
|
11
|
-
})
|
|
12
|
-
export class JColorsConfigComponent {}
|
package/tailjng-0.1.2.tgz
DELETED
|
Binary file
|