clases 1.1.5 → 1.1.6

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/dist/index.cjs CHANGED
@@ -17,38 +17,22 @@ function createCl(...plugins) {
17
17
  }
18
18
  if (typeof value === "object") {
19
19
  return Object.entries(value).map(([nestedKey, nestedValue]) => {
20
- const isRegistered = registry[nestedKey] !== void 0;
21
- let nextKey;
22
- if (key === "" || key === "base") {
23
- nextKey = nestedKey;
24
- } else if (isRegistered) {
25
- nextKey = `${key}:${nestedKey}`;
26
- } else {
27
- nextKey = key;
20
+ const isPrefix = registry[nestedKey] !== void 0;
21
+ if (isPrefix) {
22
+ const nextKey = key ? `${key}:${nestedKey}` : nestedKey;
23
+ return process(nextKey, nestedValue);
28
24
  }
29
- return process(nextKey, nestedValue);
25
+ return nestedValue ? process(key, nestedKey) : "";
30
26
  }).join(" ");
31
27
  }
32
- const resolvedPrefix = key.split(":").map((part) => {
33
- if (part === "base") return null;
34
- return registry[part] || null;
35
- }).filter(Boolean).join(":");
28
+ const resolvedPrefix = key.split(":").map((part) => registry[part] || null).filter(Boolean).join(":");
36
29
  if (typeof value === "string") {
37
30
  return value.split(/[,\s\n]+/).filter(Boolean).map((cls) => !resolvedPrefix ? cls : `${resolvedPrefix}:${cls}`).join(" ");
38
31
  }
39
32
  return "";
40
33
  };
41
34
  return (...inputs) => {
42
- const processed = inputs.map((input) => {
43
- if (input !== null && typeof input === "object" && !Array.isArray(input)) {
44
- return Object.entries(input).map(([k, v]) => {
45
- if (v === true) return k;
46
- if (registry[k] || k === "base") return process(k, v);
47
- return process("base", v);
48
- }).join(" ");
49
- }
50
- return input;
51
- });
35
+ const processed = inputs.map((input) => process("", input));
52
36
  return tailwindMerge.twMerge(clsx__default.default(processed));
53
37
  };
