tailjng 0.1.0 → 0.1.2

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 CHANGED
@@ -41,9 +41,11 @@ El CLI instala **dependencias transitivas** automáticamente (ej. `button` → `
41
41
 
42
42
  ## Requisitos
43
43
 
44
- - Angular **19.2+**
45
- - Tailwind CSS **4.x**
46
- - Peers: `lucide-angular`, `date-fns`, `exceljs`, `xlsx` (el CLI los instala con `init:app` si faltan)
44
+ - Angular **19.2+** (19.x dentro del mismo major; no Angular 20/21 aún)
45
+ - Tailwind CSS **4.x** (incluido si eliges Tailwind al crear el proyecto con `ng new`)
46
+ -{
47
+ - Peers: `lucide-angular`, `date-fns`, `exceljs`, `xlsx`, `file-saver` (el CLI los instala con `init:app` si faltan)
48
+ - Estilos globales en **CSS o SCSS** — `init:app` detecta cuál usa tu app
47
49
 
48
50
  ---
49
51
 
@@ -132,13 +134,39 @@ import { JAlertToastComponent } from './tailjng/alert/alert-toast/toast-alert.co
132
134
  <JButton [text]="'Guardar'" classes="primary" [icon]="icons.save" (clicked)="save()" />
133
135
  ```
134
136
 
135
- ### Colores — `JColorsService` (solo npm)
137
+ ### Colores — `JColorsService` + safelist Tailwind
136
138
 
137
- No uses `npx tailjng add color`. Las variantes vienen del servicio:
139
+ Las variantes (`primary`, `success_soft`, …) las resuelve **`JColorsService`** en runtime. Tailwind v4 **no ve** esas clases en el HTML estático, así que el paquete incluye `node_modules/tailjng/src/colors.safelist.css` con `@source inline(...)`.
140
+
141
+ `init:app` importa ese archivo en tu `styles.css` / `styles.scss` automáticamente.
142
+
143
+ **Variantes personalizadas del proyecto:**
144
+
145
+ ```powershell
146
+ npx tailjng add colors-config
147
+ ```
148
+
149
+ Copia `src/app/tailjng/colors/` con:
150
+
151
+ - `colors.config.ts` — define variantes extra (`TAILJNG_COLORS_CONFIG`)
152
+ - `colors.safelist.css` — añade tus clases Tailwind al `@source inline` para que el build las genere
153
+
154
+ Registra el provider en `app.config.ts`:
155
+
156
+ ```typescript
157
+ import { tailjngColorsProvider } from './tailjng/colors/colors.config';
158
+
159
+ providers: [
160
+ tailjngColorsProvider,
161
+ // ...
162
+ ],
163
+ ```
164
+
165
+ Uso en componentes (igual que siempre):
138
166
 
139
167
  ```html
140
- <JButton classes="success" … />
141
- <JBadge classes="warning_soft" … />
168
+ <JButton classes="primary" … />
169
+ <JButton classes="brand" … />
142
170
  ```
143
171
 
144
172
  ### Select con datos estáticos
@@ -20,16 +20,22 @@ const {
20
20
  patchAppConfig,
21
21
  patchAppComponentForAlerts,
22
22
  getMissingPackages,
23
+ resolveRuntimePackages,
24
+ resolveDevPackages,
25
+ hasTailwindSetup,
26
+ getTailjngSafelistCssImport,
27
+ ensureTailjngSafelistImport,
28
+ resolveStyleFilePath,
23
29
  fileExists,
24
30
  } = require('../settings/project-utils');
25
31
 
26
32
  const RUNTIME_PACKAGES = {
27
- '@angular/animations': '^19.2.0',
28
33
  'lucide-angular': '^0.525.0',
29
34
  '@ng-icons/lucide': '>=32.0.0',
30
35
  'date-fns': '^4.1.0',
31
36
  'exceljs': '^4.4.0',
32
37
  'xlsx': '^0.18.5',
38
+ 'file-saver': '^2.0.5',
33
39
  };
34
40
 
35
41
  const DEV_PACKAGES = {
@@ -82,10 +88,19 @@ function installPackages(workspaceRoot, packages, isDev = false) {
82
88
  const flag = isDev ? '--save-dev' : '--save';
83
89
  console.log(`${COLORS.blue}[tailjng CLI] Installing ${isDev ? 'dev ' : ''}dependencies...${COLORS.reset}`);
84
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
+
85
99
  try {
86
- execSync(`npm install ${flag} ${spec}`, { cwd: workspaceRoot, stdio: 'inherit' });
100
+ run();
87
101
  } catch {
88
- execSync(`npm install ${flag} ${spec}`, { cwd: workspaceRoot, stdio: 'inherit', shell: true });
102
+ console.log(`${COLORS.yellow}[tailjng CLI] Retrying with --legacy-peer-deps...${COLORS.reset}`);
103
+ run('--legacy-peer-deps');
89
104
  }
90
105
  }
91
106
 
@@ -158,6 +173,7 @@ async function runInitApp() {
158
173
 
159
174
  const packageJsonPath = path.join(workspaceRoot, 'package.json');
160
175
  const packageJson = fileExists(packageJsonPath) ? readJson(packageJsonPath) : { dependencies: {}, devDependencies: {} };
176
+ const tailwindReady = hasTailwindSetup(workspaceRoot, packageJson, primaryStylePath);
161
177
 
162
178
  if (!packageJson.dependencies?.tailjng) {
163
179
  console.log(`${COLORS.yellow}[tailjng CLI] WARNING: tailjng is not in package.json dependencies.${COLORS.reset}`);
@@ -165,13 +181,26 @@ async function runInitApp() {
165
181
  }
166
182
 
167
183
  if (installDeps) {
168
- const missingRuntime = Object.fromEntries(getMissingPackages(packageJson, RUNTIME_PACKAGES));
169
- const missingDev = Object.fromEntries(getMissingPackages(packageJson, DEV_PACKAGES));
184
+ if (tailwindReady) {
185
+ console.log(`${COLORS.cyan}[tailjng CLI] Tailwind already configured — skipping Tailwind/PostCSS packages and .postcssrc.json${COLORS.reset}`);
186
+ }
187
+
188
+ const runtimePackages = resolveRuntimePackages(packageJson, RUNTIME_PACKAGES);
189
+ const devPackages = resolveDevPackages(packageJson, DEV_PACKAGES, tailwindReady);
190
+ const missingRuntime = Object.fromEntries(getMissingPackages(packageJson, runtimePackages, workspaceRoot));
191
+ const missingDev = Object.fromEntries(getMissingPackages(packageJson, devPackages, workspaceRoot));
192
+
193
+ if (missingRuntime['@angular/animations']) {
194
+ console.log(`${COLORS.dim}[tailjng CLI] Adding @angular/animations aligned with @angular/core${COLORS.reset}`);
195
+ }
196
+
170
197
  installPackages(workspaceRoot, missingRuntime, false);
171
198
  installPackages(workspaceRoot, missingDev, true);
172
199
  }
173
200
 
174
201
  const hasAppConfig = fileExists(appConfigPath);
202
+ const safelistImport = getTailjngSafelistCssImport(workspaceRoot, primaryStylePath, selectedApp);
203
+ const primaryStyleFullPath = resolveStyleFilePath(workspaceRoot, primaryStylePath, selectedApp);
175
204
  const files = buildInitFiles({
176
205
  styleLanguage,
177
206
  primaryStylePath,
@@ -180,6 +209,7 @@ async function runInitApp() {
180
209
  componentsPath,
181
210
  overwrite,
182
211
  hasAppConfig,
212
+ safelistImport,
183
213
  });
184
214
 
185
215
  let created = 0;
@@ -192,6 +222,12 @@ async function runInitApp() {
192
222
  }
193
223
 
194
224
  for (const file of files) {
225
+ if (tailwindReady && file.relativePath === '.postcssrc.json') {
226
+ skipped += 1;
227
+ console.log(`${COLORS.yellow}↷ Skipped (Tailwind already configured) ${file.relativePath}${COLORS.reset}`);
228
+ continue;
229
+ }
230
+
195
231
  const targetPath = resolveTargetPath(workspaceRoot, selectedApp, file.relativePath, file.appRootRelative);
196
232
  const isPrimaryStyles = file.relativePath === primaryStylePath;
197
233
  const forceWrite = isPrimaryStyles && shouldWriteStyles(targetPath);
@@ -222,6 +258,11 @@ async function runInitApp() {
222
258
  console.log(`${COLORS.green}✔ Added node_modules/tailjng/src/styles.css to angular.json${COLORS.reset}`);
223
259
  }
224
260
 
261
+ const safelistPatched = ensureTailjngSafelistImport(primaryStyleFullPath, safelistImport);
262
+ if (safelistPatched.changed) {
263
+ console.log(`${COLORS.green}✔ Added tailjng colors safelist to ${path.relative(workspaceRoot, primaryStyleFullPath)}${COLORS.reset}`);
264
+ }
265
+
225
266
  if (installComponents) {
226
267
  const previousCwd = process.cwd();
227
268
  process.chdir(appRoot);
@@ -236,11 +277,15 @@ async function runInitApp() {
236
277
  }
237
278
  }
238
279
 
280
+ if (tailwindReady && !shouldWriteStyles(path.join(workspaceRoot, primaryStylePath))) {
281
+ console.log(`${COLORS.yellow}[tailjng CLI] Tip: add tailjng @theme tokens to your existing styles if components look unstyled.${COLORS.reset}`);
282
+ }
283
+
239
284
  console.log(`\n${COLORS.greenBright}${COLORS.bright}[tailjng CLI] init:app completed.${COLORS.reset}`);
240
285
  console.log(`${COLORS.dim}Created: ${created} | Skipped: ${skipped}${COLORS.reset}`);
241
286
  console.log(`\n${COLORS.cyan}Project ready. Install components when you need them:${COLORS.reset}`);
242
- console.log(` ${COLORS.dim}One by one:${COLORS.reset} cd ${path.relative(workspaceRoot, appRoot)} && npx tailjng add button`);
243
- console.log(` ${COLORS.dim}All at once:${COLORS.reset} cd ${path.relative(workspaceRoot, appRoot)} && npx tailjng install-all`);
287
+ console.log(` ${COLORS.dim}One by one:${COLORS.reset} npx tailjng add button`);
288
+ console.log(` ${COLORS.dim}All at once:${COLORS.reset} npx tailjng install-all`);
244
289
  console.log(` ${COLORS.dim}List:${COLORS.reset} npx tailjng list`);
245
290
  console.log(`\n${COLORS.cyan}Then run:${COLORS.reset} ng serve ${selectedApp.name} -o\n`);
246
291
  }
@@ -70,6 +70,38 @@ function writeFileSafe(filePath, content, overwrite = false) {
70
70
  return true;
71
71
  }
72
72
 
73
+ function resolveStyleFilePath(workspaceRoot, styleEntry, appProject) {
74
+ if (path.isAbsolute(styleEntry)) return styleEntry;
75
+ if (styleEntry.startsWith('projects/')) return path.join(workspaceRoot, styleEntry);
76
+ return path.join(workspaceRoot, appProject.root || '', styleEntry);
77
+ }
78
+
79
+ function getTailjngSafelistCssImport(workspaceRoot, styleEntry, appProject) {
80
+ const stylePath = resolveStyleFilePath(workspaceRoot, styleEntry, appProject);
81
+ const safelistPath = path.join(workspaceRoot, 'node_modules', 'tailjng', 'src', 'colors.safelist.css');
82
+ let rel = path.relative(path.dirname(stylePath), safelistPath).split(path.sep).join('/');
83
+ if (!rel.startsWith('.')) rel = `./${rel}`;
84
+ return `@import "${rel}";`;
85
+ }
86
+
87
+ function ensureTailjngSafelistImport(styleFilePath, importLine) {
88
+ if (!fs.existsSync(styleFilePath)) return { changed: false };
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 };
103
+ }
104
+
73
105
  function ensureTailjngStylesInAngularJson(angularJsonPath, projectName, styleLanguage) {
74
106
  const angularJson = readJson(angularJsonPath);
75
107
  const buildOptions = getBuildOptions(angularJson, projectName);
@@ -196,9 +228,82 @@ function patchAppComponentForAlerts(appComponentTsPath, appComponentHtmlPath) {
196
228
  return { changed };
197
229
  }
198
230
 
199
- function getMissingPackages(packageJson, packages) {
231
+ function getMissingPackages(packageJson, packages, workspaceRoot = null) {
200
232
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
201
- return Object.entries(packages).filter(([name]) => !deps[name]);
233
+ return Object.entries(packages).filter(([name]) => {
234
+ if (deps[name]) return false;
235
+ if (workspaceRoot && name.startsWith('@angular/')) {
236
+ const installed = path.join(workspaceRoot, 'node_modules', ...name.split('/'), 'package.json');
237
+ if (fs.existsSync(installed)) return false;
238
+ }
239
+ return true;
240
+ });
241
+ }
242
+
243
+ function getMergedDependencies(packageJson) {
244
+ return { ...packageJson.dependencies, ...packageJson.devDependencies };
245
+ }
246
+
247
+ /** Alinea @angular/animations con la línea de @angular/core del proyecto (evita ERESOLVE 19.2.0 vs 19.2.25). */
248
+ function resolveRuntimePackages(packageJson, basePackages) {
249
+ const packages = { ...basePackages };
250
+ const deps = getMergedDependencies(packageJson);
251
+
252
+ if (deps['@angular/animations']) {
253
+ delete packages['@angular/animations'];
254
+ } else if (deps['@angular/core']) {
255
+ packages['@angular/animations'] = deps['@angular/core'];
256
+ }
257
+
258
+ return packages;
259
+ }
260
+
261
+ function resolveDevPackages(packageJson, basePackages, tailwindReady) {
262
+ const packages = { ...basePackages };
263
+ if (!tailwindReady) return packages;
264
+
265
+ for (const name of ['tailwindcss', '@tailwindcss/postcss', 'postcss', 'autoprefixer']) {
266
+ if (getMergedDependencies(packageJson)[name]) {
267
+ delete packages[name];
268
+ }
269
+ }
270
+ return packages;
271
+ }
272
+
273
+ function hasTailwindSetup(workspaceRoot, packageJson, primaryStylePath) {
274
+ const deps = getMergedDependencies(packageJson);
275
+ if (deps.tailwindcss || deps['@tailwindcss/postcss']) {
276
+ return true;
277
+ }
278
+
279
+ const postcssConfigs = [
280
+ '.postcssrc.json',
281
+ 'postcss.config.js',
282
+ 'postcss.config.mjs',
283
+ 'postcss.config.cjs',
284
+ ];
285
+
286
+ for (const configName of postcssConfigs) {
287
+ const configPath = path.join(workspaceRoot, configName);
288
+ if (!fs.existsSync(configPath)) continue;
289
+ const content = fs.readFileSync(configPath, 'utf8');
290
+ if (/tailwindcss|@tailwindcss\/postcss/.test(content)) {
291
+ return true;
292
+ }
293
+ }
294
+
295
+ const stylePath = path.isAbsolute(primaryStylePath)
296
+ ? primaryStylePath
297
+ : path.join(workspaceRoot, primaryStylePath);
298
+
299
+ if (fs.existsSync(stylePath)) {
300
+ const content = fs.readFileSync(stylePath, 'utf8');
301
+ if (/tailwindcss/.test(content)) {
302
+ return true;
303
+ }
304
+ }
305
+
306
+ return false;
202
307
  }
203
308
 
204
309
  module.exports = {
@@ -212,9 +317,16 @@ module.exports = {
212
317
  getPrimaryStyleEntry,
213
318
  writeFileSafe,
214
319
  ensureTailjngStylesInAngularJson,
320
+ resolveStyleFilePath,
321
+ getTailjngSafelistCssImport,
322
+ ensureTailjngSafelistImport,
215
323
  patchIndexHtml,
216
324
  patchAppConfig,
217
325
  patchAppComponentForAlerts,
218
326
  getMissingPackages,
327
+ getMergedDependencies,
328
+ resolveRuntimePackages,
329
+ resolveDevPackages,
330
+ hasTailwindSetup,
219
331
  fileExists,
220
332
  };
@@ -44,9 +44,9 @@ function buildDefaultThemeBlock() {
44
44
  }`;
45
45
  }
46
46
 
47
- function buildStylesCss() {
47
+ function buildStylesCss(safelistImport = '') {
48
48
  return `@import "tailwindcss";
49
-
49
+ ${safelistImport ? `${safelistImport}\n` : ''}
50
50
  html,
51
51
  body {
52
52
  font-family: 'Arial', sans-serif;
@@ -75,9 +75,9 @@ ${buildDefaultThemeBlock()}
75
75
  `;
76
76
  }
77
77
 
78
- function buildStylesScss() {
78
+ function buildStylesScss(safelistImport = '') {
79
79
  return `@use "tailwindcss";
80
-
80
+ ${safelistImport ? `${safelistImport}\n` : ''}
81
81
  @use "./scss/scroll";
82
82
  @use "./scss/input";
83
83
 
@@ -318,6 +318,7 @@ function buildInitFiles(options) {
318
318
  socketUrl,
319
319
  componentsPath,
320
320
  overwrite,
321
+ safelistImport = '',
321
322
  } = options;
322
323
 
323
324
  const files = [
@@ -349,7 +350,7 @@ function buildInitFiles(options) {
349
350
  if (styleLanguage === 'scss') {
350
351
  files.push({
351
352
  relativePath: primaryStylePath,
352
- content: buildStylesScss(),
353
+ content: buildStylesScss(safelistImport),
353
354
  });
354
355
  files.push({
355
356
  relativePath: 'src/scss/_scroll.scss',
@@ -362,7 +363,7 @@ function buildInitFiles(options) {
362
363
  } else {
363
364
  files.push({
364
365
  relativePath: primaryStylePath,
365
- content: buildStylesCss(),
366
+ content: buildStylesCss(safelistImport),
366
367
  });
367
368
  }
368
369
 
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, signal, computed, Injectable, Inject } from '@angular/core';
2
+ import { InjectionToken, signal, computed, Injectable, Inject, inject } from '@angular/core';
3
3
  import { CurrencyPipe } from '@angular/common';
4
4
  import { formatDistanceToNowStrict } from 'date-fns';
5
5
  import { es } from 'date-fns/locale';
@@ -23,6 +23,8 @@ const TAILJNG_CONFIG = new InjectionToken('TAILJNG_CONFIG');
23
23
  // }
24
24
  // ]
25
25
 
26
+ const TAILJNG_COLORS_CONFIG = new InjectionToken('TAILJNG_COLORS_CONFIG');
27
+
26
28
  // ======================================================
27
29
  // Table Column Interface
28
30
  // This interface defines the structure of a table column in a CRUD application.
@@ -1353,86 +1355,90 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
1353
1355
  args: [{ providedIn: 'root' }]
1354
1356
  }], ctorParameters: () => [] });
1355
1357
 
1358
+ const JCOLORS_DEFAULT_VARIANTS = {
1359
+ 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',
1360
+ 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',
1361
+ 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',
1362
+ primary_ghost: 'bg-transparent text-primary dark:text-input hover:bg-primary/10 dark:hover:bg-input/15 border border-transparent dark:border-transparent',
1363
+ 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',
1364
+ 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',
1365
+ 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',
1366
+ 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',
1367
+ 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',
1368
+ 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',
1369
+ 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',
1370
+ 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',
1371
+ secondary_dark: 'bg-dark-background text-white border border-dark-border hover:bg-dark-accent/50 shadow-md',
1372
+ success: 'bg-green-500 hover:bg-green-600 text-white border border-green-300 dark:border-green-300 shadow-md',
1373
+ 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',
1374
+ 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',
1375
+ success_outline: 'bg-transparent text-green-500 border border-green-500 hover:bg-green-500/10 shadow-sm',
1376
+ success_ghost: 'bg-transparent text-green-500 hover:bg-green-500/10 border border-transparent dark:border-transparent',
1377
+ info: 'bg-blue-500 hover:bg-blue-600 text-white border border-blue-300 dark:border-blue-300 shadow-md',
1378
+ 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',
1379
+ 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',
1380
+ info_outline: 'bg-transparent text-blue-500 border border-blue-500 hover:bg-blue-500/10 shadow-sm',
1381
+ info_ghost: 'bg-transparent text-blue-500 hover:bg-blue-500/10 border border-transparent dark:border-transparent',
1382
+ warning: 'bg-yellow-600 hover:bg-yellow-700 text-white border border-yellow-500 dark:border-yellow-500 shadow-md',
1383
+ 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',
1384
+ 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',
1385
+ warning_outline: 'bg-transparent text-yellow-600 border border-yellow-600 hover:bg-yellow-600/10 shadow-sm',
1386
+ warning_ghost: 'bg-transparent text-yellow-600 hover:bg-yellow-600/10 border border-transparent dark:border-transparent',
1387
+ question: 'bg-purple-500 hover:bg-purple-600 text-white border border-purple-400 dark:border-purple-400 shadow-md',
1388
+ 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',
1389
+ 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',
1390
+ question_outline: 'bg-transparent text-purple-500 border border-purple-500 hover:bg-purple-500/10 shadow-sm',
1391
+ question_ghost: 'bg-transparent text-purple-500 hover:bg-purple-500/10 border border-transparent dark:border-transparent',
1392
+ error: 'bg-red-500 hover:bg-red-600 text-white border border-red-400 dark:border-red-400 shadow-md',
1393
+ 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',
1394
+ 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',
1395
+ error_outline: 'bg-transparent text-red-500 border border-red-500 hover:bg-red-500/10 shadow-sm',
1396
+ error_ghost: 'bg-transparent text-red-500 hover:bg-red-500/10 border border-transparent dark:border-transparent',
1397
+ loading: 'bg-gray-500 hover:bg-gray-600 text-white border border-gray-400 dark:border-gray-400 shadow-md',
1398
+ 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',
1399
+ 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',
1400
+ loading_outline: 'bg-transparent text-gray-500 border border-gray-500 hover:bg-gray-500/10 shadow-sm',
1401
+ loading_ghost: 'bg-transparent text-gray-500 hover:bg-gray-500/10 border border-transparent dark:border-transparent',
1402
+ orange: 'bg-orange-500 hover:bg-orange-600 text-white border border-orange-300 dark:border-orange-300 shadow-md',
1403
+ 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',
1404
+ 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',
1405
+ orange_outline: 'bg-transparent text-orange-500 border border-orange-500 hover:bg-orange-500/10 shadow-sm',
1406
+ orange_ghost: 'bg-transparent text-orange-500 hover:bg-orange-500/10 border border-transparent dark:border-transparent',
1407
+ cyan: 'bg-cyan-500 hover:bg-cyan-600 text-white border border-cyan-300 dark:border-cyan-300 shadow-md',
1408
+ 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',
1409
+ 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',
1410
+ cyan_outline: 'bg-transparent text-cyan-500 border border-cyan-500 hover:bg-cyan-500/10 shadow-sm',
1411
+ cyan_ghost: 'bg-transparent text-cyan-500 hover:bg-cyan-500/10 border border-transparent dark:border-transparent',
1412
+ purple: 'bg-purple-500 hover:bg-purple-600 text-white border border-purple-300 dark:border-purple-300 shadow-md',
1413
+ 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',
1414
+ 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',
1415
+ purple_outline: 'bg-transparent text-purple-500 border border-purple-500 hover:bg-purple-500/10 shadow-sm',
1416
+ purple_ghost: 'bg-transparent text-purple-500 hover:bg-purple-500/10 border border-transparent dark:border-transparent',
1417
+ teal: 'bg-teal-500 hover:bg-teal-600 text-white border border-teal-300 dark:border-teal-300 shadow-md',
1418
+ 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',
1419
+ 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',
1420
+ teal_outline: 'bg-transparent text-teal-500 border border-teal-500 hover:bg-teal-500/10 shadow-sm',
1421
+ teal_ghost: 'bg-transparent text-teal-500 hover:bg-teal-500/10 border border-transparent dark:border-transparent',
1422
+ pink: 'bg-pink-500 hover:bg-pink-600 text-white border border-pink-300 dark:border-pink-300 shadow-md',
1423
+ 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',
1424
+ 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',
1425
+ pink_outline: 'bg-transparent text-pink-500 border border-pink-500 hover:bg-pink-500/10 shadow-sm',
1426
+ pink_ghost: 'bg-transparent text-pink-500 hover:bg-pink-500/10 border border-transparent dark:border-transparent',
1427
+ green: 'bg-green-500 hover:bg-green-600 text-white border border-green-300 dark:border-green-300 shadow-md',
1428
+ 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',
1429
+ 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',
1430
+ green_outline: 'bg-transparent text-green-500 border border-green-500 hover:bg-green-500/10 shadow-sm',
1431
+ green_ghost: 'bg-transparent text-green-500 hover:bg-green-500/10 border border-transparent dark:border-transparent',
1432
+ default: 'text-black dark:text-white shadow-md border border-dark-border dark:border-border',
1433
+ 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',
1434
+ 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',
1435
+ default_ghost: 'bg-transparent text-black dark:text-white hover:bg-black/5 dark:hover:bg-white/10 border border-transparent dark:border-transparent',
1436
+ };
1356
1437
  class JColorsService {
1357
- // Variants
1438
+ colorsConfig = inject(TAILJNG_COLORS_CONFIG, { optional: true });
1358
1439
  variants = {
1359
- 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',
1360
- 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',
1361
- 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',
1362
- primary_ghost: 'bg-transparent text-primary dark:text-input hover:bg-primary/10 dark:hover:bg-input/15 border border-transparent dark:border-transparent',
1363
- 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',
1364
- 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',
1365
- 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',
1366
- 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',
1367
- 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',
1368
- 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',
1369
- 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',
1370
- 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',
1371
- secondary_dark: 'bg-dark-background text-white border border-dark-border hover:bg-dark-accent/50 shadow-md',
1372
- success: 'bg-green-500 hover:bg-green-600 text-white border border-green-300 dark:border-green-300 shadow-md',
1373
- 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',
1374
- 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',
1375
- success_outline: 'bg-transparent text-green-500 border border-green-500 hover:bg-green-500/10 shadow-sm',
1376
- success_ghost: 'bg-transparent text-green-500 hover:bg-green-500/10 border border-transparent dark:border-transparent',
1377
- info: 'bg-blue-500 hover:bg-blue-600 text-white border border-blue-300 dark:border-blue-300 shadow-md',
1378
- 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',
1379
- 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',
1380
- info_outline: 'bg-transparent text-blue-500 border border-blue-500 hover:bg-blue-500/10 shadow-sm',
1381
- info_ghost: 'bg-transparent text-blue-500 hover:bg-blue-500/10 border border-transparent dark:border-transparent',
1382
- warning: 'bg-yellow-600 hover:bg-yellow-700 text-white border border-yellow-500 dark:border-yellow-500 shadow-md',
1383
- 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',
1384
- 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',
1385
- warning_outline: 'bg-transparent text-yellow-600 border border-yellow-600 hover:bg-yellow-600/10 shadow-sm',
1386
- warning_ghost: 'bg-transparent text-yellow-600 hover:bg-yellow-600/10 border border-transparent dark:border-transparent',
1387
- question: 'bg-purple-500 hover:bg-purple-600 text-white border border-purple-400 dark:border-purple-400 shadow-md',
1388
- 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',
1389
- 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',
1390
- question_outline: 'bg-transparent text-purple-500 border border-purple-500 hover:bg-purple-500/10 shadow-sm',
1391
- question_ghost: 'bg-transparent text-purple-500 hover:bg-purple-500/10 border border-transparent dark:border-transparent',
1392
- error: 'bg-red-500 hover:bg-red-600 text-white border border-red-400 dark:border-red-400 shadow-md',
1393
- 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',
1394
- 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',
1395
- error_outline: 'bg-transparent text-red-500 border border-red-500 hover:bg-red-500/10 shadow-sm',
1396
- error_ghost: 'bg-transparent text-red-500 hover:bg-red-500/10 border border-transparent dark:border-transparent',
1397
- loading: 'bg-gray-500 hover:bg-gray-600 text-white border border-gray-400 dark:border-gray-400 shadow-md',
1398
- 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',
1399
- 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',
1400
- loading_outline: 'bg-transparent text-gray-500 border border-gray-500 hover:bg-gray-500/10 shadow-sm',
1401
- loading_ghost: 'bg-transparent text-gray-500 hover:bg-gray-500/10 border border-transparent dark:border-transparent',
1402
- orange: 'bg-orange-500 hover:bg-orange-600 text-white border border-orange-300 dark:border-orange-300 shadow-md',
1403
- 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',
1404
- 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',
1405
- orange_outline: 'bg-transparent text-orange-500 border border-orange-500 hover:bg-orange-500/10 shadow-sm',
1406
- orange_ghost: 'bg-transparent text-orange-500 hover:bg-orange-500/10 border border-transparent dark:border-transparent',
1407
- cyan: 'bg-cyan-500 hover:bg-cyan-600 text-white border border-cyan-300 dark:border-cyan-300 shadow-md',
1408
- 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',
1409
- 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',
1410
- cyan_outline: 'bg-transparent text-cyan-500 border border-cyan-500 hover:bg-cyan-500/10 shadow-sm',
1411
- cyan_ghost: 'bg-transparent text-cyan-500 hover:bg-cyan-500/10 border border-transparent dark:border-transparent',
1412
- purple: 'bg-purple-500 hover:bg-purple-600 text-white border border-purple-300 dark:border-purple-300 shadow-md',
1413
- 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',
1414
- 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',
1415
- purple_outline: 'bg-transparent text-purple-500 border border-purple-500 hover:bg-purple-500/10 shadow-sm',
1416
- purple_ghost: 'bg-transparent text-purple-500 hover:bg-purple-500/10 border border-transparent dark:border-transparent',
1417
- teal: 'bg-teal-500 hover:bg-teal-600 text-white border border-teal-300 dark:border-teal-300 shadow-md',
1418
- 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',
1419
- 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',
1420
- teal_outline: 'bg-transparent text-teal-500 border border-teal-500 hover:bg-teal-500/10 shadow-sm',
1421
- teal_ghost: 'bg-transparent text-teal-500 hover:bg-teal-500/10 border border-transparent dark:border-transparent',
1422
- pink: 'bg-pink-500 hover:bg-pink-600 text-white border border-pink-300 dark:border-pink-300 shadow-md',
1423
- 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',
1424
- 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',
1425
- pink_outline: 'bg-transparent text-pink-500 border border-pink-500 hover:bg-pink-500/10 shadow-sm',
1426
- pink_ghost: 'bg-transparent text-pink-500 hover:bg-pink-500/10 border border-transparent dark:border-transparent',
1427
- green: 'bg-green-500 hover:bg-green-600 text-white border border-green-300 dark:border-green-300 shadow-md',
1428
- 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',
1429
- 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',
1430
- green_outline: 'bg-transparent text-green-500 border border-green-500 hover:bg-green-500/10 shadow-sm',
1431
- green_ghost: 'bg-transparent text-green-500 hover:bg-green-500/10 border border-transparent dark:border-transparent',
1432
- default: 'text-black dark:text-white shadow-md border border-dark-border dark:border-border',
1433
- 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',
1434
- 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',
1435
- default_ghost: 'bg-transparent text-black dark:text-white hover:bg-black/5 dark:hover:bg-white/10 border border-transparent dark:border-transparent',
1440
+ ...JCOLORS_DEFAULT_VARIANTS,
1441
+ ...(this.colorsConfig?.variants ?? {}),
1436
1442
  };
1437
1443
  // Function to get variant with optional border and shadow
1438
1444
  getVariantClass(type, hasShadow = true, hasBorder = true) {
@@ -2290,5 +2296,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
2290
2296
  * Generated bundle index. Do not edit.
2291
2297
  */
2292
2298
 
2293
- export { JAlertDialogService, JAlertToastService, JCalendarService, JColorsService, JConverterCrudService, JDialogShared, JErrorHandlerHttpService, JExcelFilterService, JExcelService, JFileHttpService, JFormShared, JGenericCrudService, JIconsService, JParamsHttpService, JThemeService, JTransformService, JUploadFilterService, TAILJNG_CONFIG };
2299
+ export { JAlertDialogService, JAlertToastService, JCOLORS_DEFAULT_VARIANTS, JCalendarService, JColorsService, JConverterCrudService, JDialogShared, JErrorHandlerHttpService, JExcelFilterService, JExcelService, JFileHttpService, JFormShared, JGenericCrudService, JIconsService, JParamsHttpService, JThemeService, JTransformService, JUploadFilterService, TAILJNG_COLORS_CONFIG, TAILJNG_CONFIG };
2294
2300
  //# sourceMappingURL=tailjng.mjs.map