pdm-ui-kit 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/aspect-ratio/aspect-ratio.component.d.ts +1 -1
  2. package/aspect-ratio/aspect-ratio.module.d.ts +5 -2
  3. package/badge/badge.component.d.ts +1 -1
  4. package/badge/badge.module.d.ts +5 -2
  5. package/button/button-theme.constant.d.ts +2 -0
  6. package/button/button.component.d.ts +1 -4
  7. package/button/testing/button-harness.d.ts +23 -0
  8. package/checkbox/testing/checkbox-harness.d.ts +22 -0
  9. package/dialog/dialog.module.d.ts +2 -1
  10. package/dialog/testing/dialog-harness.d.ts +26 -0
  11. package/esm2020/alert/alert.component.mjs +3 -3
  12. package/esm2020/aspect-ratio/aspect-ratio.component.mjs +4 -3
  13. package/esm2020/aspect-ratio/aspect-ratio.module.mjs +9 -10
  14. package/esm2020/badge/badge.component.mjs +4 -3
  15. package/esm2020/badge/badge.module.mjs +9 -10
  16. package/esm2020/button/button-theme.constant.mjs +55 -0
  17. package/esm2020/button/button.component.mjs +5 -18
  18. package/esm2020/button/testing/button-harness.mjs +51 -0
  19. package/esm2020/checkbox/testing/checkbox-harness.mjs +54 -0
  20. package/esm2020/dialog/dialog.component.mjs +5 -4
  21. package/esm2020/dialog/dialog.module.mjs +5 -4
  22. package/esm2020/dialog/testing/dialog-harness.mjs +87 -0
  23. package/esm2020/empty/empty.component.mjs +1 -1
  24. package/esm2020/icon/icon.component.mjs +4 -3
  25. package/esm2020/icon/icon.module.mjs +9 -10
  26. package/esm2020/input/input.component.mjs +16 -4
  27. package/esm2020/input/testing/input-harness.mjs +68 -0
  28. package/esm2020/kbd/kbd.component.mjs +4 -3
  29. package/esm2020/kbd/kbd.module.mjs +9 -10
  30. package/esm2020/pagination/pagination.component.mjs +3 -3
  31. package/esm2020/pagination/testing/pagination-harness.mjs +76 -0
  32. package/esm2020/public-api.mjs +3 -1
  33. package/esm2020/select/testing/select-harness.mjs +75 -0
  34. package/esm2020/separator/separator.component.mjs +4 -3
  35. package/esm2020/separator/separator.module.mjs +9 -10
  36. package/esm2020/skeleton/skeleton.component.mjs +4 -3
  37. package/esm2020/skeleton/skeleton.module.mjs +9 -10
  38. package/esm2020/spinner/spinner.component.mjs +4 -3
  39. package/esm2020/spinner/spinner.module.mjs +9 -10
  40. package/esm2020/src/alert/alert.component.mjs +3 -3
  41. package/esm2020/src/aspect-ratio/aspect-ratio.component.mjs +4 -3
  42. package/esm2020/src/aspect-ratio/aspect-ratio.module.mjs +9 -10
  43. package/esm2020/src/badge/badge.component.mjs +4 -3
  44. package/esm2020/src/badge/badge.module.mjs +9 -10
  45. package/esm2020/src/button/button-theme.constant.mjs +55 -0
  46. package/esm2020/src/button/button.component.mjs +5 -18
  47. package/esm2020/src/dialog/dialog.component.mjs +5 -4
  48. package/esm2020/src/dialog/dialog.module.mjs +5 -4
  49. package/esm2020/src/empty/empty.component.mjs +1 -1
  50. package/esm2020/src/icon/icon.component.mjs +4 -3
  51. package/esm2020/src/icon/icon.module.mjs +9 -10
  52. package/esm2020/src/input/input.component.mjs +16 -4
  53. package/esm2020/src/kbd/kbd.component.mjs +4 -3
  54. package/esm2020/src/kbd/kbd.module.mjs +9 -10
  55. package/esm2020/src/pagination/pagination.component.mjs +3 -3
  56. package/esm2020/src/separator/separator.component.mjs +4 -3
  57. package/esm2020/src/separator/separator.module.mjs +9 -10
  58. package/esm2020/src/skeleton/skeleton.component.mjs +4 -3
  59. package/esm2020/src/skeleton/skeleton.module.mjs +9 -10
  60. package/esm2020/src/spinner/spinner.component.mjs +4 -3
  61. package/esm2020/src/spinner/spinner.module.mjs +9 -10
  62. package/esm2020/src/utils/public-api.mjs +2 -1
  63. package/esm2020/src/utils/validators.mjs +180 -0
  64. package/esm2020/testing.mjs +13 -0
  65. package/fesm2015/pdm-ui-kit-src-alert.mjs +2 -2
  66. package/fesm2015/pdm-ui-kit-src-alert.mjs.map +1 -1
  67. package/fesm2015/pdm-ui-kit-src-aspect-ratio.mjs +10 -10
  68. package/fesm2015/pdm-ui-kit-src-aspect-ratio.mjs.map +1 -1
  69. package/fesm2015/pdm-ui-kit-src-badge.mjs +10 -10
  70. package/fesm2015/pdm-ui-kit-src-badge.mjs.map +1 -1
  71. package/fesm2015/pdm-ui-kit-src-button.mjs +58 -17
  72. package/fesm2015/pdm-ui-kit-src-button.mjs.map +1 -1
  73. package/fesm2015/pdm-ui-kit-src-dialog.mjs +8 -6
  74. package/fesm2015/pdm-ui-kit-src-dialog.mjs.map +1 -1
  75. package/fesm2015/pdm-ui-kit-src-empty.mjs.map +1 -1
  76. package/fesm2015/pdm-ui-kit-src-icon.mjs +12 -12
  77. package/fesm2015/pdm-ui-kit-src-icon.mjs.map +1 -1
  78. package/fesm2015/pdm-ui-kit-src-input.mjs +15 -3
  79. package/fesm2015/pdm-ui-kit-src-input.mjs.map +1 -1
  80. package/fesm2015/pdm-ui-kit-src-kbd.mjs +10 -10
  81. package/fesm2015/pdm-ui-kit-src-kbd.mjs.map +1 -1
  82. package/fesm2015/pdm-ui-kit-src-pagination.mjs +2 -2
  83. package/fesm2015/pdm-ui-kit-src-pagination.mjs.map +1 -1
  84. package/fesm2015/pdm-ui-kit-src-separator.mjs +10 -10
  85. package/fesm2015/pdm-ui-kit-src-separator.mjs.map +1 -1
  86. package/fesm2015/pdm-ui-kit-src-skeleton.mjs +10 -10
  87. package/fesm2015/pdm-ui-kit-src-skeleton.mjs.map +1 -1
  88. package/fesm2015/pdm-ui-kit-src-spinner.mjs +10 -10
  89. package/fesm2015/pdm-ui-kit-src-spinner.mjs.map +1 -1
  90. package/fesm2015/pdm-ui-kit-src-utils.mjs +181 -1
  91. package/fesm2015/pdm-ui-kit-src-utils.mjs.map +1 -1
  92. package/fesm2015/pdm-ui-kit.mjs +814 -211
  93. package/fesm2015/pdm-ui-kit.mjs.map +1 -1
  94. package/fesm2020/pdm-ui-kit-src-alert.mjs +2 -2
  95. package/fesm2020/pdm-ui-kit-src-alert.mjs.map +1 -1
  96. package/fesm2020/pdm-ui-kit-src-aspect-ratio.mjs +10 -10
  97. package/fesm2020/pdm-ui-kit-src-aspect-ratio.mjs.map +1 -1
  98. package/fesm2020/pdm-ui-kit-src-badge.mjs +10 -10
  99. package/fesm2020/pdm-ui-kit-src-badge.mjs.map +1 -1
  100. package/fesm2020/pdm-ui-kit-src-button.mjs +58 -17
  101. package/fesm2020/pdm-ui-kit-src-button.mjs.map +1 -1
  102. package/fesm2020/pdm-ui-kit-src-dialog.mjs +8 -6
  103. package/fesm2020/pdm-ui-kit-src-dialog.mjs.map +1 -1
  104. package/fesm2020/pdm-ui-kit-src-empty.mjs.map +1 -1
  105. package/fesm2020/pdm-ui-kit-src-icon.mjs +12 -12
  106. package/fesm2020/pdm-ui-kit-src-icon.mjs.map +1 -1
  107. package/fesm2020/pdm-ui-kit-src-input.mjs +15 -3
  108. package/fesm2020/pdm-ui-kit-src-input.mjs.map +1 -1
  109. package/fesm2020/pdm-ui-kit-src-kbd.mjs +10 -10
  110. package/fesm2020/pdm-ui-kit-src-kbd.mjs.map +1 -1
  111. package/fesm2020/pdm-ui-kit-src-pagination.mjs +2 -2
  112. package/fesm2020/pdm-ui-kit-src-pagination.mjs.map +1 -1
  113. package/fesm2020/pdm-ui-kit-src-separator.mjs +10 -10
  114. package/fesm2020/pdm-ui-kit-src-separator.mjs.map +1 -1
  115. package/fesm2020/pdm-ui-kit-src-skeleton.mjs +10 -10
  116. package/fesm2020/pdm-ui-kit-src-skeleton.mjs.map +1 -1
  117. package/fesm2020/pdm-ui-kit-src-spinner.mjs +10 -10
  118. package/fesm2020/pdm-ui-kit-src-spinner.mjs.map +1 -1
  119. package/fesm2020/pdm-ui-kit-src-utils.mjs +181 -1
  120. package/fesm2020/pdm-ui-kit-src-utils.mjs.map +1 -1
  121. package/fesm2020/pdm-ui-kit.mjs +673 -211
  122. package/fesm2020/pdm-ui-kit.mjs.map +1 -1
  123. package/icon/icon.component.d.ts +1 -1
  124. package/icon/icon.module.d.ts +5 -2
  125. package/input/input.component.d.ts +4 -0
  126. package/input/testing/input-harness.d.ts +27 -0
  127. package/kbd/kbd.component.d.ts +1 -1
  128. package/kbd/kbd.module.d.ts +5 -2
  129. package/package.json +1 -1
  130. package/pagination/testing/pagination-harness.d.ts +21 -0
  131. package/public-api.d.ts +1 -0
  132. package/select/testing/select-harness.d.ts +25 -0
  133. package/separator/separator.component.d.ts +1 -1
  134. package/separator/separator.module.d.ts +5 -2
  135. package/skeleton/skeleton.component.d.ts +1 -1
  136. package/skeleton/skeleton.module.d.ts +5 -2
  137. package/spinner/spinner.component.d.ts +1 -1
  138. package/spinner/spinner.module.d.ts +5 -2
  139. package/src/aspect-ratio/aspect-ratio.component.d.ts +1 -1
  140. package/src/aspect-ratio/aspect-ratio.module.d.ts +5 -2
  141. package/src/badge/badge.component.d.ts +1 -1
  142. package/src/badge/badge.module.d.ts +5 -2
  143. package/src/button/button-theme.constant.d.ts +2 -0
  144. package/src/button/button.component.d.ts +1 -4
  145. package/src/dialog/dialog.module.d.ts +2 -1
  146. package/src/icon/icon.component.d.ts +1 -1
  147. package/src/icon/icon.module.d.ts +5 -2
  148. package/src/input/input.component.d.ts +4 -0
  149. package/src/kbd/kbd.component.d.ts +1 -1
  150. package/src/kbd/kbd.module.d.ts +5 -2
  151. package/src/separator/separator.component.d.ts +1 -1
  152. package/src/separator/separator.module.d.ts +5 -2
  153. package/src/skeleton/skeleton.component.d.ts +1 -1
  154. package/src/skeleton/skeleton.module.d.ts +5 -2
  155. package/src/spinner/spinner.component.d.ts +1 -1
  156. package/src/spinner/spinner.module.d.ts +5 -2
  157. package/src/utils/public-api.d.ts +1 -0
  158. package/src/utils/validators.d.ts +109 -0
  159. package/testing.d.ts +12 -0