54
38
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["twMerge","clsx"],"mappings":"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","file":"index.cjs","sourcesContent":["import { twMerge } from 'tailwind-merge';\r\nimport clsx, { type ClassValue } from 'clsx';\r\n\r\n/**\r\n * Motor de prefijos con soporte para plugins, lógica transparente y limpieza via twMerge.\r\n */\r\nexport function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins) {\r\n const registry: Record<string, string> = Object.assign({}, ...plugins);\r\n\r\n const process = (key: string, value: any): string => {\r\n if (!value) return '';\r\n\r\n // 1. Manejo de Arrays\r\n if (Array.isArray(value)) {\r\n return value\r\n .map((v) => process(key, v))\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n // 2. Manejo de Objetos (Nesting y Lógica)\r\n if (typeof value === 'object') {\r\n return Object.entries(value)\r\n .map(([nestedKey, nestedValue]) => {\r\n const isRegistered = registry[nestedKey] !== undefined;\r\n\r\n let nextKey: string;\r\n if (key === '' || key === 'base') {\r\n // Si no hay prefijo previo, el hijo inicia la cadena\r\n nextKey = nestedKey;\r\n } else if (isRegistered) {\r\n // Si el hijo es un prefijo registrado, se concatena (ej: md:hover)\r\n nextKey = `${key}:${nestedKey}`;\r\n } else {\r\n // Si el hijo es lógica transparente (ej: variants), heredamos el prefijo padre\r\n nextKey = key;\r\n }\r\n\r\n return process(nextKey, nestedValue);\r\n })\r\n .join(' ');\r\n }\r\n\r\n // 3. Resolución Final de Prefijos\r\n const resolvedPrefix = key\r\n .split(':')\r\n .map((part) => {\r\n if (part === 'base') return null; // 'base' nunca se imprime\r\n return registry[part] || null; // Solo lo registrado sobrevive\r\n })\r\n .filter(Boolean)\r\n .join(':');\r\n\r\n // 4. Aplicación de Clases\r\n if (typeof value === 'string') {\r\n return value\r\n .split(/[,\\s\\n]+/)\r\n .filter(Boolean)\r\n .map((cls) => (!resolvedPrefix ? cls : `${resolvedPrefix}:${cls}`))\r\n .join(' ');\r\n }\r\n return '';\r\n };\r\n\r\n /**\r\n * Función resultante (tw)\r\n */\r\n return (...inputs: ClassValue[]) => {\r\n const processed = inputs.map((input) => {\r\n if (input !== null && typeof input === 'object' && !Array.isArray(input)) {\r\n return Object.entries(input)\r\n .map(([k, v]) => {\r\n // Soporte para booleanos nativos de clsx: { 'clase': true }\r\n if (v === true) return k;\r\n\r\n // Si la llave es un prefijo registrado (md, hover, ui), empezamos proceso\r\n if (registry[k] || k === 'base') return process(k, v);\r\n\r\n // Si no es prefijo (ej: variantes dinámicas), procesamos el interior como base\r\n return process('base', v);\r\n })\r\n .join(' ');\r\n }\r\n return input;\r\n });\r\n\r\n // Resolvemos con clsx y limpiamos conflictos con twMerge\r\n return twMerge(clsx(processed));\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["twMerge","clsx"],"mappings":";;;;;;;;;;AAGO,SAAS,YAAuD,OAAA,EAAmB;AACtF,EAAA,MAAM,WAAmC,MAAA,CAAO,MAAA,CAAO,EAAC,EAAG,GAAG,OAAO,CAAA;AAErE,EAAA,MAAM,OAAA,GAAU,CAAC,GAAA,EAAa,KAAA,KAAuB;AACjD,IAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAGnB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACtB,MAAA,OAAO,KAAA,CACF,GAAA,CAAI,CAAC,CAAA,KAAM,OAAA,CAAQ,GAAA,EAAK,CAAC,CAAC,CAAA,CAC1B,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAAA,IACjB;AAGA,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,MAAA,OAAO,MAAA,CAAO,QAAQ,KAAK,CAAA,CACtB,IAAI,CAAC,CAAC,SAAA,EAAW,WAAW,CAAA,KAAM;AAC/B,QAAA,MAAM,QAAA,GAAW,QAAA,CAAS,SAAS,CAAA,KAAM,MAAA;AAEzC,QAAA,IAAI,QAAA,EAAU;AACV,UAAA,MAAM,UAAU,GAAA,GAAM,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,GAAK,SAAA;AAC9C,UAAA,OAAO,OAAA,CAAQ,SAAS,WAAW,CAAA;AAAA,QACvC;AAGA,QAAA,OAAO,WAAA,GAAc,OAAA,CAAQ,GAAA,EAAK,SAAS,CAAA,GAAI,EAAA;AAAA,MACnD,CAAC,CAAA,CACA,IAAA,CAAK,GAAG,CAAA;AAAA,IACjB;AAGA,IAAA,MAAM,iBAAiB,GAAA,CAClB,KAAA,CAAM,GAAG,CAAA,CACT,IAAI,CAAC,IAAA,KAAS,QAAA,CAAS,IAAI,KAAK,IAAI,CAAA,CACpC,OAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEb,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,MAAA,OAAO,KAAA,CACF,MAAM,UAAU,CAAA,CAChB,OAAO,OAAO,CAAA,CACd,IAAI,CAAC,GAAA,KAAS,CAAC,cAAA,GAAiB,GAAA,GAAM,GAAG,cAAc,CAAA,CAAA,EAAI,GAAG,CAAA,CAAG,CAAA,CACjE,KAAK,GAAG,CAAA;AAAA,IACjB;AACA,IAAA,OAAO,EAAA;AAAA,EACX,CAAA;AAEA,EAAA,OAAO,IAAI,MAAA,KAAyB;AAEhC,IAAA,MAAM,SAAA,GAAY,OAAO,GAAA,CAAI,CAAC,UAAU,OAAA,CAAQ,EAAA,EAAI,KAAK,CAAC,CAAA;AAC1D,IAAA,OAAOA,qBAAA,CAAQC,qBAAA,CAAK,SAAS,CAAC,CAAA;AAAA,EAClC,CAAA;AACJ","file":"index.cjs","sourcesContent":["import { twMerge } from 'tailwind-merge';\r\nimport clsx, { type ClassValue } from 'clsx';\r\n\r\nexport function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins) {\r\n const registry: Record<string, string> = Object.assign({}, ...plugins);\r\n\r\n const process = (key: string, value: any): string => {\r\n if (!value) return '';\r\n\r\n // 1. Soporte Multilínea (Arrays)\r\n if (Array.isArray(value)) {\r\n return value\r\n .map((v) => process(key, v))\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n // 2. Objetos de Prefijos\r\n if (typeof value === 'object') {\r\n return Object.entries(value)\r\n .map(([nestedKey, nestedValue]) => {\r\n const isPrefix = registry[nestedKey] !== undefined;\r\n\r\n if (isPrefix) {\r\n const nextKey = key ? `${key}:${nestedKey}` : nestedKey;\r\n return process(nextKey, nestedValue);\r\n }\r\n\r\n // Lógica estándar: si no es prefijo, es una clase condicional\r\n return nestedValue ? process(key, nestedKey) : '';\r\n })\r\n .join(' ');\r\n }\r\n\r\n // 3. Resolución y Aplicación\r\n const resolvedPrefix = key\r\n .split(':')\r\n .map((part) => registry[part] || null)\r\n .filter(Boolean)\r\n .join(':');\r\n\r\n if (typeof value === 'string') {\r\n return value\r\n .split(/[,\\s\\n]+/)\r\n .filter(Boolean)\r\n .map((cls) => (!resolvedPrefix ? cls : `${resolvedPrefix}:${cls}`))\r\n .join(' ');\r\n }\r\n return '';\r\n };\r\n\r\n return (...inputs: ClassValue[]) => {\r\n // Procesamos uno a uno para capturar objetos de prefijos antes de que clsx los aplane\r\n const processed = inputs.map((input) => process('', input));\r\n return twMerge(clsx(processed));\r\n };\r\n}\r\n"]}
package/dist/index.d.cts CHANGED
@@ -1,8 +1,5 @@
1
1
  import { ClassValue } from 'clsx';
2
2
 
3
- /**
4
- * Motor de prefijos con soporte para plugins, lógica transparente y limpieza via twMerge.
5
- */
6
3
  declare function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins): (...inputs: ClassValue[]) => string;
7
4
 
8
5
  export { createCl };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,5 @@
1
1
  import { ClassValue } from 'clsx';
2
2
 
3
- /**
4
- * Motor de prefijos con soporte para plugins, lógica transparente y limpieza via twMerge.
5
- */
6
3
  declare function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins): (...inputs: ClassValue[]) => string;
