clases 1.1.13 → 1.1.14

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
@@ -8,48 +8,34 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
8
  var clsx__default = /*#__PURE__*/_interopDefault(clsx);
9
9
 
10
10
  // src/index.ts
11
- function createCl(...plugins) {
11
+ function createCl(plugins, options = {}) {
12
12
  const registry = Object.assign({}, ...plugins);
13
+ const { baseKey = "base", conditionKey = "if", prefix: globalPrefix = "" } = options;
13
14
  const process = (accumulatedPath, input) => {
14
- console.log(`[START] Path: "${accumulatedPath}" | Input:`, input);
15
- if (!input) {
16
- console.log(`[SKIP] Input is falsy`);
17
- return "";
18
- }
15
+ if (!input) return "";
19
16
  if (typeof input === "string") {
20
17
  const resolvedPrefix = accumulatedPath.split(":").map((part) => {
21
- if (part === "base" || part === "?") return null;
18
+ if (part === baseKey || part === conditionKey) return null;
22
19
  return registry[part] || part;
23
20
  }).filter(Boolean).join(":");
24
- const result = input.split(/[,\s\n]+/).filter(Boolean).map((cls) => resolvedPrefix ? `${resolvedPrefix}:${cls}` : cls).join(" ");
25
- console.log(`[STRING] Resolved: "${resolvedPrefix}" | Out: "${result}"`);
26
- return result;
21
+ return input.split(/[,\s\n]+/).filter(Boolean).map((cls) => {
22
+ const finalClass = globalPrefix ? `${globalPrefix}${cls}` : cls;
23
+ return resolvedPrefix ? `${resolvedPrefix}:${finalClass}` : finalClass;
24
+ }).join(" ");
27
25
  }
28
26
  if (Array.isArray(input)) {
29
- console.log(`[ARRAY] Processing ${input.length} elements...`);
30
27
  return input.map((i) => process(accumulatedPath, i)).filter(Boolean).join(" ");
31
28
  }
32
29
  if (typeof input === "object") {
33
- console.log(`[OBJECT] Keys:`, Object.keys(input));
34
30
  return Object.entries(input).map(([key, value]) => {
35
- const isTransparent = key === "base" || key === "?";
31
+ if (!value) return "";
32
+ const isTransparent = key === baseKey || key === conditionKey;
36
33
  const isRegistered = registry[key] !== void 0;
37
- console.log(
38
- ` -> Key: "${key}" | Value: ${value} | isPrefix: ${isRegistered} | isTransparent: ${isTransparent}`
39
- );
40
- if (!value) {
41
- console.log(` [SKIP KEY] "${key}" because value is falsy`);
42
- return "";
43
- }
44
34
  if (isTransparent || isRegistered) {
45
35
  const newPath = accumulatedPath ? `${accumulatedPath}:${key}` : key;
46
- console.log(` [DIVE] Moving to path: "${newPath}"`);
47
36
  return process(newPath, value);
48
37
  } else {
49
- console.log(
50
- ` [CLASS] Treating key "${key}" as class under path "${accumulatedPath}"`
51
- );
52
- return process(accumulatedPath, key);
38
+ return value ? process(accumulatedPath, key) : "";
53
39
  }
54
40
  }).filter(Boolean).join(" ");
55
41
  }
@@ -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\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 = (accumulatedPath: string, input: any): string => {\r\n console.log(`[START] Path: \"${accumulatedPath}\" | Input:`, input);\r\n\r\n if (!input) {\r\n console.log(`[SKIP] Input is falsy`);\r\n return '';\r\n }\r\n\r\n // 1. Caso String\r\n if (typeof input === 'string') {\r\n const resolvedPrefix = accumulatedPath\r\n .split(':')\r\n .map((part) => {\r\n if (part === 'base' || part === '?') return null;\r\n return registry[part] || part;\r\n })\r\n .filter(Boolean)\r\n .join(':');\r\n\r\n const result = input\r\n .split(/[,\\s\\n]+/)\r\n .filter(Boolean)\r\n .map((cls) => (resolvedPrefix ? `${resolvedPrefix}:${cls}` : cls))\r\n .join(' ');\r\n\r\n console.log(`[STRING] Resolved: \"${resolvedPrefix}\" | Out: \"${result}\"`);\r\n return result;\r\n }\r\n\r\n // 2. Caso Array\r\n if (Array.isArray(input)) {\r\n console.log(`[ARRAY] Processing ${input.length} elements...`);\r\n return input\r\n .map((i) => process(accumulatedPath, i))\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n // 3. Caso Objeto\r\n if (typeof input === 'object') {\r\n console.log(`[OBJECT] Keys:`, Object.keys(input));\r\n return Object.entries(input)\r\n .map(([key, value]) => {\r\n const isTransparent = key === 'base' || key === '?';\r\n const isRegistered = registry[key] !== undefined;\r\n\r\n console.log(\r\n ` -> Key: \"${key}\" | Value: ${value} | isPrefix: ${isRegistered} | isTransparent: ${isTransparent}`\r\n );\r\n\r\n if (!value) {\r\n console.log(` [SKIP KEY] \"${key}\" because value is falsy`);\r\n return '';\r\n }\r\n\r\n if (isTransparent || isRegistered) {\r\n const newPath = accumulatedPath ? `${accumulatedPath}:${key}` : key;\r\n console.log(` [DIVE] Moving to path: \"${newPath}\"`);\r\n return process(newPath, value);\r\n } else {\r\n console.log(\r\n ` [CLASS] Treating key \"${key}\" as class under path \"${accumulatedPath}\"`\r\n );\r\n return process(accumulatedPath, key);\r\n }\r\n })\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n return '';\r\n };\r\n\r\n return (...inputs: ClassValue[]) => {\r\n const processed = inputs.map((input) => process('', input));\r\n return twMerge(clsx(processed));\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["twMerge","clsx"],"mappings":";;;;;;;;;;AAUO,SAAS,QAAA,CAId,OAAA,EAAmB,OAAA,GAA2B,EAAC,EAAG;AAEhD,EAAA,MAAM,WAAmC,MAAA,CAAO,MAAA,CAAO,EAAC,EAAG,GAAG,OAAO,CAAA;AAGrE,EAAA,MAAM,EAAE,UAAU,MAAA,EAAa,YAAA,GAAe,MAAW,MAAA,EAAQ,YAAA,GAAe,IAAG,GAAI,OAAA;AAoBvF,EAAA,MAAM,OAAA,GAAU,CAAC,eAAA,EAAyB,KAAA,KAAuB;AAC7D,IAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAGnB,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,MAAA,MAAM,iBAAiB,eAAA,CAClB,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,IAAA,KAAS;AAEX,QAAA,IAAI,IAAA,KAAS,OAAA,IAAW,IAAA,KAAS,YAAA,EAAc,OAAO,IAAA;AAEtD,QAAA,OAAO,QAAA,CAAS,IAAI,CAAA,IAAK,IAAA;AAAA,MAC7B,CAAC,CAAA,CACA,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEb,MAAA,OAAO,KAAA,CACF,MAAM,UAAU,CAAA,CAChB,OAAO,OAAO,CAAA,CACd,GAAA,CAAI,CAAC,GAAA,KAAQ;AAEV,QAAA,MAAM,aAAa,YAAA,GAAe,CAAA,EAAG,YAAY,CAAA,EAAG,GAAG,CAAA,CAAA,GAAK,GAAA;AAE5D,QAAA,OAAO,cAAA,GAAiB,CAAA,EAAG,cAAc,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,GAAK,UAAA;AAAA,MAChE,CAAC,CAAA,CACA,IAAA,CAAK,GAAG,CAAA;AAAA,IACjB;AAGA,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACtB,MAAA,OAAO,KAAA,CACF,GAAA,CAAI,CAAC,CAAA,KAAM,OAAA,CAAQ,eAAA,EAAiB,CAAC,CAAC,CAAA,CACtC,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,GAAA,EAAK,KAAK,CAAA,KAAM;AACnB,QAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAEnB,QAAA,MAAM,aAAA,GAAgB,GAAA,KAAQ,OAAA,IAAW,GAAA,KAAQ,YAAA;AACjD,QAAA,MAAM,YAAA,GAAe,QAAA,CAAS,GAAG,CAAA,KAAM,MAAA;AAEvC,QAAA,IAAI,iBAAiB,YAAA,EAAc;AAE/B,UAAA,MAAM,UAAU,eAAA,GAAkB,CAAA,EAAG,eAAe,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,GAAA;AAChE,UAAA,OAAO,OAAA,CAAQ,SAAS,KAAK,CAAA;AAAA,QACjC,CAAA,MAAO;AAGH,UAAA,OAAO,KAAA,GAAQ,OAAA,CAAQ,eAAA,EAAiB,GAAG,CAAA,GAAI,EAAA;AAAA,QACnD;AAAA,MACJ,CAAC,CAAA,CACA,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAAA,IACjB;AAEA,IAAA,OAAO,EAAA;AAAA,EACX,CAAA;AAEA,EAAA,OAAO,IAAI,MAAA,KAAyB;AAChC,IAAA,MAAM,SAAA,GAAY,OAAO,GAAA,CAAI,CAAC,UAAU,OAAA,CAAQ,EAAA,EAAI,KAAK,CAAC,CAAA;AAE1D,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\n// Tipos para las opciones de configuración\r\nexport interface ClOptions<B extends string, C extends string> {\r\n baseKey?: B;\r\n conditionKey?: C;\r\n prefix?: string;\r\n}\r\n\r\nexport function createCl<\r\n TPlugins extends Record<string, string>[],\r\n B extends string = 'base',\r\n C extends string = '?'\r\n>(plugins: TPlugins, options: ClOptions<B, C> = {}) {\r\n // Unificamos los plugins en un solo registro\r\n const registry: Record<string, string> = Object.assign({}, ...plugins);\r\n\r\n // Extraemos opciones con valores por defecto\r\n const { baseKey = 'base' as B, conditionKey = 'if' as C, prefix: globalPrefix = '' } = options;\r\n\r\n /**\r\n * Aplica el prefijo global de configuración (ej: 'tw-') a una clase\r\n */\r\n const applyGlobalPrefix = (cls: string) => {\r\n if (!globalPrefix) return cls;\r\n // Evitamos prefijar si la clase ya tiene el prefijo o es vacía\r\n return cls\r\n .split(':')\r\n .map((part) => {\r\n // Solo prefijamos la clase final, no los modificadores (hover, md, etc)\r\n // pero como tailwind-merge y clsx se encargan de la limpieza,\r\n // aplicamos una lógica simple:\r\n return part;\r\n })\r\n .join(':');\r\n // Nota: El prefijo global de Tailwind suele aplicarse a la clase base: 'tw-bg-red'\r\n };\r\n\r\n const process = (accumulatedPath: string, input: any): string => {\r\n if (!input) return '';\r\n\r\n // 1. Caso String: Aquí es donde se resuelve el path acumulado\r\n if (typeof input === 'string') {\r\n const resolvedPrefix = accumulatedPath\r\n .split(':')\r\n .map((part) => {\r\n // Si la parte del path es una de las llaves especiales, no genera prefijo CSS\r\n if (part === baseKey || part === conditionKey) return null;\r\n // Retornamos el valor del registro (ej: 'hover') o la parte tal cual\r\n return registry[part] || part;\r\n })\r\n .filter(Boolean)\r\n .join(':');\r\n\r\n return input\r\n .split(/[,\\s\\n]+/)\r\n .filter(Boolean)\r\n .map((cls) => {\r\n // Aplicamos el prefijo global a la clase\r\n const finalClass = globalPrefix ? `${globalPrefix}${cls}` : cls;\r\n // Aplicamos el prefijo acumulado (hover, md, etc)\r\n return resolvedPrefix ? `${resolvedPrefix}:${finalClass}` : finalClass;\r\n })\r\n .join(' ');\r\n }\r\n\r\n // 2. Caso Array\r\n if (Array.isArray(input)) {\r\n return input\r\n .map((i) => process(accumulatedPath, i))\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n // 3. Caso Objeto\r\n if (typeof input === 'object') {\r\n return Object.entries(input)\r\n .map(([key, value]) => {\r\n if (!value) return '';\r\n\r\n const isTransparent = key === baseKey || key === conditionKey;\r\n const isRegistered = registry[key] !== undefined;\r\n\r\n if (isTransparent || isRegistered) {\r\n // Si es una llave especial o registrada, profundizamos en el path\r\n const newPath = accumulatedPath ? `${accumulatedPath}:${key}` : key;\r\n return process(newPath, value);\r\n } else {\r\n // Si la llave no está registrada, se trata como una clase bajo el path actual\r\n // (Aquí value actúa como condición booleana para la llave)\r\n return value ? process(accumulatedPath, key) : '';\r\n }\r\n })\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n return '';\r\n };\r\n\r\n return (...inputs: ClassValue[]) => {\r\n const processed = inputs.map((input) => process('', input));\r\n // twMerge se encarga de que 'bg-red-500 bg-blue-500' resulte en 'bg-blue-500'\r\n return twMerge(clsx(processed));\r\n };\r\n}\r\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { ClassValue } from 'clsx';
2
2
 
3
- declare function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins): (...inputs: ClassValue[]) => string;
3
+ interface ClOptions<B extends string, C extends string> {
4
+ baseKey?: B;
5
+ conditionKey?: C;
6
+ prefix?: string;
7
+ }
8
+ declare function createCl<TPlugins extends Record<string, string>[], B extends string = 'base', C extends string = '?'>(plugins: TPlugins, options?: ClOptions<B, C>): (...inputs: ClassValue[]) => string;
4
9
 
5
- export { createCl };
10
+ export { type ClOptions, createCl };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { ClassValue } from 'clsx';
2
2
 
3
- declare function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins): (...inputs: ClassValue[]) => string;
3
+ interface ClOptions<B extends string, C extends string> {
4
+ baseKey?: B;
5
+ conditionKey?: C;
6
+ prefix?: string;
7
+ }
8
+ declare function createCl<TPlugins extends Record<string, string>[], B extends string = 'base', C extends string = '?'>(plugins: TPlugins, options?: ClOptions<B, C>): (...inputs: ClassValue[]) => string;
4
9
 
5
- export { createCl };
10
+ export { type ClOptions, createCl };
package/dist/index.js CHANGED
@@ -2,48 +2,34 @@ import { twMerge } from 'tailwind-merge';
2
2
  import clsx from 'clsx';
3
3
 
4
4
  // src/index.ts
5
- function createCl(...plugins) {
5
+ function createCl(plugins, options = {}) {
6
6
  const registry = Object.assign({}, ...plugins);
7
+ const { baseKey = "base", conditionKey = "if", prefix: globalPrefix = "" } = options;
7
8
  const process = (accumulatedPath, input) => {
8
- console.log(`[START] Path: "${accumulatedPath}" | Input:`, input);
9
- if (!input) {
10
- console.log(`[SKIP] Input is falsy`);
11
- return "";
12
- }
9
+ if (!input) return "";
13
10
  if (typeof input === "string") {
14
11
  const resolvedPrefix = accumulatedPath.split(":").map((part) => {
15
- if (part === "base" || part === "?") return null;
12
+ if (part === baseKey || part === conditionKey) return null;
16
13
  return registry[part] || part;
17
14
  }).filter(Boolean).join(":");
18
- const result = input.split(/[,\s\n]+/).filter(Boolean).map((cls) => resolvedPrefix ? `${resolvedPrefix}:${cls}` : cls).join(" ");
19
- console.log(`[STRING] Resolved: "${resolvedPrefix}" | Out: "${result}"`);
20
- return result;
15
+ return input.split(/[,\s\n]+/).filter(Boolean).map((cls) => {
16
+ const finalClass = globalPrefix ? `${globalPrefix}${cls}` : cls;
17
+ return resolvedPrefix ? `${resolvedPrefix}:${finalClass}` : finalClass;
18
+ }).join(" ");
21
19
  }
22
20
  if (Array.isArray(input)) {
23
- console.log(`[ARRAY] Processing ${input.length} elements...`);
24
21
  return input.map((i) => process(accumulatedPath, i)).filter(Boolean).join(" ");
25
22
  }
26
23
  if (typeof input === "object") {
27
- console.log(`[OBJECT] Keys:`, Object.keys(input));
28
24
  return Object.entries(input).map(([key, value]) => {
29
- const isTransparent = key === "base" || key === "?";
25
+ if (!value) return "";
26
+ const isTransparent = key === baseKey || key === conditionKey;
30
27
  const isRegistered = registry[key] !== void 0;
31
- console.log(
32
- ` -> Key: "${key}" | Value: ${value} | isPrefix: ${isRegistered} | isTransparent: ${isTransparent}`
33
- );
34
- if (!value) {
35
- console.log(` [SKIP KEY] "${key}" because value is falsy`);
36
- return "";
37
- }
38
28
  if (isTransparent || isRegistered) {
39
29
  const newPath = accumulatedPath ? `${accumulatedPath}:${key}` : key;
40
- console.log(` [DIVE] Moving to path: "${newPath}"`);
41
30
  return process(newPath, value);
42
31
  } else {
43
- console.log(
44
- ` [CLASS] Treating key "${key}" as class under path "${accumulatedPath}"`
45
- );
46
- return process(accumulatedPath, key);
32
+ return value ? process(accumulatedPath, key) : "";
47
33
  }
48
34
  }).filter(Boolean).join(" ");
49
35
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","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 = (accumulatedPath: string, input: any): string => {\r\n console.log(`[START] Path: \"${accumulatedPath}\" | Input:`, input);\r\n\r\n if (!input) {\r\n console.log(`[SKIP] Input is falsy`);\r\n return '';\r\n }\r\n\r\n // 1. Caso String\r\n if (typeof input === 'string') {\r\n const resolvedPrefix = accumulatedPath\r\n .split(':')\r\n .map((part) => {\r\n if (part === 'base' || part === '?') return null;\r\n return registry[part] || part;\r\n })\r\n .filter(Boolean)\r\n .join(':');\r\n\r\n const result = input\r\n .split(/[,\\s\\n]+/)\r\n .filter(Boolean)\r\n .map((cls) => (resolvedPrefix ? `${resolvedPrefix}:${cls}` : cls))\r\n .join(' ');\r\n\r\n console.log(`[STRING] Resolved: \"${resolvedPrefix}\" | Out: \"${result}\"`);\r\n return result;\r\n }\r\n\r\n // 2. Caso Array\r\n if (Array.isArray(input)) {\r\n console.log(`[ARRAY] Processing ${input.length} elements...`);\r\n return input\r\n .map((i) => process(accumulatedPath, i))\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n // 3. Caso Objeto\r\n if (typeof input === 'object') {\r\n console.log(`[OBJECT] Keys:`, Object.keys(input));\r\n return Object.entries(input)\r\n .map(([key, value]) => {\r\n const isTransparent = key === 'base' || key === '?';\r\n const isRegistered = registry[key] !== undefined;\r\n\r\n console.log(\r\n ` -> Key: \"${key}\" | Value: ${value} | isPrefix: ${isRegistered} | isTransparent: ${isTransparent}`\r\n );\r\n\r\n if (!value) {\r\n console.log(` [SKIP KEY] \"${key}\" because value is falsy`);\r\n return '';\r\n }\r\n\r\n if (isTransparent || isRegistered) {\r\n const newPath = accumulatedPath ? `${accumulatedPath}:${key}` : key;\r\n console.log(` [DIVE] Moving to path: \"${newPath}\"`);\r\n return process(newPath, value);\r\n } else {\r\n console.log(\r\n ` [CLASS] Treating key \"${key}\" as class under path \"${accumulatedPath}\"`\r\n );\r\n return process(accumulatedPath, key);\r\n }\r\n })\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n return '';\r\n };\r\n\r\n return (...inputs: ClassValue[]) => {\r\n const processed = inputs.map((input) => process('', input));\r\n return twMerge(clsx(processed));\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;AAUO,SAAS,QAAA,CAId,OAAA,EAAmB,OAAA,GAA2B,EAAC,EAAG;AAEhD,EAAA,MAAM,WAAmC,MAAA,CAAO,MAAA,CAAO,EAAC,EAAG,GAAG,OAAO,CAAA;AAGrE,EAAA,MAAM,EAAE,UAAU,MAAA,EAAa,YAAA,GAAe,MAAW,MAAA,EAAQ,YAAA,GAAe,IAAG,GAAI,OAAA;AAoBvF,EAAA,MAAM,OAAA,GAAU,CAAC,eAAA,EAAyB,KAAA,KAAuB;AAC7D,IAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAGnB,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC3B,MAAA,MAAM,iBAAiB,eAAA,CAClB,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,IAAA,KAAS;AAEX,QAAA,IAAI,IAAA,KAAS,OAAA,IAAW,IAAA,KAAS,YAAA,EAAc,OAAO,IAAA;AAEtD,QAAA,OAAO,QAAA,CAAS,IAAI,CAAA,IAAK,IAAA;AAAA,MAC7B,CAAC,CAAA,CACA,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEb,MAAA,OAAO,KAAA,CACF,MAAM,UAAU,CAAA,CAChB,OAAO,OAAO,CAAA,CACd,GAAA,CAAI,CAAC,GAAA,KAAQ;AAEV,QAAA,MAAM,aAAa,YAAA,GAAe,CAAA,EAAG,YAAY,CAAA,EAAG,GAAG,CAAA,CAAA,GAAK,GAAA;AAE5D,QAAA,OAAO,cAAA,GAAiB,CAAA,EAAG,cAAc,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,GAAK,UAAA;AAAA,MAChE,CAAC,CAAA,CACA,IAAA,CAAK,GAAG,CAAA;AAAA,IACjB;AAGA,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACtB,MAAA,OAAO,KAAA,CACF,GAAA,CAAI,CAAC,CAAA,KAAM,OAAA,CAAQ,eAAA,EAAiB,CAAC,CAAC,CAAA,CACtC,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,GAAA,EAAK,KAAK,CAAA,KAAM;AACnB,QAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAEnB,QAAA,MAAM,aAAA,GAAgB,GAAA,KAAQ,OAAA,IAAW,GAAA,KAAQ,YAAA;AACjD,QAAA,MAAM,YAAA,GAAe,QAAA,CAAS,GAAG,CAAA,KAAM,MAAA;AAEvC,QAAA,IAAI,iBAAiB,YAAA,EAAc;AAE/B,UAAA,MAAM,UAAU,eAAA,GAAkB,CAAA,EAAG,eAAe,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,GAAA;AAChE,UAAA,OAAO,OAAA,CAAQ,SAAS,KAAK,CAAA;AAAA,QACjC,CAAA,MAAO;AAGH,UAAA,OAAO,KAAA,GAAQ,OAAA,CAAQ,eAAA,EAAiB,GAAG,CAAA,GAAI,EAAA;AAAA,QACnD;AAAA,MACJ,CAAC,CAAA,CACA,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAAA,IACjB;AAEA,IAAA,OAAO,EAAA;AAAA,EACX,CAAA;AAEA,EAAA,OAAO,IAAI,MAAA,KAAyB;AAChC,IAAA,MAAM,SAAA,GAAY,OAAO,GAAA,CAAI,CAAC,UAAU,OAAA,CAAQ,EAAA,EAAI,KAAK,CAAC,CAAA;AAE1D,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// Tipos para las opciones de configuración\r\nexport interface ClOptions<B extends string, C extends string> {\r\n baseKey?: B;\r\n conditionKey?: C;\r\n prefix?: string;\r\n}\r\n\r\nexport function createCl<\r\n TPlugins extends Record<string, string>[],\r\n B extends string = 'base',\r\n C extends string = '?'\r\n>(plugins: TPlugins, options: ClOptions<B, C> = {}) {\r\n // Unificamos los plugins en un solo registro\r\n const registry: Record<string, string> = Object.assign({}, ...plugins);\r\n\r\n // Extraemos opciones con valores por defecto\r\n const { baseKey = 'base' as B, conditionKey = 'if' as C, prefix: globalPrefix = '' } = options;\r\n\r\n /**\r\n * Aplica el prefijo global de configuración (ej: 'tw-') a una clase\r\n */\r\n const applyGlobalPrefix = (cls: string) => {\r\n if (!globalPrefix) return cls;\r\n // Evitamos prefijar si la clase ya tiene el prefijo o es vacía\r\n return cls\r\n .split(':')\r\n .map((part) => {\r\n // Solo prefijamos la clase final, no los modificadores (hover, md, etc)\r\n // pero como tailwind-merge y clsx se encargan de la limpieza,\r\n // aplicamos una lógica simple:\r\n return part;\r\n })\r\n .join(':');\r\n // Nota: El prefijo global de Tailwind suele aplicarse a la clase base: 'tw-bg-red'\r\n };\r\n\r\n const process = (accumulatedPath: string, input: any): string => {\r\n if (!input) return '';\r\n\r\n // 1. Caso String: Aquí es donde se resuelve el path acumulado\r\n if (typeof input === 'string') {\r\n const resolvedPrefix = accumulatedPath\r\n .split(':')\r\n .map((part) => {\r\n // Si la parte del path es una de las llaves especiales, no genera prefijo CSS\r\n if (part === baseKey || part === conditionKey) return null;\r\n // Retornamos el valor del registro (ej: 'hover') o la parte tal cual\r\n return registry[part] || part;\r\n })\r\n .filter(Boolean)\r\n .join(':');\r\n\r\n return input\r\n .split(/[,\\s\\n]+/)\r\n .filter(Boolean)\r\n .map((cls) => {\r\n // Aplicamos el prefijo global a la clase\r\n const finalClass = globalPrefix ? `${globalPrefix}${cls}` : cls;\r\n // Aplicamos el prefijo acumulado (hover, md, etc)\r\n return resolvedPrefix ? `${resolvedPrefix}:${finalClass}` : finalClass;\r\n })\r\n .join(' ');\r\n }\r\n\r\n // 2. Caso Array\r\n if (Array.isArray(input)) {\r\n return input\r\n .map((i) => process(accumulatedPath, i))\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n // 3. Caso Objeto\r\n if (typeof input === 'object') {\r\n return Object.entries(input)\r\n .map(([key, value]) => {\r\n if (!value) return '';\r\n\r\n const isTransparent = key === baseKey || key === conditionKey;\r\n const isRegistered = registry[key] !== undefined;\r\n\r\n if (isTransparent || isRegistered) {\r\n // Si es una llave especial o registrada, profundizamos en el path\r\n const newPath = accumulatedPath ? `${accumulatedPath}:${key}` : key;\r\n return process(newPath, value);\r\n } else {\r\n // Si la llave no está registrada, se trata como una clase bajo el path actual\r\n // (Aquí value actúa como condición booleana para la llave)\r\n return value ? process(accumulatedPath, key) : '';\r\n }\r\n })\r\n .filter(Boolean)\r\n .join(' ');\r\n }\r\n\r\n return '';\r\n };\r\n\r\n return (...inputs: ClassValue[]) => {\r\n const processed = inputs.map((input) => process('', input));\r\n // twMerge se encarga de que 'bg-red-500 bg-blue-500' resulte en 'bg-blue-500'\r\n return twMerge(clsx(processed));\r\n };\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "clases",
3
- "version": "1.1.13",
3
+ "version": "1.1.14",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
+ "bin": {
8
+ "clases-init": "./scripts/init.js"
9
+ },
7
10
  "exports": {
8
11
  ".": {
9
12
  "types": "./dist/index.d.ts",
package/src/index.ts CHANGED
@@ -1,41 +1,72 @@
1
1
  import { twMerge } from 'tailwind-merge';
2
2
  import clsx, { type ClassValue } from 'clsx';
3
3
 
4
- export function createCl<TPlugins extends Record<string, string>[]>(...plugins: TPlugins) {
4
+ // Tipos para las opciones de configuración
5
+ export interface ClOptions<B extends string, C extends string> {
6
+ baseKey?: B;
7
+ conditionKey?: C;
8
+ prefix?: string;
9
+ }
10
+
11
+ export function createCl<
12
+ TPlugins extends Record<string, string>[],
13
+ B extends string = 'base',
14
+ C extends string = '?'
15
+ >(plugins: TPlugins, options: ClOptions<B, C> = {}) {
16
+ // Unificamos los plugins en un solo registro
5
17
  const registry: Record<string, string> = Object.assign({}, ...plugins);
6
18
 
7
- const process = (accumulatedPath: string, input: any): string => {
8
- console.log(`[START] Path: "${accumulatedPath}" | Input:`, input);
19
+ // Extraemos opciones con valores por defecto
20
+ const { baseKey = 'base' as B, conditionKey = 'if' as C, prefix: globalPrefix = '' } = options;
9
21
 
10
- if (!input) {
11
- console.log(`[SKIP] Input is falsy`);
12
- return '';
13
- }
22
+ /**
23
+ * Aplica el prefijo global de configuración (ej: 'tw-') a una clase
24
+ */
25
+ const applyGlobalPrefix = (cls: string) => {
26
+ if (!globalPrefix) return cls;
27
+ // Evitamos prefijar si la clase ya tiene el prefijo o es vacía
28
+ return cls
29
+ .split(':')
30
+ .map((part) => {
31
+ // Solo prefijamos la clase final, no los modificadores (hover, md, etc)
32
+ // pero como tailwind-merge y clsx se encargan de la limpieza,
33
+ // aplicamos una lógica simple:
34
+ return part;
35
+ })
36
+ .join(':');
37
+ // Nota: El prefijo global de Tailwind suele aplicarse a la clase base: 'tw-bg-red'
38
+ };
39
+
40
+ const process = (accumulatedPath: string, input: any): string => {
41
+ if (!input) return '';
14
42
 
15
- // 1. Caso String
43
+ // 1. Caso String: Aquí es donde se resuelve el path acumulado
16
44
  if (typeof input === 'string') {
17
45
  const resolvedPrefix = accumulatedPath
18
46
  .split(':')
19
47
  .map((part) => {
20
- if (part === 'base' || part === '?') return null;
48
+ // Si la parte del path es una de las llaves especiales, no genera prefijo CSS
49
+ if (part === baseKey || part === conditionKey) return null;
50
+ // Retornamos el valor del registro (ej: 'hover') o la parte tal cual
21
51
  return registry[part] || part;
22
52
  })
23
53
  .filter(Boolean)
24
54
  .join(':');
25
55
 
26
- const result = input
56
+ return input
27
57
  .split(/[,\s\n]+/)
28
58
  .filter(Boolean)
29
- .map((cls) => (resolvedPrefix ? `${resolvedPrefix}:${cls}` : cls))
59
+ .map((cls) => {
60
+ // Aplicamos el prefijo global a la clase
61
+ const finalClass = globalPrefix ? `${globalPrefix}${cls}` : cls;
62
+ // Aplicamos el prefijo acumulado (hover, md, etc)
63
+ return resolvedPrefix ? `${resolvedPrefix}:${finalClass}` : finalClass;
64
+ })
30
65
  .join(' ');
31
-
32
- console.log(`[STRING] Resolved: "${resolvedPrefix}" | Out: "${result}"`);
33
- return result;
34
66
  }
35
67
 
36
68
  // 2. Caso Array
37
69
  if (Array.isArray(input)) {
38
- console.log(`[ARRAY] Processing ${input.length} elements...`);
39
70
  return input
40
71
  .map((i) => process(accumulatedPath, i))
41
72
  .filter(Boolean)
@@ -44,30 +75,21 @@ export function createCl<TPlugins extends Record<string, string>[]>(...plugins:
44
75
 
45
76
  // 3. Caso Objeto
46
77
  if (typeof input === 'object') {
47
- console.log(`[OBJECT] Keys:`, Object.keys(input));
48
78
  return Object.entries(input)
49
79
  .map(([key, value]) => {
50
- const isTransparent = key === 'base' || key === '?';
51
- const isRegistered = registry[key] !== undefined;
80
+ if (!value) return '';
52
81
 
53
- console.log(
54
- ` -> Key: "${key}" | Value: ${value} | isPrefix: ${isRegistered} | isTransparent: ${isTransparent}`
55
- );
56
-
57
- if (!value) {
58
- console.log(` [SKIP KEY] "${key}" because value is falsy`);
59
- return '';
60
- }
82
+ const isTransparent = key === baseKey || key === conditionKey;
83
+ const isRegistered = registry[key] !== undefined;
61
84
 
62
85
  if (isTransparent || isRegistered) {
86
+ // Si es una llave especial o registrada, profundizamos en el path
63
87
  const newPath = accumulatedPath ? `${accumulatedPath}:${key}` : key;
64
- console.log(` [DIVE] Moving to path: "${newPath}"`);
65
88
  return process(newPath, value);
66
89
  } else {
67
- console.log(
68
- ` [CLASS] Treating key "${key}" as class under path "${accumulatedPath}"`
69
- );
70
- return process(accumulatedPath, key);
90
+ // Si la llave no está registrada, se trata como una clase bajo el path actual
91
+ // (Aquí value actúa como condición booleana para la llave)
92
+ return value ? process(accumulatedPath, key) : '';
71
93
  }
72
94
  })
73
95
  .filter(Boolean)
@@ -79,6 +101,7 @@ export function createCl<TPlugins extends Record<string, string>[]>(...plugins:
79
101
 
80
102
  return (...inputs: ClassValue[]) => {
81
103
  const processed = inputs.map((input) => process('', input));
104
+ // twMerge se encarga de que 'bg-red-500 bg-blue-500' resulte en 'bg-blue-500'
82
105
  return twMerge(clsx(processed));
83
106
  };
84
107
  }
@@ -1,28 +1,34 @@
1
+ #!/usr/bin/env node
1
2
  const fs = require('fs');
2
3
  const path = require('path');
3
4
 
4
- // Intentamos encontrar el root del proyecto del usuario
5
- const projectRoot = process.env.INIT_CWD || path.resolve('../../');
6
- // Buscamos si existe la carpeta 'src' para ponerlo ahí (mejor para Tailwind/Vite)
5
+ // Intentamos INIT_CWD (npm/pnpm), si no, el directorio actual
6
+ const projectRoot = process.env.INIT_CWD || process.cwd();
7
7
  const hasSrc = fs.existsSync(path.join(projectRoot, 'src'));
8
8
  const targetDir = hasSrc ? path.join(projectRoot, 'src') : projectRoot;
9
9
  const configPath = path.join(targetDir, 'clases.config.ts');
10
10
 
11
11
  const template = `import { createCl } from 'clases';
12
12
 
13
- // Instancia base agnóstica
14
13
  export const cl = createCl({});
15
14
  `;
16
15
 
17
- try {
18
- // Solo lo creamos si no existe para no borrar trabajo del usuario
19
- if (!fs.existsSync(configPath)) {
16
+ function init() {
17
+ if (fs.existsSync(configPath)) {
18
+ // Si el usuario lo corre manualmente con npx, avisamos.
19
+ // Si es postinstall, mejor callar.
20
+ if (!process.env.INIT_CWD) {
21
+ console.log('⚠️ El archivo clases.config.ts ya existe.');
22
+ }
23
+ return;
24
+ }
25
+
26
+ try {
20
27
  fs.writeFileSync(configPath, template, 'utf8');
21
- console.log(
22
- '\x1b[36m%s\x1b[0m',
23
- ' [clases] Configuración base creada en ' + (hasSrc ? 'src/' : './')
24
- );
28
+ console.log('\x1b[32m%s\x1b[0m', '✅ clases.config.ts generado con éxito.');
29
+ } catch (e) {
30
+ console.error(' Error al crear la configuración:', e.message);
25
31
  }
26
- } catch (err) {
27
- // Fallo silencioso para no romper la instalación si hay problemas de permisos
28
32
  }
33
+
34
+ init();
@@ -1,98 +1,110 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { createCl } from '../index';
2
+ import { createCl } from '../index'; // Ajusta la ruta a tu archivo
3
3
 
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' });
4
+ describe('createCl - Motor de Clases', () => {
5
+ // Configuración de prueba simulando Tailwind
6
+ const tailwindRegistry = {
7
+ hover: 'hover',
8
+ md: 'md',
9
+ dark: 'dark'
10
+ };
7
11
 
8
- it('Nivel 1: Prefijos Básicos y Mapping', () => {
12
+ it('debe manejar clases base simples', () => {
13
+ const cl = createCl([tailwindRegistry]);
14
+ const result = cl({ base: 'flex items-center' });
15
+ expect(result).toBe('flex items-center');
16
+ });
17
+
18
+ it('debe aplicar prefijos del registro (Anidamiento)', () => {
19
+ const cl = createCl([tailwindRegistry]);
9
20
  const result = cl({
10
- md: 'p-4 m-2',
11
- ui: 'bg-red-500'
21
+ base: 'block',
22
+ hover: 'bg-red-500',
23
+ md: {
24
+ base: 'p-4',
25
+ hover: 'bg-blue-500'
26
+ }
12
27
  });
13
- expect(result).toBe('md:p-4 md:m-2 prefix:bg-red-500');
28
+ expect(result).toContain('block');
29
+ expect(result).toContain('hover:bg-red-500');
30
+ expect(result).toContain('md:p-4');
31
+ expect(result).toContain('md:hover:bg-blue-500');
14
32
  });
15
33
 
16
- it('Nivel 2: Soporte Multilínea (Arrays)', () => {
34
+ it('debe procesar condicionales con la llave "?"', () => {
35
+ const cl = createCl([tailwindRegistry]);
36
+ const isError = true;
37
+ const isLarge = false;
38
+
17
39
  const result = cl({
18
- md: ['p-4', 'flex items-center', 'text-white']
40
+ base: 'text-sm',
41
+ '?': {
42
+ 'text-red-500': isError,
43
+ 'p-8': isLarge
44
+ }
19
45
  });
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');
46
+ expect(result).toBe('text-sm text-red-500');
22
47
  });
23
48
 
24
- it('Nivel 3: Lógica Estándar (clsx style)', () => {
25
- const isEnabled = true;
26
- const isDark = false;
49
+ it('debe permitir sobreescribir baseKey y conditionKey', () => {
50
+ const cl = createCl([tailwindRegistry], {
51
+ baseKey: 'root',
52
+ conditionKey: 'when'
53
+ });
27
54
 
28
55
  const result = cl({
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'
56
+ root: 'container',
57
+ when: { hidden: true },
58
+ hover: { root: 'opacity-50' }
34
59
  });
35
60
 
36
- expect(result).toContain('opacity-100');
37
- expect(result).toContain('hover:bg-blue-500');
38
- expect(result).not.toContain('opacity-0');
61
+ expect(result).toBe('container hidden hover:opacity-50');
39
62
  });
40
63
 
41
- it('Nivel 4: Anidación de Prefijos', () => {
64
+ it('debe aplicar un prefijo global a todas las clases', () => {
65
+ const cl = createCl([tailwindRegistry], {
66
+ prefix: 'tw-'
67
+ });
68
+
42
69
  const result = cl({
43
- md: {
44
- hover: {
45
- dark: 'bg-black text-white'
46
- }
47
- }
70
+ base: 'flex',
71
+ hover: 'bg-black'
48
72
  });
49
- expect(result).toBe('md:hover:dark:bg-black md:hover:dark:text-white');
50
- });
51
73
 
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');
74
+ // Resultado esperado: "tw-flex hover:tw-bg-black"
75
+ expect(result).toBe('tw-flex hover:tw-bg-black');
57
76
  });
58
77
 
59
- it('Nivel 6: Manejo de Strings Complejos (Comas y saltos de línea)', () => {
78
+ it('debe resolver clases tratadas como llaves de objeto (shorthand)', () => {
79
+ const cl = createCl([tailwindRegistry]);
80
+ const isVisible = true;
81
+
60
82
  const result = cl({
61
- md: 'text-xl, leading-tight, \n font-bold'
83
+ 'bg-white': true,
84
+ 'text-black': isVisible,
85
+ hidden: false
62
86
  });
63
- expect(result).toBe('md:text-xl md:leading-tight md:font-bold');
87
+
88
+ expect(result).toBe('bg-white text-black');
64
89
  });
65
90
 
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');
91
+ it('debe integrar tailwind-merge correctamente', () => {
92
+ const cl = createCl([tailwindRegistry]);
93
+ // twMerge debería eliminar la clase redundante 'p-2'
94
+ const result = cl('p-2', 'p-4');
95
+ expect(result).toBe('p-4');
72
96
  });
73
97
 
74
- it('Nivel 8: Lógica Condicional Anidada dentro de Prefijos', () => {
75
- const isActive = true;
76
- const isError = false;
77
- // Forzamos el tipo para que TS permita comparar con 'light' en el test
78
- const theme = 'dark' as 'light' | 'dark';
98
+ it('debe manejar múltiples plugins/diccionarios', () => {
99
+ const pluginA = { ui: 'ui' };
100
+ const pluginB = { theme: 'theme' };
101
+ const cl = createCl([pluginA, pluginB]);
79
102
 
80
103
  const result = cl({
81
- md: {
82
- // Objeto de lógica pura dentro de un prefijo
83
- 'bg-green-500': isActive,
84
- 'bg-red-500': isError,
85
- // Combinación con otro prefijo anidado
86
- dark: {
87
- 'text-white': theme === 'dark',
88
- 'text-black': theme === 'light' // Ahora TS ya no se queja
89
- }
90
- }
104
+ ui: 'button',
105
+ theme: 'dark'
91
106
  });
92
107
 
93
- expect(result).toContain('md:bg-green-500');
94
- expect(result).toContain('md:dark:text-white');
95
- expect(result).not.toContain('bg-red-500');
96
- expect(result).not.toContain('text-black');
108
+ expect(result).toBe('ui:button theme:dark');
97
109
  });
98
110
  });