@@ -231,9 +231,189 @@ function logZIndexStack(element) {
231
231
  console.table(stack);
232
232
  }
233
233
 
234
+ /**
235
+ * Form validation utilities for PDM UI Kit
236
+ *
237
+ * Pure validation functions and patterns that work with any form validation library.
238
+ * These functions validate values directly and return true/false, making them framework-agnostic.
239
+ */
240
+ /**
241
+ * Validate email format
242
+ *
243
+ * @example
244
+ * isValidEmail('user@example.com') // true
245
+ */
246
+ function isValidEmail(value) {
247
+ if (!value)
248
+ return false;
249
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
250
+ return emailRegex.test(value);
251
+ }
252
+ /**
253
+ * Validate URL format
254
+ *
255
+ * @example
256
+ * isValidUrl('https://example.com') // true
257
+ */
258
+ function isValidUrl(value) {
259
+ if (!value)
260
+ return false;
261
+ try {
262
+ new URL(value);
263
+ return true;
264
+ }
265
+ catch (_a) {
266
+ return false;
267
+ }
268
+ }
269
+ /**
270
+ * Validate minimum length
271
+ *
272
+ * @example
273
+ * hasMinLength('password', 8) // true if length >= 8
274
+ */
275
+ function hasMinLength(value, min) {
276
+ if (!value)
277
+ return false;
278
+ return String(value).length >= min;
279
+ }
280
+ /**
281
+ * Validate maximum length
282
+ *
283
+ * @example
284
+ * hasMaxLength('bio', 500) // true if length <= 500
285
+ */
286
+ function hasMaxLength(value, max) {
287
+ if (!value)
288
+ return true;
289
+ return String(value).length <= max;
290
+ }
291
+ /**
292
+ * Validate that value only contains numbers
293
+ *
294
+ * @example
295
+ * isNumeric('12345') // true
296
+ */
297
+ function isNumeric(value) {
298
+ if (!value)
299
+ return false;
300
+ return /^\d+$/.test(String(value));
301
+ }
302
+ /**
303
+ * Validate that two values match (e.g., password confirmation)
304
+ *
305
+ * @example
306
+ * valuesMatch(password, confirmPassword) // true if they match
307
+ */
308
+ function valuesMatch(value1, value2) {
309
+ if (!value1 || !value2)
310
+ return false;
311
+ return value1 === value2;
312
+ }
313
+ /**
314
+ * Validate minimum value
315
+ *
316
+ * @example
317
+ * isMinValue(age, 18) // true if age >= 18
318
+ */
319
+ function isMinValue(value, min) {
320
+ if (value === null || value === undefined)
321
+ return false;
322
+ return value >= min;
323
+ }
324
+ /**
325
+ * Validate maximum value
326
+ *
327
+ * @example
328
+ * isMaxValue(percentage, 100) // true if percentage <= 100
329
+ */
330
+ function isMaxValue(value, max) {
331
+ if (value === null || value === undefined)
332
+ return false;
333
+ return value <= max;
334
+ }
335
+ /**
336
+ * Validate phone number format (basic international format)
337
+ * Accepts: +1234567890, (123) 456-7890, 123-456-7890
338
+ *
339
+ * @example
340
+ * isValidPhone('+1234567890') // true
341
+ */
342
+ function isValidPhone(value) {
343
+ if (!value)
344
+ return false;
345
+ const phoneRegex = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/;
346
+ return phoneRegex.test(String(value).replace(/\s/g, ''));
347
+ }
348
+ /**
349
+ * Check if value contains at least one uppercase letter
350
+ *
351
+ * @example
352
+ * hasUppercase('Password') // true
353
+ */
354
+ function hasUppercase(value) {
355
+ if (!value)
356
+ return false;
357
+ return /[A-Z]/.test(value);
358
+ }
359
+ /**
360
+ * Check if value contains at least one lowercase letter
361
+ *
362
+ * @example
363
+ * hasLowercase('Password') // true
364
+ */
365
+ function hasLowercase(value) {
366
+ if (!value)
367
+ return false;
368
+ return /[a-z]/.test(value);
369
+ }
370
+ /**
371
+ * Check if value contains at least one number
372
+ *
373
+ * @example
374
+ * hasNumber('Pass123') // true
375
+ */
376
+ function hasNumber(value) {
377
+ if (!value)
378
+ return false;
379
+ return /\d/.test(value);
380
+ }
381
+ /**
382
+ * Check if value contains at least one special character
383
+ *
384
+ * @example
385
+ * hasSpecialChar('Pass@123') // true
386
+ */
387
+ function hasSpecialChar(value) {
388
+ if (!value)
389
+ return false;
390
+ return /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(value);
391
+ }
392
+ /**
393
+ * Get user-friendly error message for validation failures
394
+ *
395
+ * @example
396
+ * getErrorMessage('invalidEmail') // "Please enter a valid email address"
397
+ */
398
+ function getErrorMessage(errorCode, fieldName = 'Field') {
399
+ const messages = {
400
+ required: `${fieldName} is required`,
401
+ invalidEmail: 'Please enter a valid email address',
402
+ invalidUrl: 'Please enter a valid URL',
403
+ invalidPhone: 'Please enter a valid phone number',
404
+ notNumeric: `${fieldName} must contain only numbers`,
405
+ noUppercase: `${fieldName} must contain at least one uppercase letter`,
406
+ noLowercase: `${fieldName} must contain at least one lowercase letter`,
407
+ noNumber: `${fieldName} must contain at least one number`,
408
+ noSpecialChar: `${fieldName} must contain at least one special character`,
409
+ fieldsDoNotMatch: 'Fields do not match',
410
+ };
411
+ return messages[errorCode] || 'Invalid input';
412
+ }
413
+
234
414
  /**
235
415
  * Generated bundle index. Do not edit.
236
416
  */