7
4
 
8
5
  export { createCl };
package/dist/index.js CHANGED
@@ -11,38 +11,22 @@ function createCl(...plugins) {
11
11
  }
12
12
  if (typeof value === "object") {
13
13
  return Object.entries(value).map(([nestedKey, nestedValue]) => {
14
- const isRegistered = registry[nestedKey] !== void 0;
15
- let nextKey;
16
- if (key === "" || key === "base") {
17
- nextKey = nestedKey;
18
- } else if (isRegistered) {
19
- nextKey = `${key}:${nestedKey}`;
20
- } else {
21
- nextKey = key;
14
+ const isPrefix = registry[nestedKey] !== void 0;
15
+ if (isPrefix) {
16
+ const nextKey = key ? `${key}:${nestedKey}` : nestedKey;
17
+ return process(nextKey, nestedValue);
22
18
  }
23
- return process(nextKey, nestedValue);
19
+ return nestedValue ? process(key, nestedKey) : "";
24
20
  }).join(" ");
25
21
  }
26
- const resolvedPrefix = key.split(":").map((part) => {
27
- if (part === "base") return null;
28
- return registry[part] || null;
29
- }).filter(Boolean).join(":");
22
+ const resolvedPrefix = key.split(":").map((part) => registry[part] || null).filter(Boolean).join(":");
30
23
  if (typeof value === "string") {
31
24
  return value.split(/[,\s\n]+/).filter(Boolean).map((cls) => !resolvedPrefix ? cls : `${resolvedPrefix}:${cls}`).join(" ");
32
25
  }
33
26
  return "";
34
27
  };
35
28
  return (...inputs) => {
36
- const processed = inputs.map((input) => {
37
- if (input !== null && typeof input === "object" && !Array.isArray(input)) {
38
- return Object.entries(input).map(([k, v]) => {
39
- if (v === true) return k;
40
- if (registry[k] || k === "base") return process(k, v);
41
- return process("base", v);
42
- }).join(" ");
43
- }
44
- return input;
45
- });
29
+ const processed = inputs.map((input) => process("", input));
46
30
  return twMerge(clsx(processed));
47
31
  };