237
417
 
238
- export { BREAKPOINTS, RESPONSIVE_CONTAINER, RESPONSIVE_DISPLAY, TABLE_RESPONSIVE, Z_INDEX, logZIndexStack, overflowResponsive, responsive, spacingResponsive, widthResponsive };
418
+ export { BREAKPOINTS, RESPONSIVE_CONTAINER, RESPONSIVE_DISPLAY, TABLE_RESPONSIVE, Z_INDEX, getErrorMessage, hasLowercase, hasMaxLength, hasMinLength, hasNumber, hasSpecialChar, hasUppercase, isMaxValue, isMinValue, isNumeric, isValidEmail, isValidPhone, isValidUrl, logZIndexStack, overflowResponsive, responsive, spacingResponsive, valuesMatch, widthResponsive };
239
419
  //# sourceMappingURL=pdm-ui-kit-src-utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pdm-ui-kit-src-utils.mjs","sources":["../../../src/utils/responsive.ts","../../../src/utils/z-index.ts","../../../src/utils/pdm-ui-kit-src-utils.ts"],"sourcesContent":["/**\n * Sistema de responsive utilities para PDM UI Kit\n * \n * Proporciona constantes, tipos y helpers para manejar responsive design\n * de forma consistente en todos los componentes.\n */\n\n/**\n * Breakpoints estándar de Tailwind CSS\n * Mobile-first approach: los estilos base son para mobile, los breakpoints son MIN-WIDTH\n */\nexport const BREAKPOINTS = {\n sm: '640px', // tablet portrait\n md: '768px', // tablet landscape\n lg: '1024px', // desktop\n xl: '1280px', // large desktop\n '2xl': '1536px' // extra large desktop\n} as const;\n\nexport type Breakpoint = keyof typeof BREAKPOINTS;\n\n/**\n * Estrategias de overflow para componentes que pueden desbordar\n */\nexport type OverflowStrategy = \n | 'auto' // Scroll automático cuando sea necesario\n | 'scroll' // Siempre scroll\n | 'hidden' // Ocultar contenido que desborda\n | 'visible'; // Permitir desbordamiento\n\n/**\n * Estrategias responsive para tablas\n */\nexport type TableResponsiveStrategy = \n | 'scroll' // Scroll horizontal en mobile (default, más simple)\n | 'stack' // Convertir filas en cards verticales en mobile\n | 'wrap' // Permitir que el contenido haga wrap\n | 'collapse'; // Colapsar columnas menos importantes en mobile\n\n/**\n * Helper para generar clases responsive de forma programática\n * \n * @example\n * responsive({ default: 'block', sm: 'flex', lg: 'grid' })\n * // Returns: 'block sm:flex lg:grid'\n */\nexport function responsive<T extends string>(\n config: Partial<Record<Breakpoint | 'default', T>>\n): string {\n const classes: string[] = [];\n \n if (config.default) {\n classes.push(config.default);\n }\n \n (['sm', 'md', 'lg', 'xl', '2xl'] as Breakpoint[]).forEach(bp => {\n if (config[bp]) {\n classes.push(`${bp}:${config[bp]}`);\n }\n });\n \n return classes.join(' ');\n}\n\n/**\n * Helper para overflow responsive\n * Maneja el caso común de scroll en mobile, auto en desktop\n * \n * @example\n * overflowResponsive('x', 'scroll', 'auto')\n * // Returns: 'overflow-x-scroll sm:overflow-x-auto'\n */\nexport function overflowResponsive(\n axis: 'x' | 'y' | 'both',\n mobile: OverflowStrategy,\n desktop?: OverflowStrategy\n): string {\n const axisClass = axis === 'both' ? 'overflow' : `overflow-${axis}`;\n const mobileClass = `${axisClass}-${mobile}`;\n \n if (!desktop || desktop === mobile) {\n return mobileClass;\n }\n \n return `${mobileClass} sm:${axisClass}-${desktop}`;\n}\n\n/**\n * Helper para spacing responsive\n * Útil para padding/margin que necesita ajustarse por breakpoint\n * \n * @example\n * spacingResponsive('px', { default: '4', sm: '6', lg: '8' })\n * // Returns: 'px-4 sm:px-6 lg:px-8'\n */\nexport function spacingResponsive(\n property: 'p' | 'px' | 'py' | 'pt' | 'pr' | 'pb' | 'pl' | 'm' | 'mx' | 'my' | 'mt' | 'mr' | 'mb' | 'ml',\n values: Partial<Record<Breakpoint | 'default', string>>\n): string {\n return responsive(\n Object.entries(values).reduce((acc, [key, value]) => {\n acc[key as Breakpoint | 'default'] = `${property}-${value}` as any;\n return acc;\n }, {} as Record<Breakpoint | 'default', string>)\n );\n}\n\n/**\n * Helper para width responsive\n * \n * @example\n * widthResponsive({ default: 'full', sm: 'auto', lg: '1/2' })\n * // Returns: 'w-full sm:w-auto lg:w-1/2'\n */\nexport function widthResponsive(\n values: Partial<Record<Breakpoint | 'default', string>>\n): string {\n return responsive(\n Object.entries(values).reduce((acc, [key, value]) => {\n acc[key as Breakpoint | 'default'] = `w-${value}` as any;\n return acc;\n }, {} as Record<Breakpoint | 'default', string>)\n );\n}\n\n/**\n * Clases comunes para containers responsive\n * Pensadas para wrappers que contienen contenido que puede desbordar\n */\nexport const RESPONSIVE_CONTAINER = {\n // Container con scroll horizontal en mobile, contenido visible en desktop\n tableWrapper: 'relative w-full overflow-x-auto sm:overflow-x-visible',\n \n // Container con padding negativo en mobile para scroll edge-to-edge\n tableWrapperFullBleed: 'relative w-full -mx-4 px-4 overflow-x-auto sm:mx-0 sm:px-0 sm:overflow-x-visible',\n \n // Container con max-width responsive\n contentWrapper: 'w-full mx-auto px-4 sm:px-6 lg:px-8 max-w-screen-2xl',\n \n // Container para modals/dialogs\n modalWrapper: 'w-full max-w-lg mx-auto px-4 sm:px-0',\n \n // Container para forms\n formWrapper: 'w-full max-w-md mx-auto space-y-4'\n} as const;\n\n/**\n * Clases comunes para display responsive\n */\nexport const RESPONSIVE_DISPLAY = {\n // Ocultar en mobile, mostrar en desktop\n hideOnMobile: 'hidden sm:block',\n \n // Mostrar solo en mobile\n showOnMobile: 'block sm:hidden',\n \n // Stack en mobile, flex en desktop\n stackToFlex: 'flex flex-col sm:flex-row',\n \n // Stack en mobile, grid en desktop\n stackToGrid: 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3'\n} as const;\n\n/**\n * Clases para table responsive strategies\n */\nexport const TABLE_RESPONSIVE = {\n // Scroll horizontal (default, más simple)\n scroll: {\n wrapper: 'relative w-full overflow-x-auto',\n table: 'w-full min-w-full',\n cell: 'whitespace-nowrap'\n },\n \n // Permitir wrap del contenido\n wrap: {\n wrapper: 'relative w-full overflow-x-auto',\n table: 'w-full',\n cell: 'whitespace-normal break-words'\n },\n \n // Stack en mobile (cada fila se convierte en card)\n // Requiere lógica adicional en el componente\n stack: {\n wrapper: 'relative w-full',\n table: 'w-full',\n row: 'block sm:table-row border-b sm:border-b-0',\n cell: 'block sm:table-cell py-2 sm:py-0 before:content-[attr(data-label)] before:font-medium before:inline-block before:w-32 sm:before:content-none'\n },\n \n // Collapse: ocultar columnas menos importantes en mobile\n // Se usa con clases de visibility en las columnas específicas\n collapse: {\n wrapper: 'relative w-full overflow-x-auto',\n table: 'w-full',\n cell: 'whitespace-nowrap',\n // Estas clases se aplican a columnas opcionales\n optionalColumn: 'hidden md:table-cell'\n }\n} as const;\n","/**\n * Z-Index Scale - Sistema centralizado de z-index\n *\n * JERARQUÍA (de menor a mayor):\n * 1. base (z-0) - Elementos normales del DOM\n * 2. dropdown (z-10) - Selects, combobox, date-pickers\n * 3. sticky (z-20) - Headers, navigation bars\n * 4. drawerBackdrop (z-30) - Backdrop de drawers\n * 5. drawer (z-40) - Sidebar drawer, sheets laterales\n * 6. modalBackdrop (z-40) - Backdrop de modals ( mismo nivel que drawer)\n * 7. modal (z-50) - Dialogs, alert-dialogs\n * 8. popover (z-[70]) - Tooltips, dropdowns DENTRO de modals\n * 9. toast (z-[100]) - Notificaciones que deben estar sobre TODO\n *\n * REGLA CRÍTICA:\n * - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-[70] o mayor\n * - Esto permite que funcionen DENTRO de modals (z-50)\n * - Backdrop de modal debe ser z-40 para estar DEBAJO del contenido del modal (z-50)\n */\n\nexport const Z_INDEX = {\n\t/**\n\t * Base - contenido normal del DOM\n\t */\n\tbase: \"z-0\",\n\n\t/**\n\t * Dropdown - Selects, combobox, date-pickers\n\t * Debe estar SOBRE contenido normal pero BAJO overlays\n\t */\n\tdropdown: \"z-10\",\n\n\t/**\n\t * Sticky - Headers, navigation fija\n\t */\n\tsticky: \"z-20\",\n\n\t/**\n\t * Drawer backdrop - Backdrop de sidebar drawer\n\t * Debe estar DEBAJO del drawer panel y DEBAJO de modals\n\t */\n\tdrawerBackdrop: \"z-30\",\n\n\t/**\n\t * Drawer - Sidebar drawer, sheets laterales\n\t * Debe estar SOBRE su backdrop pero BAJO modals\n\t */\n\tdrawer: \"z-40\",\n\n\t/**\n\t * Modal backdrop - Backdrop de dialogs\n\t * Mismo nivel que drawer backdrop (z-40)\n\t */\n\tmodalBackdrop: \"z-40\",\n\n\t/**\n\t * Modal - Dialogs, alert-dialogs\n\t * Debe estar SOBRE su backdrop\n\t */\n\tmodal: \"z-50\",\n\n\t/**\n\t * Popover - Tooltips, dropdowns, selects options DENTRO de modals\n\t * CRÍTICO: Debe ser MAYOR que modal (z-50) para aparecer sobre modals\n\t * USAR SIEMPRE mergeOverlayPanelClass() para asegurar este valor\n\t */\n\tpopover: \"z-[70]\",\n\n\t/**\n\t * Toast - Notificaciones globales\n\t * Debe estar sobre TODO\n\t */\n\ttoast: \"z-[100]\",\n} as const;\n\n/**\n * Helper para debugging z-index issues\n */\nexport function logZIndexStack(element: HTMLElement): void {\n\tif (typeof window === \"undefined\") return;\n\n\tlet current: HTMLElement | null = element;\n\tconst stack: Array<{ element: string; zIndex: string; position: string }> =\n\t\t[];\n\n\twhile (current && current !== document.body) {\n\t\tconst computed = window.getComputedStyle(current);\n\t\tconst zIndex = computed.zIndex;\n\t\tconst position = computed.position;\n\n\t\tif (zIndex !== \"auto\") {\n\t\t\tstack.push({\n\t\t\t\telement:\n\t\t\t\t\tcurrent.tagName +\n\t\t\t\t\t(current.className ? `.${current.className.split(\" \")[0]}` : \"\"),\n\t\t\t\tzIndex,\n\t\t\t\tposition,\n\t\t\t});\n\t\t}\n\n\t\tcurrent = current.parentElement;\n\t}\n\n\tconsole.table(stack);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pdm-ui-kit-src-utils.mjs","sources":["../../../src/utils/responsive.ts","../../../src/utils/z-index.ts","../../../src/utils/validators.ts","../../../src/utils/pdm-ui-kit-src-utils.ts"],"sourcesContent":["/**\n * Sistema de responsive utilities para PDM UI Kit\n * \n * Proporciona constantes, tipos y helpers para manejar responsive design\n * de forma consistente en todos los componentes.\n */\n\n/**\n * Breakpoints estándar de Tailwind CSS\n * Mobile-first approach: los estilos base son para mobile, los breakpoints son MIN-WIDTH\n */\nexport const BREAKPOINTS = {\n sm: '640px', // tablet portrait\n md: '768px', // tablet landscape\n lg: '1024px', // desktop\n xl: '1280px', // large desktop\n '2xl': '1536px' // extra large desktop\n} as const;\n\nexport type Breakpoint = keyof typeof BREAKPOINTS;\n\n/**\n * Estrategias de overflow para componentes que pueden desbordar\n */\nexport type OverflowStrategy = \n | 'auto' // Scroll automático cuando sea necesario\n | 'scroll' // Siempre scroll\n | 'hidden' // Ocultar contenido que desborda\n | 'visible'; // Permitir desbordamiento\n\n/**\n * Estrategias responsive para tablas\n */\nexport type TableResponsiveStrategy = \n | 'scroll' // Scroll horizontal en mobile (default, más simple)\n | 'stack' // Convertir filas en cards verticales en mobile\n | 'wrap' // Permitir que el contenido haga wrap\n | 'collapse'; // Colapsar columnas menos importantes en mobile\n\n/**\n * Helper para generar clases responsive de forma programática\n * \n * @example\n * responsive({ default: 'block', sm: 'flex', lg: 'grid' })\n * // Returns: 'block sm:flex lg:grid'\n */\nexport function responsive<T extends string>(\n config: Partial<Record<Breakpoint | 'default', T>>\n): string {\n const classes: string[] = [];\n \n if (config.default) {\n classes.push(config.default);\n }\n \n (['sm', 'md', 'lg', 'xl', '2xl'] as Breakpoint[]).forEach(bp => {\n if (config[bp]) {\n classes.push(`${bp}:${config[bp]}`);\n }\n });\n \n return classes.join(' ');\n}\n\n/**\n * Helper para overflow responsive\n * Maneja el caso común de scroll en mobile, auto en desktop\n * \n * @example\n * overflowResponsive('x', 'scroll', 'auto')\n * // Returns: 'overflow-x-scroll sm:overflow-x-auto'\n */\nexport function overflowResponsive(\n axis: 'x' | 'y' | 'both',\n mobile: OverflowStrategy,\n desktop?: OverflowStrategy\n): string {\n const axisClass = axis === 'both' ? 'overflow' : `overflow-${axis}`;\n const mobileClass = `${axisClass}-${mobile}`;\n \n if (!desktop || desktop === mobile) {\n return mobileClass;\n }\n \n return `${mobileClass} sm:${axisClass}-${desktop}`;\n}\n\n/**\n * Helper para spacing responsive\n * Útil para padding/margin que necesita ajustarse por breakpoint\n * \n * @example\n * spacingResponsive('px', { default: '4', sm: '6', lg: '8' })\n * // Returns: 'px-4 sm:px-6 lg:px-8'\n */\nexport function spacingResponsive(\n property: 'p' | 'px' | 'py' | 'pt' | 'pr' | 'pb' | 'pl' | 'm' | 'mx' | 'my' | 'mt' | 'mr' | 'mb' | 'ml',\n values: Partial<Record<Breakpoint | 'default', string>>\n): string {\n return responsive(\n Object.entries(values).reduce((acc, [key, value]) => {\n acc[key as Breakpoint | 'default'] = `${property}-${value}` as any;\n return acc;\n }, {} as Record<Breakpoint | 'default', string>)\n );\n}\n\n/**\n * Helper para width responsive\n * \n * @example\n * widthResponsive({ default: 'full', sm: 'auto', lg: '1/2' })\n * // Returns: 'w-full sm:w-auto lg:w-1/2'\n */\nexport function widthResponsive(\n values: Partial<Record<Breakpoint | 'default', string>>\n): string {\n return responsive(\n Object.entries(values).reduce((acc, [key, value]) => {\n acc[key as Breakpoint | 'default'] = `w-${value}` as any;\n return acc;\n }, {} as Record<Breakpoint | 'default', string>)\n );\n}\n\n/**\n * Clases comunes para containers responsive\n * Pensadas para wrappers que contienen contenido que puede desbordar\n */\nexport const RESPONSIVE_CONTAINER = {\n // Container con scroll horizontal en mobile, contenido visible en desktop\n tableWrapper: 'relative w-full overflow-x-auto sm:overflow-x-visible',\n \n // Container con padding negativo en mobile para scroll edge-to-edge\n tableWrapperFullBleed: 'relative w-full -mx-4 px-4 overflow-x-auto sm:mx-0 sm:px-0 sm:overflow-x-visible',\n \n // Container con max-width responsive\n contentWrapper: 'w-full mx-auto px-4 sm:px-6 lg:px-8 max-w-screen-2xl',\n \n // Container para modals/dialogs\n modalWrapper: 'w-full max-w-lg mx-auto px-4 sm:px-0',\n \n // Container para forms\n formWrapper: 'w-full max-w-md mx-auto space-y-4'\n} as const;\n\n/**\n * Clases comunes para display responsive\n */\nexport const RESPONSIVE_DISPLAY = {\n // Ocultar en mobile, mostrar en desktop\n hideOnMobile: 'hidden sm:block',\n \n // Mostrar solo en mobile\n showOnMobile: 'block sm:hidden',\n \n // Stack en mobile, flex en desktop\n stackToFlex: 'flex flex-col sm:flex-row',\n \n // Stack en mobile, grid en desktop\n stackToGrid: 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3'\n} as const;\n\n/**\n * Clases para table responsive strategies\n */\nexport const TABLE_RESPONSIVE = {\n // Scroll horizontal (default, más simple)\n scroll: {\n wrapper: 'relative w-full overflow-x-auto',\n table: 'w-full min-w-full',\n cell: 'whitespace-nowrap'\n },\n \n // Permitir wrap del contenido\n wrap: {\n wrapper: 'relative w-full overflow-x-auto',\n table: 'w-full',\n cell: 'whitespace-normal break-words'\n },\n \n // Stack en mobile (cada fila se convierte en card)\n // Requiere lógica adicional en el componente\n stack: {\n wrapper: 'relative w-full',\n table: 'w-full',\n row: 'block sm:table-row border-b sm:border-b-0',\n cell: 'block sm:table-cell py-2 sm:py-0 before:content-[attr(data-label)] before:font-medium before:inline-block before:w-32 sm:before:content-none'\n },\n \n // Collapse: ocultar columnas menos importantes en mobile\n // Se usa con clases de visibility en las columnas específicas\n collapse: {\n wrapper: 'relative w-full overflow-x-auto',\n table: 'w-full',\n cell: 'whitespace-nowrap',\n // Estas clases se aplican a columnas opcionales\n optionalColumn: 'hidden md:table-cell'\n }\n} as const;\n","/**\n * Z-Index Scale - Sistema centralizado de z-index\n *\n * JERARQUÍA (de menor a mayor):\n * 1. base (z-0) - Elementos normales del DOM\n * 2. dropdown (z-10) - Selects, combobox, date-pickers\n * 3. sticky (z-20) - Headers, navigation bars\n * 4. drawerBackdrop (z-30) - Backdrop de drawers\n * 5. drawer (z-40) - Sidebar drawer, sheets laterales\n * 6. modalBackdrop (z-40) - Backdrop de modals ( mismo nivel que drawer)\n * 7. modal (z-50) - Dialogs, alert-dialogs\n * 8. popover (z-[70]) - Tooltips, dropdowns DENTRO de modals\n * 9. toast (z-[100]) - Notificaciones que deben estar sobre TODO\n *\n * REGLA CRÍTICA:\n * - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-[70] o mayor\n * - Esto permite que funcionen DENTRO de modals (z-50)\n * - Backdrop de modal debe ser z-40 para estar DEBAJO del contenido del modal (z-50)\n */\n\nexport const Z_INDEX = {\n\t/**\n\t * Base - contenido normal del DOM\n\t */\n\tbase: \"z-0\",\n\n\t/**\n\t * Dropdown - Selects, combobox, date-pickers\n\t * Debe estar SOBRE contenido normal pero BAJO overlays\n\t */\n\tdropdown: \"z-10\",\n\n\t/**\n\t * Sticky - Headers, navigation fija\n\t */\n\tsticky: \"z-20\",\n\n\t/**\n\t * Drawer backdrop - Backdrop de sidebar drawer\n\t * Debe estar DEBAJO del drawer panel y DEBAJO de modals\n\t */\n\tdrawerBackdrop: \"z-30\",\n\n\t/**\n\t * Drawer - Sidebar drawer, sheets laterales\n\t * Debe estar SOBRE su backdrop pero BAJO modals\n\t */\n\tdrawer: \"z-40\",\n\n\t/**\n\t * Modal backdrop - Backdrop de dialogs\n\t * Mismo nivel que drawer backdrop (z-40)\n\t */\n\tmodalBackdrop: \"z-40\",\n\n\t/**\n\t * Modal - Dialogs, alert-dialogs\n\t * Debe estar SOBRE su backdrop\n\t */\n\tmodal: \"z-50\",\n\n\t/**\n\t * Popover - Tooltips, dropdowns, selects options DENTRO de modals\n\t * CRÍTICO: Debe ser MAYOR que modal (z-50) para aparecer sobre modals\n\t * USAR SIEMPRE mergeOverlayPanelClass() para asegurar este valor\n\t */\n\tpopover: \"z-[70]\",\n\n\t/**\n\t * Toast - Notificaciones globales\n\t * Debe estar sobre TODO\n\t */\n\ttoast: \"z-[100]\",\n} as const;\n\n/**\n * Helper para debugging z-index issues\n */\nexport function logZIndexStack(element: HTMLElement): void {\n\tif (typeof window === \"undefined\") return;\n\n\tlet current: HTMLElement | null = element;\n\tconst stack: Array<{ element: string; zIndex: string; position: string }> =\n\t\t[];\n\n\twhile (current && current !== document.body) {\n\t\tconst computed = window.getComputedStyle(current);\n\t\tconst zIndex = computed.zIndex;\n\t\tconst position = computed.position;\n\n\t\tif (zIndex !== \"auto\") {\n\t\t\tstack.push({\n\t\t\t\telement:\n\t\t\t\t\tcurrent.tagName +\n\t\t\t\t\t(current.className ? `.${current.className.split(\" \")[0]}` : \"\"),\n\t\t\t\tzIndex,\n\t\t\t\tposition,\n\t\t\t});\n\t\t}\n\n\t\tcurrent = current.parentElement;\n\t}\n\n\tconsole.table(stack);\n}\n","/**\n * Form validation utilities for PDM UI Kit\n *\n * Pure validation functions and patterns that work with any form validation library.\n * These functions validate values directly and return true/false, making them framework-agnostic.\n */\n\nexport interface PdmValidationError {\n message: string;\n code: string;\n}\n\n/**\n * Validate email format\n *\n * @example\n * isValidEmail('user@example.com') // true\n */\nexport function isValidEmail(value: string): boolean {\n if (!value) return false;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(value);\n}\n\n/**\n * Validate URL format\n *\n * @example\n * isValidUrl('https://example.com') // true\n */\nexport function isValidUrl(value: string): boolean {\n if (!value) return false;\n try {\n new URL(value);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Validate minimum length\n *\n * @example\n * hasMinLength('password', 8) // true if length >= 8\n */\nexport function hasMinLength(value: string, min: number): boolean {\n if (!value) return false;\n return String(value).length >= min;\n}\n\n/**\n * Validate maximum length\n *\n * @example\n * hasMaxLength('bio', 500) // true if length <= 500\n */\nexport function hasMaxLength(value: string, max: number): boolean {\n if (!value) return true;\n return String(value).length <= max;\n}\n\n/**\n * Validate that value only contains numbers\n *\n * @example\n * isNumeric('12345') // true\n */\nexport function isNumeric(value: string): boolean {\n if (!value) return false;\n return /^\\d+$/.test(String(value));\n}\n\n/**\n * Validate that two values match (e.g., password confirmation)\n *\n * @example\n * valuesMatch(password, confirmPassword) // true if they match\n */\nexport function valuesMatch(value1: string, value2: string): boolean {\n if (!value1 || !value2) return false;\n return value1 === value2;\n}\n\n/**\n * Validate minimum value\n *\n * @example\n * isMinValue(age, 18) // true if age >= 18\n */\nexport function isMinValue(value: number, min: number): boolean {\n if (value === null || value === undefined) return false;\n return value >= min;\n}\n\n/**\n * Validate maximum value\n *\n * @example\n * isMaxValue(percentage, 100) // true if percentage <= 100\n */\nexport function isMaxValue(value: number, max: number): boolean {\n if (value === null || value === undefined) return false;\n return value <= max;\n}\n\n/**\n * Validate phone number format (basic international format)\n * Accepts: +1234567890, (123) 456-7890, 123-456-7890\n *\n * @example\n * isValidPhone('+1234567890') // true\n */\nexport function isValidPhone(value: string): boolean {\n if (!value) return false;\n const phoneRegex = /^[\\+]?[(]?[0-9]{3}[)]?[-\\s\\.]?[0-9]{3}[-\\s\\.]?[0-9]{4,6}$/;\n return phoneRegex.test(String(value).replace(/\\s/g, ''));\n}\n\n/**\n * Check if value contains at least one uppercase letter\n *\n * @example\n * hasUppercase('Password') // true\n */\nexport function hasUppercase(value: string): boolean {\n if (!value) return false;\n return /[A-Z]/.test(value);\n}\n\n/**\n * Check if value contains at least one lowercase letter\n *\n * @example\n * hasLowercase('Password') // true\n */\nexport function hasLowercase(value: string): boolean {\n if (!value) return false;\n return /[a-z]/.test(value);\n}\n\n/**\n * Check if value contains at least one number\n *\n * @example\n * hasNumber('Pass123') // true\n */\nexport function hasNumber(value: string): boolean {\n if (!value) return false;\n return /\\d/.test(value);\n}\n\n/**\n * Check if value contains at least one special character\n *\n * @example\n * hasSpecialChar('Pass@123') // true\n */\nexport function hasSpecialChar(value: string): boolean {\n if (!value) return false;\n return /[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]/.test(value);\n}\n\n/**\n * Get user-friendly error message for validation failures\n *\n * @example\n * getErrorMessage('invalidEmail') // \"Please enter a valid email address\"\n */\nexport function getErrorMessage(errorCode: string, fieldName: string = 'Field'): string {\n const messages: Record<string, string> = {\n required: `${fieldName} is required`,\n invalidEmail: 'Please enter a valid email address',\n invalidUrl: 'Please enter a valid URL',\n invalidPhone: 'Please enter a valid phone number',\n notNumeric: `${fieldName} must contain only numbers`,\n noUppercase: `${fieldName} must contain at least one uppercase letter`,\n noLowercase: `${fieldName} must contain at least one lowercase letter`,\n noNumber: `${fieldName} must contain at least one number`,\n noSpecialChar: `${fieldName} must contain at least one special character`,\n fieldsDoNotMatch: 'Fields do not match',\n };\n\n return messages[errorCode] || 'Invalid input';\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}