48
32
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;AAMO,SAAS,YAAuD,OAAA,EAAmB;AACtF,EAAA,MAAM,WAAmC,MAAA,CAAO,MAAA,CAAO,EAAC,EAAG,GAAG,OAAO,CAAA;AAErE,EAAA,MAAM,OAAA,GAAU,CAAC,GAAA,EAAa,KAAA,KAAuB;AACjD,IAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAGnB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACtB,MAAA,OAAO,KAAA,CACF,GAAA,CAAI,CAAC,CAAA,KAAM,OAAA,CAAQ,GAAA,EAAK,CAAC,CAAC,CAAA,CAC1B,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAAA,IACjB;AAGA,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,MAAA,OAAO,MAAA,CAAO,QAAQ,KAAK,CAAA,CACtB,IAAI,CAAC,CAAC,SAAA,EAAW,WAAW,CAAA,KAAM;AAC/B,QAAA,MAAM,YAAA,GAAe,QAAA,CAAS,SAAS,CAAA,KAAM,MAAA;AAE7C,QAAA,IAAI,OAAA;AACJ,QAAA,IAAI,GAAA,KAAQ,EAAA,IAAM,GAAA,KAAQ,MAAA,EAAQ;AAE9B,UAAA,OAAA,GAAU,SAAA;AAAA,QACd,WAAW,YAAA,EAAc;AAErB,UAAA,OAAA,GAAU,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA;AAAA,QACjC,CAAA,MAAO;AAEH,UAAA,OAAA,GAAU,GAAA;AAAA,QACd;AAEA,QAAA,OAAO,OAAA,CAAQ,SAAS,WAAW,CAAA;AAAA,MACvC,CAAC,CAAA,CACA,IAAA,CAAK,GAAG,CAAA;AAAA,IACjB;AAGA,IAAA,MAAM,iBAAiB,GAAA,CAClB,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,IAAA,KAAS;AACX,MAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,IAAA;AAC5B,MAAA,OAAO,QAAA,CAAS,IAAI,CAAA,IAAK,IAAA;AAAA,IAC7B,CAAC,CAAA,CACA,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAGb,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,MAAA,OAAO,KAAA,CACF,MAAM,UAAU,CAAA,CAChB,OAAO,OAAO,CAAA,CACd,IAAI,CAAC,GAAA,KAAS,CAAC,cAAA,GAAiB,GAAA,GAAM,GAAG,cAAc,CAAA,CAAA,EAAI,GAAG,CAAA,CAAG,CAAA,CACjE,KAAK,GAAG,CAAA;AAAA,IACjB;AACA,IAAA,OAAO,EAAA;AAAA,EACX,CAAA;AAKA,EAAA,OAAO,IAAI,MAAA,KAAyB;AAChC,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU;AACpC,MAAA,IAAI,KAAA,KAAU,QAAQ,OAAO,KAAA,KAAU,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACtE,QAAA,OAAO,MAAA,CAAO,QAAQ,KAAK,CAAA,CACtB,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM;AAEb,UAAA,IAAI,CAAA,KAAM,MAAM,OAAO,CAAA;AAGvB,UAAA,IAAI,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,KAAM,QAAQ,OAAO,OAAA,CAAQ,GAAG,CAAC,CAAA;AAGpD,UAAA,OAAO,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAAA,QAC5B,CAAC,CAAA,CACA,IAAA,CAAK,GAAG,CAAA;AAAA,MACjB;AACA,MAAA,OAAO,KAAA;AAAA,IACX,CAAC,CAAA;AAGD,IAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAC,CAAA;AAAA,EAClC,CAAA;AACJ","file":"index.js","sourcesContent":["import { twMerge } from 'tailwind-merge';\r\nimport clsx, { type ClassValue } from 'clsx';\r\n\r\n/**\r\n * Motor de prefijos con soporte para plugins, lógica transparente y limpieza via twMerge.\r\n */\r\nexport function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins) {\r\n const registry: Record<string, string> = Object.assign({}, ...plugins);\r\n\r\n const process = (key: string, value: any): string => {\r\n if (!value) return '';\r\n\r\n // 1. Manejo de Arrays\r\n if (Array.isArray(value)) {\r\n return value\r\n .map((v) => process(key, v))\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n // 2. Manejo de Objetos (Nesting y Lógica)\r\n if (typeof value === 'object') {\r\n return Object.entries(value)\r\n .map(([nestedKey, nestedValue]) => {\r\n const isRegistered = registry[nestedKey] !== undefined;\r\n\r\n let nextKey: string;\r\n if (key === '' || key === 'base') {\r\n // Si no hay prefijo previo, el hijo inicia la cadena\r\n nextKey = nestedKey;\r\n } else if (isRegistered) {\r\n // Si el hijo es un prefijo registrado, se concatena (ej: md:hover)\r\n nextKey = `${key}:${nestedKey}`;\r\n } else {\r\n // Si el hijo es lógica transparente (ej: variants), heredamos el prefijo padre\r\n nextKey = key;\r\n }\r\n\r\n return process(nextKey, nestedValue);\r\n })\r\n .join(' ');\r\n }\r\n\r\n // 3. Resolución Final de Prefijos\r\n const resolvedPrefix = key\r\n .split(':')\r\n .map((part) => {\r\n if (part === 'base') return null; // 'base' nunca se imprime\r\n return registry[part] || null; // Solo lo registrado sobrevive\r\n })\r\n .filter(Boolean)\r\n .join(':');\r\n\r\n // 4. Aplicación de Clases\r\n if (typeof value === 'string') {\r\n return value\r\n .split(/[,\\s\\n]+/)\r\n .filter(Boolean)\r\n .map((cls) => (!resolvedPrefix ? cls : `${resolvedPrefix}:${cls}`))\r\n .join(' ');\r\n }\r\n return '';\r\n };\r\n\r\n /**\r\n * Función resultante (tw)\r\n */\r\n return (...inputs: ClassValue[]) => {\r\n const processed = inputs.map((input) => {\r\n if (input !== null && typeof input === 'object' && !Array.isArray(input)) {\r\n return Object.entries(input)\r\n .map(([k, v]) => {\r\n // Soporte para booleanos nativos de clsx: { 'clase': true }\r\n if (v === true) return k;\r\n\r\n // Si la llave es un prefijo registrado (md, hover, ui), empezamos proceso\r\n if (registry[k] || k === 'base') return process(k, v);\r\n\r\n // Si no es prefijo (ej: variantes dinámicas), procesamos el interior como base\r\n return process('base', v);\r\n })\r\n .join(' ');\r\n }\r\n return input;\r\n });\r\n\r\n // Resolvemos con clsx y limpiamos conflictos con twMerge\r\n return twMerge(clsx(processed));\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;AAGO,SAAS,YAAuD,OAAA,EAAmB;AACtF,EAAA,MAAM,WAAmC,MAAA,CAAO,MAAA,CAAO,EAAC,EAAG,GAAG,OAAO,CAAA;AAErE,EAAA,MAAM,OAAA,GAAU,CAAC,GAAA,EAAa,KAAA,KAAuB;AACjD,IAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAGnB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACtB,MAAA,OAAO,KAAA,CACF,GAAA,CAAI,CAAC,CAAA,KAAM,OAAA,CAAQ,GAAA,EAAK,CAAC,CAAC,CAAA,CAC1B,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAAA,IACjB;AAGA,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,MAAA,OAAO,MAAA,CAAO,QAAQ,KAAK,CAAA,CACtB,IAAI,CAAC,CAAC,SAAA,EAAW,WAAW,CAAA,KAAM;AAC/B,QAAA,MAAM,QAAA,GAAW,QAAA,CAAS,SAAS,CAAA,KAAM,MAAA;AAEzC,QAAA,IAAI,QAAA,EAAU;AACV,UAAA,MAAM,UAAU,GAAA,GAAM,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,GAAK,SAAA;AAC9C,UAAA,OAAO,OAAA,CAAQ,SAAS,WAAW,CAAA;AAAA,QACvC;AAGA,QAAA,OAAO,WAAA,GAAc,OAAA,CAAQ,GAAA,EAAK,SAAS,CAAA,GAAI,EAAA;AAAA,MACnD,CAAC,CAAA,CACA,IAAA,CAAK,GAAG,CAAA;AAAA,IACjB;AAGA,IAAA,MAAM,iBAAiB,GAAA,CAClB,KAAA,CAAM,GAAG,CAAA,CACT,IAAI,CAAC,IAAA,KAAS,QAAA,CAAS,IAAI,KAAK,IAAI,CAAA,CACpC,OAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEb,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,MAAA,OAAO,KAAA,CACF,MAAM,UAAU,CAAA,CAChB,OAAO,OAAO,CAAA,CACd,IAAI,CAAC,GAAA,KAAS,CAAC,cAAA,GAAiB,GAAA,GAAM,GAAG,cAAc,CAAA,CAAA,EAAI,GAAG,CAAA,CAAG,CAAA,CACjE,KAAK,GAAG,CAAA;AAAA,IACjB;AACA,IAAA,OAAO,EAAA;AAAA,EACX,CAAA;AAEA,EAAA,OAAO,IAAI,MAAA,KAAyB;AAEhC,IAAA,MAAM,SAAA,GAAY,OAAO,GAAA,CAAI,CAAC,UAAU,OAAA,CAAQ,EAAA,EAAI,KAAK,CAAC,CAAA;AAC1D,IAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAC,CAAA;AAAA,EAClC,CAAA;AACJ","file":"index.js","sourcesContent":["import { twMerge } from 'tailwind-merge';\r\nimport clsx, { type ClassValue } from 'clsx';\r\n\r\nexport function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins) {\r\n const registry: Record<string, string> = Object.assign({}, ...plugins);\r\n\r\n const process = (key: string, value: any): string => {\r\n if (!value) return '';\r\n\r\n // 1. Soporte Multilínea (Arrays)\r\n if (Array.isArray(value)) {\r\n return value\r\n .map((v) => process(key, v))\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n // 2. Objetos de Prefijos\r\n if (typeof value === 'object') {\r\n return Object.entries(value)\r\n .map(([nestedKey, nestedValue]) => {\r\n const isPrefix = registry[nestedKey] !== undefined;\r\n\r\n if (isPrefix) {\r\n const nextKey = key ? `${key}:${nestedKey}` : nestedKey;\r\n return process(nextKey, nestedValue);\r\n }\r\n\r\n // Lógica estándar: si no es prefijo, es una clase condicional\r\n return nestedValue ? process(key, nestedKey) : '';\r\n })\r\n .join(' ');\r\n }\r\n\r\n // 3. Resolución y Aplicación\r\n const resolvedPrefix = key\r\n .split(':')\r\n .map((part) => registry[part] || null)\r\n .filter(Boolean)\r\n .join(':');\r\n\r\n if (typeof value === 'string') {\r\n return value\r\n .split(/[,\\s\\n]+/)\r\n .filter(Boolean)\r\n .map((cls) => (!resolvedPrefix ? cls : `${resolvedPrefix}:${cls}`))\r\n .join(' ');\r\n }\r\n return '';\r\n };\r\n\r\n return (...inputs: ClassValue[]) => {\r\n // Procesamos uno a uno para capturar objetos de prefijos antes de que clsx los aplane\r\n const processed = inputs.map((input) => process('', input));\r\n return twMerge(clsx(processed));\r\n };\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clases",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/src/index.ts CHANGED
@@ -1,16 +1,13 @@
1
1
  import { twMerge } from 'tailwind-merge';
2
2
  import clsx, { type ClassValue } from 'clsx';
3
3
 
4
- /**
5
- * Motor de prefijos con soporte para plugins, lógica transparente y limpieza via twMerge.
6
- */
7
4
  export function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins) {
8
5
  const registry: Record<string, string> = Object.assign({}, ...plugins);
9
6
 
10
7
  const process = (key: string, value: any): string => {
11
8
  if (!value) return '';
12
9
 
13
- // 1. Manejo de Arrays
10
+ // 1. Soporte Multilínea (Arrays)
14
11
  if (Array.isArray(value)) {
15
12
  return value
16
13
  .map((v) => process(key, v))
@@ -18,40 +15,30 @@ export function createCl<TPlugins extends Record<string, string>[]>(...plugins:
18
15
  .join(' ');
19
16
  }
20
17
 
21
- // 2. Manejo de Objetos (Nesting y Lógica)
18
+ // 2. Objetos de Prefijos
22
19
  if (typeof value === 'object') {
23
20
  return Object.entries(value)
24
21
  .map(([nestedKey, nestedValue]) => {
25
- const isRegistered = registry[nestedKey] !== undefined;
22
+ const isPrefix = registry[nestedKey] !== undefined;
26
23
 
27
- let nextKey: string;
28
- if (key === '' || key === 'base') {
29
- // Si no hay prefijo previo, el hijo inicia la cadena
30
- nextKey = nestedKey;
31
- } else if (isRegistered) {
32
- // Si el hijo es un prefijo registrado, se concatena (ej: md:hover)
33
- nextKey = `${key}:${nestedKey}`;
34
- } else {
35
- // Si el hijo es lógica transparente (ej: variants), heredamos el prefijo padre
36
- nextKey = key;
24
+ if (isPrefix) {
25
+ const nextKey = key ? `${key}:${nestedKey}` : nestedKey;
26
+ return process(nextKey, nestedValue);
37
27
  }
38
28
 
39
- return process(nextKey, nestedValue);
29
+ // Lógica estándar: si no es prefijo, es una clase condicional
30
+ return nestedValue ? process(key, nestedKey) : '';
40
31
  })
41
32
  .join(' ');
42
33
  }
43
34
 
44
- // 3. Resolución Final de Prefijos
35
+ // 3. Resolución y Aplicación
45
36
  const resolvedPrefix = key
46
37
  .split(':')
47
- .map((part) => {
48
- if (part === 'base') return null; // 'base' nunca se imprime
49
- return registry[part] || null; // Solo lo registrado sobrevive
50
- })
38
+ .map((part) => registry[part] || null)
51
39
  .filter(Boolean)
52
40
  .join(':');
53
41
 
54
- // 4. Aplicación de Clases
55
42
  if (typeof value === 'string') {
56
43
  return value
57
44
  .split(/[,\s\n]+/)
@@ -62,29 +49,9 @@ export function createCl<TPlugins extends Record<string, string>[]>(...plugins:
62
49
  return '';
63
50
  };
64
51
 
65
- /**
66
- * Función resultante (tw)
67
- */
68
52
  return (...inputs: ClassValue[]) => {
69
- const processed = inputs.map((input) => {
70
- if (input !== null && typeof input === 'object' && !Array.isArray(input)) {
71
- return Object.entries(input)
72
- .map(([k, v]) => {
73
- // Soporte para booleanos nativos de clsx: { 'clase': true }
74
- if (v === true) return k;
75
-
76
- // Si la llave es un prefijo registrado (md, hover, ui), empezamos proceso
77
- if (registry[k] || k === 'base') return process(k, v);
78
-
79
- // Si no es prefijo (ej: variantes dinámicas), procesamos el interior como base
80
- return process('base', v);
81
- })
82
- .join(' ');
83
- }
84
- return input;
85
- });
86
-
87
- // Resolvemos con clsx y limpiamos conflictos con twMerge
53
+ // Procesamos uno a uno para capturar objetos de prefijos antes de que clsx los aplane
54
+ const processed = inputs.map((input) => process('', input));
88
55
  return twMerge(clsx(processed));
89
56
  };
90
57
  }
@@ -1,166 +1,73 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import { createCl } from '../index';
3
3
 
4
- describe('cl - Escala de Complejidad (Registry-Based)', () => {
5
- // 1. Setup con Prefijos y Plugins registrados
6
- const cl = createCl(
7
- { md: 'md', hover: 'hover', focus: 'focus' }, // Tailwind
8
- { ui: 'prefix', btn: 'button' } // Plugins
9
- );
4
+ describe('cl - Prefix Engine (Scope: Prefixes + clsx + twMerge)', () => {
5
+ // Setup con prefijos de Tailwind y un alias personalizado
6
+ const cl = createCl({ md: 'md', hover: 'hover', dark: 'dark' }, { ui: 'prefix' });
10
7
 
11
- it('Nivel 1: Uso básico (Strings y Arrays)', () => {
12
- expect(cl('p-4', ['m-2', 'flex'])).toBe('p-4 m-2 flex');
13
- });
14
-
15
- it('Nivel 2: Objetos Simples y Registro', () => {
16
- // 'md' está registrado, 'p-4' es el valor
17
- expect(cl({ md: 'p-4' })).toBe('md:p-4');
18
- // 'ui' se mapea a 'prefix'
19
- expect(cl({ ui: 'p-4' })).toBe('prefix:p-4');
20
- });
21
-
22
- it('Nivel 3: Transparencia Automática (Sintaxis Hermosa)', () => {
23
- // 'custom' NO está registrado -> Invisible
24
- // 'inner' NO está registrado -> Invisible
8
+ it('Nivel 1: Prefijos Básicos y Mapping', () => {
25
9
  const result = cl({
26
- custom: {
27
- inner: 'text-center'
28
- }
10
+ md: 'p-4 m-2',
11
+ ui: 'bg-red-500'
29
12
  });
30
- expect(result).toBe('text-center');
13
+ expect(result).toBe('md:p-4 md:m-2 prefix:bg-red-500');
31
14
  });
32
15
 
33
- it('Nivel 4: Nesting Híbrido (Registrado + Transparente)', () => {
16
+ it('Nivel 2: Soporte Multilínea (Arrays)', () => {
34
17
  const result = cl({
35
- md: {
36
- // Registrado
37
- card: {
38
- // Lógico (Transparente)
39
- hover: {
40
- // Registrado
41
- base: 'shadow-lg'
42
- }
43
- }
44
- }
18
+ md: ['p-4', 'flex items-center', 'text-white']
45
19
  });
46
- // Debe saltar 'card' y conectar md con hover
47
- expect(result).toBe('md:hover:shadow-lg');
48
- });
49
-
50
- it('Nivel 5: El "Inception" (Lógica anidada, condicionales y plugins)', () => {
51
- const isEnabled = true;
52
- const variant = 'primary';
53
- const theme = 'dark';
54
-
55
- const result = cl({
56
- md: {
57
- [isEnabled ? 'active' : 'idle']: {
58
- ui: {
59
- [`[${variant}]`]: {
60
- base: 'bg-blue-500',
61
- // Seleccionamos el valor ANTES de que el motor lo aplane
62
- theme: theme === 'dark' ? 'text-white' : 'text-black'
63
- }
64
- }
65
- }
66
- }
67
- });
68
-
69
- expect(result).toContain('md:prefix:bg-blue-500');
70
- expect(result).toContain('md:prefix:text-white'); // Ahora sí pasará
71
- expect(result).not.toContain('md:prefix:text-black');
72
- });
73
-
74
- it('Nivel 6: Resolución de Conflictos Final (twMerge)', () => {
75
- // En este nivel probamos que tras toda la recursión, twMerge limpie el resultado
76
- const result = cl({ md: 'p-4' }, { md: { logic: 'p-8' } });
77
- // md:p-8 debe ganar a md:p-4
78
- expect(result).toBe('md:p-8');
20
+ // El prefijo se debe aplicar a cada elemento del array
21
+ expect(result).toBe('md:p-4 md:flex md:items-center md:text-white');
79
22
  });
80
23
 
81
- it('Nivel 7: Selectores Dinámicos (Sintaxis de Componente)', () => {
82
- const variant = 'primary';
83
- const onHover = 'scale';
24
+ it('Nivel 3: Lógica Estándar (clsx style)', () => {
25
+ const isEnabled = true;
26
+ const isDark = false;
84
27
 
85
28
  const result = cl({
86
- // 'variants' no está registrado -> Desaparece
87
- variants: {
88
- primary: 'bg-action text-white',
89
- secondary: 'bg-neutral-50 text-black'
90
- }[variant],
91
-
92
- // 'effects' no está registrado -> Desaparece
93
- effects: {
94
- scale: 'elevate-hover',
95
- dim: 'hover:opacity-80'
96
- }[onHover]
29
+ // Llaves que NO están en el registro se tratan como clases condicionales
30
+ 'opacity-100': isEnabled,
31
+ 'opacity-0': isDark,
32
+ // Mezcla con prefijos
33
+ hover: 'bg-blue-500'
97
34
  });
98
35
 
99
- // El resultado no debe contener ni 'variants:' ni 'effects:'
100
- expect(result).toBe('bg-action text-white elevate-hover');
101
- expect(result).not.toContain('variants:');
102
- expect(result).not.toContain('effects:');
36
+ expect(result).toContain('opacity-100');
37
+ expect(result).toContain('hover:bg-blue-500');
38
+ expect(result).not.toContain('opacity-0');
103
39
  });
104
40
 
105
- it('Nivel 8: Combinación de Selectores con Prefijos Registrados', () => {
106
- const variant = 'secondary';
107
- const isDark = true;
108
-
41
+ it('Nivel 4: Anidación de Prefijos', () => {
109
42
  const result = cl({
110
43
  md: {
111
- // Selector dinámico dentro de un prefijo registrado
112
- container: {
113
- [variant]: {
114
- base: 'p-4',
115
- // Prefijo registrado dentro de un selector dinámico
116
- hover: 'shadow-xl'
117
- }
118
- }[variant]
44
+ hover: {
45
+ dark: 'bg-black text-white'
46
+ }
119
47
  }
120
48
  });
121
-
122
- // 'md' y 'hover' se mantienen, 'container' y 'secondary' desaparecen
123
- expect(result).toBe('md:p-4 md:hover:shadow-xl');
49
+ expect(result).toBe('md:hover:dark:bg-black md:hover:dark:text-white');
124
50
  });
125
51
 
126
- it('Nivel 9: El Caso del Botón (Reproducción de Bug)', () => {
127
- const variant = 'secondary';
128
- const onHover = 'scale';
129
-
130
- const result = cl(
131
- // 1. Clases base (Strings)
132
- 'py-2 px-4 rounded-lg flex clickable',
133
- // 2. Objeto de configuración con lógica dinámica
134
- {
135
- variants: {
136
- primary: 'bg-action text-white',
137
- secondary: 'bg-neutral-50 text-text-muted border-2',
138
- danger: 'bg-red-400 text-white'
139
- }[variant],
140
-
141
- effects: {
142
- scale: 'elevate-hover',
143
- dim: 'hover:opacity-80 transition-opacity',
144
- color: {
145
- primary: 'hover:bg-action-hover',
146
- secondary: 'hover:bg-neutral-200'
147
- }[variant]
148
- }[onHover]
149
- }
150
- );
151
-
152
- // Verificación de limpieza
153
- expect(result).not.toContain('variants:');
154
- expect(result).not.toContain('effects:');
52
+ it('Nivel 5: Resolución de Conflictos (twMerge)', () => {
53
+ // twMerge debe hacer que la última clase gane si hay colisión
54
+ const result = cl('p-2', { md: 'p-4' }, { md: 'p-8' });
55
+ // md:p-8 debe ganar a md:p-4, y p-2 se mantiene por ser base
56
+ expect(result).toBe('p-2 md:p-8');
57
+ });
155
58
 
156
- // Verificación de contenido
157
- expect(result).toContain('bg-neutral-50');
158
- expect(result).toContain('elevate-hover');
159
- expect(result).toContain('clickable'); // Debe mantener las clases base
59
+ it('Nivel 6: Manejo de Strings Complejos (Comas y saltos de línea)', () => {
60
+ const result = cl({
61
+ md: 'text-xl, leading-tight, \n font-bold'
62
+ });
63
+ expect(result).toBe('md:text-xl md:leading-tight md:font-bold');
64
+ });
160
65
 
161
- // El resultado final debe ser un string limpio de Tailwind
162
- expect(result).toBe(
163
- 'py-2 px-4 rounded-lg flex clickable bg-neutral-50 text-text-muted border-2 elevate-hover'
164
- );
66
+ it('Nivel 7: Integración con Variables/Ternarios Externos', () => {
67
+ const variant = 'primary';
68
+ const result = cl('base-btn', variant === 'primary' ? 'bg-blue-500' : 'bg-gray-500', {
69
+ md: ['px-4', variant === 'primary' ? 'text-white' : 'text-black']
70
+ });
71
+ expect(result).toBe('base-btn bg-blue-500 md:px-4 md:text-white');
165
72
  });
166
73
  });