@axzydev/axzy_ui_system 1.7.0 → 1.7.1

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 (51) hide show
  1. package/dist/index.cjs +1738 -308
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.cts +739 -3
  5. package/dist/index.d.ts +739 -3
  6. package/dist/index.js +1629 -233
  7. package/dist/index.js.map +1 -1
  8. package/dist/layered.css +1 -1
  9. package/package.json +14 -7
  10. package/src/App.tsx +60 -2
  11. package/src/components/atoms/image/image.props.ts +2 -0
  12. package/src/components/atoms/image/image.tsx +3 -2
  13. package/src/components/organisms/dialog/dialog.props.ts +2 -0
  14. package/src/components/organisms/dialog/dialog.tsx +4 -3
  15. package/src/dev.css +6 -0
  16. package/src/index.ts +90 -1
  17. package/src/json-renderer/catalog/axzyCatalog.ts +362 -0
  18. package/src/json-renderer/catalog/catalog.props.ts +128 -0
  19. package/src/json-renderer/catalog/resolve.ts +225 -0
  20. package/src/json-renderer/index.ts +70 -0
  21. package/src/json-renderer/kernel/NodeBoundary.tsx +53 -0
  22. package/src/json-renderer/kernel/SchemaRenderer.tsx +197 -0
  23. package/src/json-renderer/kernel/kernel.test.tsx +341 -0
  24. package/src/json-renderer/kernel/partial.ts +92 -0
  25. package/src/json-renderer/kernel/renderNode.tsx +113 -0
  26. package/src/json-renderer/kernel/schemaRenderer.props.ts +42 -0
  27. package/src/json-renderer/kernel/types.ts +159 -0
  28. package/src/json-renderer/shared/errors.ts +92 -0
  29. package/src/json-renderer/shared/limits.ts +87 -0
  30. package/src/json-renderer/shared/paths.ts +66 -0
  31. package/src/json-renderer/shared/shared.test.ts +108 -0
  32. package/src/json-renderer/stream/tolerantParse.test.ts +152 -0
  33. package/src/json-renderer/stream/tolerantParse.ts +449 -0
  34. package/src/json-renderer/test/setup.ts +38 -0
  35. package/src/json-renderer/validation/migrate.ts +83 -0
  36. package/src/json-renderer/validation/validate.ts +161 -0
  37. package/src/json-renderer/validation/validation.test.ts +165 -0
  38. package/src/json-renderer/vocabulary/buildContract.ts +158 -0
  39. package/src/sandbox/axzyConfig.test.ts +40 -0
  40. package/src/sandbox/axzyConfig.ts +77 -0
  41. package/src/sandbox/i18n.ts +218 -0
  42. package/src/sandbox/navigation.ts +1 -0
  43. package/src/sandbox/useHashRoute.ts +39 -9
  44. package/src/showcases/DemoJsonDashboard.tsx +489 -0
  45. package/src/showcases/DemoJsonDocs.tsx +339 -0
  46. package/src/showcases/DemoJsonPortfolio.tsx +257 -0
  47. package/src/showcases/JsonScreenShowcase.tsx +341 -0
  48. package/src/showcases/demoApp/demoData.ts +181 -0
  49. package/src/showcases/demoApp/nodeTree.test.ts +39 -0
  50. package/src/showcases/demoApp/nodeTree.ts +35 -0
  51. package/src/showcases/demoApp/schemas.test.ts +54 -0
package/dist/index.js CHANGED
@@ -1823,7 +1823,7 @@ function ITJsonRenderer({
1823
1823
  json,
1824
1824
  className
1825
1825
  }) {
1826
- const renderNode = (node) => {
1826
+ const renderNode2 = (node) => {
1827
1827
  if (node == null || typeof node === "boolean") {
1828
1828
  return null;
1829
1829
  }
@@ -1834,10 +1834,10 @@ function ITJsonRenderer({
1834
1834
  return node;
1835
1835
  }
1836
1836
  if (Array.isArray(node)) {
1837
- return node.map((child, idx) => /* @__PURE__ */ jsx9(React.Fragment, { children: renderNode(child) }, idx));
1837
+ return node.map((child, idx) => /* @__PURE__ */ jsx9(React.Fragment, { children: renderNode2(child) }, idx));
1838
1838
  }
1839
1839
  const { type, props = {}, children, text } = node;
1840
- const childContent = children !== void 0 ? renderNode(children) : text;
1840
+ const childContent = children !== void 0 ? renderNode2(children) : text;
1841
1841
  switch (type) {
1842
1842
  case "button":
1843
1843
  return /* @__PURE__ */ jsx9(ITButton, { ...props, children: childContent });
@@ -1859,9 +1859,9 @@ function ITJsonRenderer({
1859
1859
  }
1860
1860
  };
1861
1861
  if (Array.isArray(json)) {
1862
- return /* @__PURE__ */ jsx9("div", { className: clsx7(className), children: json.map((n, idx) => /* @__PURE__ */ jsx9(React.Fragment, { children: renderNode(n) }, idx)) });
1862
+ return /* @__PURE__ */ jsx9("div", { className: clsx7(className), children: json.map((n, idx) => /* @__PURE__ */ jsx9(React.Fragment, { children: renderNode2(n) }, idx)) });
1863
1863
  }
1864
- return /* @__PURE__ */ jsx9("div", { className: clsx7(className), children: renderNode(json) });
1864
+ return /* @__PURE__ */ jsx9("div", { className: clsx7(className), children: renderNode2(json) });
1865
1865
  }
1866
1866
 
1867
1867
  // src/hooks/useJsonRender.tsx
@@ -5970,7 +5970,8 @@ function ITDialog({
5970
5970
  className,
5971
5971
  title,
5972
5972
  useFormHeader = false,
5973
- fullScreen = false
5973
+ fullScreen = false,
5974
+ padded = true
5974
5975
  }) {
5975
5976
  const { t } = useITTranslation();
5976
5977
  const modalRef = useRef14(null);
@@ -5999,7 +6000,7 @@ function ITDialog({
5999
6000
  "div",
6000
6001
  {
6001
6002
  ref: modalRef,
6002
- className: `overflow-hidden relative ${fullScreen ? "w-screen h-screen max-w-none rounded-none m-0 flex flex-col" : `${className || ""} ${useFormHeader ? "p-0" : "p-6"}`}`,
6003
+ className: `overflow-hidden relative ${fullScreen ? "w-screen h-screen max-w-none rounded-none m-0 flex flex-col" : `${className || ""} ${!padded || useFormHeader ? "p-0" : "p-6"}`}`,
6003
6004
  style: {
6004
6005
  backgroundColor: theme.card.backgroundColor,
6005
6006
  borderRadius: fullScreen ? "0" : theme.card.borderRadius,
@@ -6021,8 +6022,8 @@ function ITDialog({
6021
6022
  children: /* @__PURE__ */ jsx31(FaRegTimesCircle, {})
6022
6023
  }
6023
6024
  ),
6024
- title && /* @__PURE__ */ jsx31(ITText, { as: "h2", className: "text-xl font-semibold mb-4", children: title }),
6025
- /* @__PURE__ */ jsx31("div", { children })
6025
+ title && (padded ? /* @__PURE__ */ jsx31(ITText, { as: "h2", className: "text-xl font-semibold mb-4", children: title }) : /* @__PURE__ */ jsx31("div", { className: "flex items-center justify-between gap-3 px-6 py-4 border-b border-slate-200", children: /* @__PURE__ */ jsx31(ITText, { as: "h2", className: "text-lg font-medium", children: title }) })),
6026
+ /* @__PURE__ */ jsx31("div", { className: padded ? void 0 : "min-h-0 flex-1 flex flex-col", children })
6026
6027
  ] })
6027
6028
  }
6028
6029
  )
@@ -6949,7 +6950,8 @@ var ITImage = ({
6949
6950
  src,
6950
6951
  alt,
6951
6952
  className = "",
6952
- fallback = ""
6953
+ fallback = "",
6954
+ fit = "cover"
6953
6955
  }) => {
6954
6956
  const [imageError, setImageError] = useState23(false);
6955
6957
  const { t } = useITTranslation();
@@ -6965,7 +6967,8 @@ var ITImage = ({
6965
6967
  {
6966
6968
  src: fallback,
6967
6969
  alt: t("image.fallbackAlt"),
6968
- className: "w-full h-full object-cover"
6970
+ className: "w-full h-full",
6971
+ style: { objectFit: fit }
6969
6972
  }
6970
6973
  ) : /* @__PURE__ */ jsx39(
6971
6974
  "img",
@@ -6973,7 +6976,8 @@ var ITImage = ({
6973
6976
  src,
6974
6977
  alt,
6975
6978
  onError: handleImageError,
6976
- className: "w-full h-full object-cover"
6979
+ className: "w-full h-full",
6980
+ style: { objectFit: fit }
6977
6981
  }
6978
6982
  )
6979
6983
  }
@@ -11106,7 +11110,7 @@ function ITCodeTreeView({
11106
11110
  const line = analysis.nodeLines.get(pathKey(node.path))?.line;
11107
11111
  const isRoot = node.key === "";
11108
11112
  const isCollapsed = collapsed[node.key] ?? (node.childCount > 0 && node.level >= AUTO_EXPANDED_LEVELS);
11109
- const hasChildren = node.childCount > 0;
11113
+ const hasChildren2 = node.childCount > 0;
11110
11114
  const isPrimitive = node.kind !== "object" && node.kind !== "array";
11111
11115
  return /* @__PURE__ */ jsxs52(
11112
11116
  "div",
@@ -11114,7 +11118,7 @@ function ITCodeTreeView({
11114
11118
  className: "it-json-editor-tree-row",
11115
11119
  style: { paddingLeft: node.level * 14 },
11116
11120
  children: [
11117
- hasChildren ? /* @__PURE__ */ jsx72(
11121
+ hasChildren2 ? /* @__PURE__ */ jsx72(
11118
11122
  "button",
11119
11123
  {
11120
11124
  type: "button",
@@ -11129,7 +11133,7 @@ function ITCodeTreeView({
11129
11133
  /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tk-key", children: node.label }),
11130
11134
  /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tk-punct", children: ":" })
11131
11135
  ] }),
11132
- hasChildren ? /* @__PURE__ */ jsxs52(Fragment11, { children: [
11136
+ hasChildren2 ? /* @__PURE__ */ jsxs52(Fragment11, { children: [
11133
11137
  /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tk-punct", children: node.kind === "array" ? "[" : "{" }),
11134
11138
  isCollapsed && /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tk-punct", children: node.kind === "array" ? "]" : "}" }),
11135
11139
  /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tree-badge", children: t("jsonEditor.childCount", { count: node.childCount }) })
@@ -12149,8 +12153,1452 @@ function EditorToggle({
12149
12153
  );
12150
12154
  }
12151
12155
 
12156
+ // src/json-renderer/kernel/SchemaRenderer.tsx
12157
+ import { useEffect as useEffect18, useMemo as useMemo16, useRef as useRef23 } from "react";
12158
+
12159
+ // src/types/loader.types.ts
12160
+ var sizeClasses = {
12161
+ sm: "h-4 w-4",
12162
+ md: "h-8 w-8",
12163
+ lg: "h-12 w-12",
12164
+ xl: "h-16 w-16"
12165
+ };
12166
+
12167
+ // src/components/atoms/loader/loader.tsx
12168
+ import { jsx as jsx74 } from "react/jsx-runtime";
12169
+ function ITLoader({
12170
+ size = "md",
12171
+ variant = "spinner",
12172
+ color = "primary",
12173
+ // Default to semantic primary
12174
+ className = ""
12175
+ }) {
12176
+ const { t } = useITTranslation();
12177
+ const isSemantic = color in theme.colors;
12178
+ const resolvedColor = isSemantic ? theme.colors[color][500] : color;
12179
+ const isCssValue = isSemantic || color.startsWith("#") || color.startsWith("rgb");
12180
+ const style = isCssValue ? { color: resolvedColor } : {};
12181
+ const bgStyle = isCssValue ? { backgroundColor: resolvedColor } : {};
12182
+ const colorClass = !isCssValue ? color : "";
12183
+ if (variant === "spinner") {
12184
+ return /* @__PURE__ */ jsx74(
12185
+ "div",
12186
+ {
12187
+ className: `inline-block ${sizeClasses[size]} animate-spin rounded-full border-2 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${colorClass} ${className}`,
12188
+ role: "status",
12189
+ style,
12190
+ children: /* @__PURE__ */ jsx74(ITText, { as: "span", className: "!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]", children: t("common.loading") })
12191
+ }
12192
+ );
12193
+ }
12194
+ if (variant === "dots") {
12195
+ return /* @__PURE__ */ jsx74(
12196
+ "div",
12197
+ {
12198
+ className: `flex items-center justify-center space-x-2 ${className}`,
12199
+ children: [...Array(3)].map((_, i) => /* @__PURE__ */ jsx74(
12200
+ "div",
12201
+ {
12202
+ className: `${sizeClasses[size.replace(/l|g/, "")]} animate-bounce rounded-full ${colorClass}`,
12203
+ style: {
12204
+ ...bgStyle,
12205
+ animationDelay: `${i * 0.1}s`
12206
+ }
12207
+ },
12208
+ i
12209
+ ))
12210
+ }
12211
+ );
12212
+ }
12213
+ if (variant === "bar") {
12214
+ return /* @__PURE__ */ jsx74(
12215
+ "div",
12216
+ {
12217
+ className: `w-full ${size === "sm" ? "h-1" : size === "md" ? "h-1.5" : size === "lg" ? "h-2" : "h-2.5"} bg-secondary-200 rounded-full overflow-hidden ${className}`,
12218
+ children: /* @__PURE__ */ jsx74(
12219
+ "div",
12220
+ {
12221
+ className: `h-full animate-progress ${colorClass}`,
12222
+ style: {
12223
+ backgroundColor: resolvedColor,
12224
+ // Simplified gradient for modern look, or keep it solid
12225
+ backgroundImage: isCssValue ? `linear-gradient(to right, ${resolvedColor}DD, ${resolvedColor})` : void 0,
12226
+ animation: "progress 1.5s ease-in-out infinite"
12227
+ }
12228
+ }
12229
+ )
12230
+ }
12231
+ );
12232
+ }
12233
+ if (variant === "pulse") {
12234
+ return /* @__PURE__ */ jsx74(
12235
+ "div",
12236
+ {
12237
+ className: `rounded-full ${sizeClasses[size]} animate-pulse ${colorClass} ${className}`,
12238
+ style: bgStyle
12239
+ }
12240
+ );
12241
+ }
12242
+ return null;
12243
+ }
12244
+
12245
+ // src/json-renderer/catalog/catalog.props.ts
12246
+ var GLOBALLY_FORBIDDEN_PROPS = [
12247
+ "dangerouslySetInnerHTML",
12248
+ "render",
12249
+ "component",
12250
+ "children",
12251
+ // los hijos se declaran como nodos, nunca como prop
12252
+ "ref",
12253
+ "key",
12254
+ "style",
12255
+ // se permite solo si el catálogo lo declara explícitamente
12256
+ "icon",
12257
+ "actions",
12258
+ "action",
12259
+ "emptyAction",
12260
+ "fallback",
12261
+ "logo",
12262
+ "badge"
12263
+ ];
12264
+ function createCatalog(entries, excluded = {}) {
12265
+ const index = {};
12266
+ for (const entry of entries) {
12267
+ if (index[entry.type]) {
12268
+ throw new Error(`Cat\xE1logo duplicado: ${entry.type}`);
12269
+ }
12270
+ index[entry.type] = entry;
12271
+ }
12272
+ return { entries: index, excluded };
12273
+ }
12274
+ function getCatalogEntry(catalog, type) {
12275
+ return catalog.entries[type];
12276
+ }
12277
+ function isExcludedType(catalog, type) {
12278
+ return Boolean(catalog.excluded && type in catalog.excluded);
12279
+ }
12280
+ function getExclusionReason(catalog, type) {
12281
+ return catalog.excluded?.[type];
12282
+ }
12283
+
12284
+ // src/json-renderer/catalog/axzyCatalog.ts
12285
+ var COLORS = ["primary", "secondary", "success", "danger", "warning", "info", "purple", "error", "gray"];
12286
+ var SIZES = ["sm", "md", "lg"];
12287
+ var DIRECTIONS = ["row", "column"];
12288
+ var ALIGNS = ["start", "center", "end", "stretch", "baseline"];
12289
+ var JUSTIFIES = ["start", "center", "end", "between", "around", "evenly"];
12290
+ var WRAPS = ["nowrap", "wrap", "wrap-reverse"];
12291
+ var TEXT_PROPS = {
12292
+ className: { kind: "string", doc: "Clases extra del componente." }
12293
+ };
12294
+ var AXZY_CATALOG_ENTRIES = [
12295
+ {
12296
+ type: "ITText",
12297
+ component: ITText,
12298
+ children: true,
12299
+ text: true,
12300
+ summary: "Texto sem\xE1ntico. Usa `text` o `children` para el contenido.",
12301
+ props: {
12302
+ as: { kind: "enum", values: ["span", "p", "h1", "h2", "h3", "h4", "label", "div", "strong", "em"], default: "span", doc: "Etiqueta HTML sem\xE1ntica." },
12303
+ muted: { kind: "boolean", default: false, doc: "Aten\xFAa el color del texto." },
12304
+ ...TEXT_PROPS
12305
+ }
12306
+ },
12307
+ {
12308
+ type: "ITButton",
12309
+ component: ITButton,
12310
+ children: true,
12311
+ text: true,
12312
+ summary: "Bot\xF3n. `onClick` es una acci\xF3n registrada por el host.",
12313
+ props: {
12314
+ label: { kind: "string", doc: "Texto del bot\xF3n (alternativa a `text`)." },
12315
+ color: { kind: "enum", values: COLORS, default: "primary" },
12316
+ size: { kind: "enum", values: SIZES, default: "md" },
12317
+ variant: {
12318
+ kind: "enum",
12319
+ values: ["filled", "outlined", "raised", "rounded", "text", "raised-text", "icon-only", "link"],
12320
+ default: "filled"
12321
+ },
12322
+ disabled: { kind: "boolean", default: false },
12323
+ type: { kind: "enum", values: ["button", "submit", "reset"], default: "button" },
12324
+ ariaLabel: { kind: "string", doc: "Etiqueta accesible cuando el bot\xF3n no lleva texto." },
12325
+ title: { kind: "string" },
12326
+ onClick: { kind: "action", doc: "Nombre de una acci\xF3n registrada." },
12327
+ ...TEXT_PROPS
12328
+ },
12329
+ forbidden: ["icon"]
12330
+ },
12331
+ {
12332
+ type: "ITCard",
12333
+ component: ITCard,
12334
+ children: true,
12335
+ summary: "Tarjeta con t\xEDtulo, imagen y contenido.",
12336
+ props: {
12337
+ title: { kind: "string" },
12338
+ image: { kind: "string", doc: "URL de la imagen de cabecera." },
12339
+ alt: { kind: "string" },
12340
+ onClick: { kind: "action" },
12341
+ imageClassName: { kind: "string" },
12342
+ titleClassName: { kind: "string" },
12343
+ contentClassName: { kind: "string" },
12344
+ actionClassName: { kind: "string" },
12345
+ ...TEXT_PROPS
12346
+ },
12347
+ forbidden: ["actions"]
12348
+ },
12349
+ {
12350
+ type: "ITAlert",
12351
+ component: ITAlert,
12352
+ children: true,
12353
+ text: true,
12354
+ summary: "Aviso con variante sem\xE1ntica.",
12355
+ props: {
12356
+ variant: { kind: "enum", values: ["info", "success", "warning", "error"], default: "info" },
12357
+ title: { kind: "string" },
12358
+ dismissible: { kind: "boolean", default: false },
12359
+ onDismiss: { kind: "action" },
12360
+ ...TEXT_PROPS
12361
+ },
12362
+ forbidden: ["icon"]
12363
+ },
12364
+ {
12365
+ type: "ITEmptyState",
12366
+ component: ITEmptyState,
12367
+ text: true,
12368
+ summary: "Estado vac\xEDo con t\xEDtulo, descripci\xF3n y acci\xF3n.",
12369
+ props: {
12370
+ title: { kind: "string", required: true },
12371
+ description: { kind: "string" },
12372
+ ...TEXT_PROPS
12373
+ },
12374
+ forbidden: ["icon", "action"]
12375
+ },
12376
+ {
12377
+ type: "ITStatCard",
12378
+ component: ITStatCard,
12379
+ summary: "M\xE9trica con valor y tendencia.",
12380
+ props: {
12381
+ label: { kind: "string", required: true },
12382
+ value: { kind: "string", required: true, doc: "Valor ya formateado o n\xFAmero." },
12383
+ trend: { kind: "string" },
12384
+ trendDirection: { kind: "enum", values: ["up", "down", "neutral"] },
12385
+ color: { kind: "string", doc: "Color CSS del icono." },
12386
+ onClick: { kind: "action" },
12387
+ ...TEXT_PROPS
12388
+ },
12389
+ forbidden: ["icon"]
12390
+ },
12391
+ {
12392
+ type: "ITChip",
12393
+ component: ITChip,
12394
+ children: true,
12395
+ text: true,
12396
+ summary: "Etiqueta compacta, opcionalmente removible o seleccionable.",
12397
+ props: {
12398
+ label: { kind: "string" },
12399
+ color: { kind: "enum", values: COLORS, default: "gray" },
12400
+ size: { kind: "enum", values: SIZES, default: "md" },
12401
+ variant: { kind: "enum", values: ["soft", "filled", "outlined"], default: "soft" },
12402
+ removable: { kind: "boolean", default: false },
12403
+ selected: { kind: "boolean", default: false },
12404
+ disabled: { kind: "boolean", default: false },
12405
+ onRemove: { kind: "action" },
12406
+ onClick: { kind: "action" },
12407
+ ...TEXT_PROPS
12408
+ },
12409
+ forbidden: ["icon"]
12410
+ },
12411
+ {
12412
+ type: "ITBadget",
12413
+ component: ITBadget,
12414
+ children: true,
12415
+ text: true,
12416
+ summary: "Insignia de estado.",
12417
+ props: {
12418
+ label: { kind: "string" },
12419
+ color: { kind: "enum", values: COLORS, default: "primary" },
12420
+ size: { kind: "enum", values: SIZES, default: "md" },
12421
+ variant: { kind: "enum", values: ["soft", "filled", "outlined"], default: "soft" },
12422
+ ...TEXT_PROPS
12423
+ }
12424
+ },
12425
+ {
12426
+ type: "ITAvatar",
12427
+ component: ITAvatar,
12428
+ summary: "Avatar con imagen o iniciales.",
12429
+ props: {
12430
+ src: { kind: "string" },
12431
+ alt: { kind: "string" },
12432
+ initials: { kind: "string", doc: "Se usa cuando no hay imagen." },
12433
+ size: { kind: "enum", values: ["xs", "sm", "md", "lg", "xl"] },
12434
+ color: { kind: "string" },
12435
+ onClick: { kind: "action" },
12436
+ ...TEXT_PROPS
12437
+ },
12438
+ forbidden: ["badge"]
12439
+ },
12440
+ {
12441
+ type: "ITDivider",
12442
+ component: ITDivider,
12443
+ summary: "Separador horizontal o vertical.",
12444
+ props: {
12445
+ orientation: { kind: "enum", values: ["horizontal", "vertical"], default: "horizontal" },
12446
+ color: { kind: "string" },
12447
+ thickness: { kind: "string" },
12448
+ ...TEXT_PROPS
12449
+ }
12450
+ },
12451
+ {
12452
+ type: "ITStack",
12453
+ component: ITStack,
12454
+ children: true,
12455
+ summary: "Pila con direcci\xF3n y separaci\xF3n uniforme.",
12456
+ props: {
12457
+ direction: { kind: "enum", values: DIRECTIONS, default: "column" },
12458
+ spacing: { kind: "number", default: 0 },
12459
+ alignItems: { kind: "enum", values: ALIGNS },
12460
+ justifyContent: { kind: "enum", values: JUSTIFIES },
12461
+ flexWrap: { kind: "enum", values: WRAPS },
12462
+ ...TEXT_PROPS
12463
+ },
12464
+ forbidden: ["divider", "style"]
12465
+ },
12466
+ {
12467
+ type: "ITFlex",
12468
+ component: ITFlex,
12469
+ children: true,
12470
+ summary: "Contenedor flex completo.",
12471
+ props: {
12472
+ direction: { kind: "enum", values: DIRECTIONS, default: "row" },
12473
+ align: { kind: "enum", values: ALIGNS },
12474
+ justify: { kind: "enum", values: JUSTIFIES },
12475
+ wrap: { kind: "enum", values: WRAPS },
12476
+ gap: { kind: "number", default: 0 },
12477
+ grow: { kind: "boolean" },
12478
+ shrink: { kind: "boolean" },
12479
+ basis: { kind: "string" },
12480
+ ...TEXT_PROPS
12481
+ },
12482
+ forbidden: ["style", "onClick"]
12483
+ },
12484
+ {
12485
+ type: "ITGrid",
12486
+ component: ITGrid,
12487
+ children: true,
12488
+ summary: "Rejilla de 12 columnas; `item` para una celda.",
12489
+ props: {
12490
+ container: { kind: "boolean", default: false },
12491
+ item: { kind: "boolean", default: false },
12492
+ spacing: { kind: "number", default: 0 },
12493
+ columns: { kind: "integer", default: 12, doc: "Columnas del contenedor." },
12494
+ xs: { kind: "integer" },
12495
+ sm: { kind: "integer" },
12496
+ md: { kind: "integer" },
12497
+ lg: { kind: "integer" },
12498
+ xl: { kind: "integer" },
12499
+ ...TEXT_PROPS
12500
+ },
12501
+ forbidden: ["style"]
12502
+ },
12503
+ {
12504
+ type: "ITLoader",
12505
+ component: ITLoader,
12506
+ summary: "Indicador de carga.",
12507
+ props: {
12508
+ variant: { kind: "enum", values: ["spinner", "dots", "bar", "pulse"], default: "spinner" },
12509
+ size: { kind: "enum", values: ["xs", "sm", "md", "lg", "xl"], default: "md" },
12510
+ color: { kind: "string" },
12511
+ ...TEXT_PROPS
12512
+ }
12513
+ },
12514
+ {
12515
+ type: "ITSkeleton",
12516
+ component: ITSkeleton,
12517
+ summary: "Marcador de carga con forma.",
12518
+ props: {
12519
+ variant: { kind: "enum", values: ["text", "rect", "circle"], default: "text" },
12520
+ width: { kind: "string" },
12521
+ height: { kind: "string" },
12522
+ count: { kind: "integer", default: 1 },
12523
+ ...TEXT_PROPS
12524
+ },
12525
+ forbidden: ["style"]
12526
+ },
12527
+ {
12528
+ type: "ITProgress",
12529
+ component: ITProgress,
12530
+ summary: "Barra de progreso.",
12531
+ props: {
12532
+ value: { kind: "number", default: 0 },
12533
+ max: { kind: "number", default: 100 },
12534
+ variant: { kind: "enum", values: ["determinate", "indeterminate"], default: "determinate" },
12535
+ color: { kind: "enum", values: COLORS, default: "primary" },
12536
+ size: { kind: "enum", values: SIZES, default: "md" },
12537
+ ...TEXT_PROPS
12538
+ },
12539
+ forbidden: ["style"]
12540
+ },
12541
+ {
12542
+ type: "ITDataTable",
12543
+ component: ITDataTable,
12544
+ summary: "Tabla con paginaci\xF3n, orden y filtros. Los datos llegan de una fuente que el host resuelve (`$source`).",
12545
+ props: {
12546
+ columns: {
12547
+ kind: "columns",
12548
+ required: true,
12549
+ doc: "Columnas: { key, label, type, sortable, filter, currencyMX }."
12550
+ },
12551
+ fetchData: {
12552
+ kind: "data",
12553
+ required: true,
12554
+ doc: 'Referencia a una fuente: { "$source": "usuarios" }. El host la convierte en un fetcher.'
12555
+ },
12556
+ title: { kind: "string", doc: "T\xEDtulo opcional sobre la tabla." },
12557
+ defaultItemsPerPage: { kind: "integer", default: 5, doc: "Filas por p\xE1gina al abrir." },
12558
+ itemsPerPageOptions: { kind: "array", doc: "Opciones del paginador, p. ej. [5, 10, 20]." },
12559
+ debounceMs: { kind: "integer", default: 400, doc: "Espera antes de refiltrar al teclear." },
12560
+ variant: { kind: "enum", values: ["default", "striped", "bordered", "minimal"], default: "default" },
12561
+ size: { kind: "enum", values: SIZES, default: "md" },
12562
+ density: { kind: "enum", values: ["compact", "normal", "comfortable"], default: "normal" },
12563
+ layout: { kind: "enum", values: ["auto", "fixed"], default: "auto" },
12564
+ showVerticalBorder: { kind: "boolean", default: true },
12565
+ autoCardBreakpoint: { kind: "integer", default: 0, doc: "Ancho (px) por debajo del cual cae a tarjetas." },
12566
+ onRowClick: { kind: "action", doc: "Nombre de una acci\xF3n registrada; recibe la fila." },
12567
+ className: { kind: "string" },
12568
+ containerClassName: { kind: "string" }
12569
+ },
12570
+ forbidden: ["renderCard", "loadingIndicator"]
12571
+ },
12572
+ {
12573
+ type: "ITImage",
12574
+ component: image_default,
12575
+ summary: "Imagen con respaldo si falla la carga.",
12576
+ props: {
12577
+ src: { kind: "string", required: true },
12578
+ alt: { kind: "string" },
12579
+ fallback: { kind: "string", doc: "URL de respaldo." },
12580
+ onClick: { kind: "action" },
12581
+ ...TEXT_PROPS
12582
+ }
12583
+ }
12584
+ ];
12585
+ var AXZY_EXCLUDED_TYPES = {
12586
+ ITJsonRenderer: "Recursi\xF3n: un esquema no puede pedir otro renderer.",
12587
+ ITSchemaRenderer: "Recursi\xF3n: un esquema no puede pedir otro renderer.",
12588
+ ITJSONEditor: "Ejecuta entrada del usuario como c\xF3digo.",
12589
+ ITFormBuilder: "Se sustituye por el nodo `form` del motor.",
12590
+ ITWysiwyg: "Produce HTML, que se salta la lista blanca.",
12591
+ ITI18nProvider: "Lo monta el host, no el esquema.",
12592
+ ITThemeProvider: "Lo monta el host, no el esquema.",
12593
+ ITLayout: "El shell lo declara el router, no un nodo suelto.",
12594
+ ITNavbar: "El shell lo declara el router, no un nodo suelto.",
12595
+ ITSidebar: "El shell lo declara el router, no un nodo suelto.",
12596
+ ITTopBar: "El shell lo declara el router, no un nodo suelto."
12597
+ };
12598
+ var axzyCatalog = createCatalog(AXZY_CATALOG_ENTRIES, AXZY_EXCLUDED_TYPES);
12599
+ var axzyCatalogTypes = Object.keys(axzyCatalog.entries);
12600
+
12601
+ // src/json-renderer/shared/limits.ts
12602
+ var DEFAULT_LIMITS = {
12603
+ maxNodes: 5e3,
12604
+ maxDepth: 40,
12605
+ maxMsPerChunk: 8,
12606
+ actionTimeoutMs: 15e3,
12607
+ maxEffectChain: 5
12608
+ };
12609
+ function resolveLimits(overrides = {}) {
12610
+ const merged = { ...DEFAULT_LIMITS, ...overrides };
12611
+ for (const [key, value] of Object.entries(merged)) {
12612
+ if (!Number.isFinite(value) || value < 0) {
12613
+ throw new RangeError(`L\xEDmite inv\xE1lido: ${key} = ${String(value)}`);
12614
+ }
12615
+ }
12616
+ return merged;
12617
+ }
12618
+ function createLimitTracker(limits = DEFAULT_LIMITS) {
12619
+ let nodes = 0;
12620
+ let deepest = 0;
12621
+ let exceeded = false;
12622
+ return {
12623
+ visit(depth) {
12624
+ if (depth > deepest) deepest = depth;
12625
+ if (nodes >= limits.maxNodes || depth > limits.maxDepth) {
12626
+ exceeded = true;
12627
+ return false;
12628
+ }
12629
+ nodes += 1;
12630
+ return true;
12631
+ },
12632
+ get nodes() {
12633
+ return nodes;
12634
+ },
12635
+ get deepest() {
12636
+ return deepest;
12637
+ },
12638
+ get exceeded() {
12639
+ return exceeded;
12640
+ }
12641
+ };
12642
+ }
12643
+
12644
+ // src/json-renderer/kernel/NodeBoundary.tsx
12645
+ import React16 from "react";
12646
+
12647
+ // src/json-renderer/shared/errors.ts
12648
+ var JsonEngineError = class extends Error {
12649
+ constructor(code, message, path, hint) {
12650
+ super(`${code} ${path ? `en ${path}: ` : ""}${message}`);
12651
+ /** Código estable del catálogo de avisos. */
12652
+ __publicField(this, "code");
12653
+ /** Ruta del esquema donde se produjo. */
12654
+ __publicField(this, "path");
12655
+ /** Sugerencia accionable. */
12656
+ __publicField(this, "hint");
12657
+ this.name = "JsonEngineError";
12658
+ this.code = code;
12659
+ this.path = path;
12660
+ this.hint = hint;
12661
+ }
12662
+ /** Convierte el error en el aviso que consume la interfaz y el informe. */
12663
+ toIssue(severity = "error") {
12664
+ return {
12665
+ code: this.code,
12666
+ severity,
12667
+ message: this.message.replace(/^JR\d{3}\s?(en .*?: )?/, ""),
12668
+ path: this.path,
12669
+ hint: this.hint
12670
+ };
12671
+ }
12672
+ };
12673
+ function issue(code, message, path = "", options = {}) {
12674
+ return {
12675
+ code,
12676
+ severity: options.severity ?? "error",
12677
+ message,
12678
+ path,
12679
+ hint: options.hint
12680
+ };
12681
+ }
12682
+
12683
+ // src/json-renderer/kernel/NodeBoundary.tsx
12684
+ var NodeBoundary = class extends React16.Component {
12685
+ constructor() {
12686
+ super(...arguments);
12687
+ __publicField(this, "state", { failed: false });
12688
+ }
12689
+ static getDerivedStateFromError() {
12690
+ return { failed: true };
12691
+ }
12692
+ componentDidCatch(error) {
12693
+ this.props.onError?.(error, this.props.path);
12694
+ }
12695
+ render() {
12696
+ if (this.state.failed) return this.props.fallback ?? null;
12697
+ return this.props.children;
12698
+ }
12699
+ };
12700
+
12701
+ // src/json-renderer/stream/tolerantParse.ts
12702
+ function isPending(value) {
12703
+ return typeof value === "object" && value !== null && value.$pending === true;
12704
+ }
12705
+ var TRUNCATED_CONTAINERS = /* @__PURE__ */ new WeakSet();
12706
+ function finalize(value, counter) {
12707
+ if (Array.isArray(value)) {
12708
+ return value.map((item) => finalize(item, counter)).filter((item) => item !== void 0);
12709
+ }
12710
+ if (value && typeof value === "object") {
12711
+ if (isPending(value)) {
12712
+ counter.pending += 1;
12713
+ return void 0;
12714
+ }
12715
+ const out = { ...value };
12716
+ let hasPendingChild = false;
12717
+ for (const [key, nested] of Object.entries(out)) {
12718
+ const resolved = finalize(nested, counter);
12719
+ if (resolved === void 0 && isPending(nested)) {
12720
+ hasPendingChild = true;
12721
+ delete out[key];
12722
+ } else {
12723
+ out[key] = resolved;
12724
+ }
12725
+ }
12726
+ const truncated = TRUNCATED_CONTAINERS.has(value);
12727
+ if ((hasPendingChild || truncated) && "type" in out) {
12728
+ out.$status = "pending";
12729
+ }
12730
+ return out;
12731
+ }
12732
+ return value;
12733
+ }
12734
+ var WHITESPACE = /* @__PURE__ */ new Set([" ", " ", "\n", "\r"]);
12735
+ var TolerantParser = class {
12736
+ constructor(text) {
12737
+ __publicField(this, "text", text);
12738
+ __publicField(this, "index", 0);
12739
+ /** `true` cuando se detuvo porque el texto se acabó (y no por un error). */
12740
+ __publicField(this, "truncated", false);
12741
+ /** `true` cuando encontró algo que no puede interpretar. */
12742
+ __publicField(this, "broken", false);
12743
+ }
12744
+ /** Offset actual. */
12745
+ get offset() {
12746
+ return this.index;
12747
+ }
12748
+ /** `true` si el consumo se detuvo por falta de texto. */
12749
+ get isTruncated() {
12750
+ return this.truncated;
12751
+ }
12752
+ /** Salta el espacio en blanco. */
12753
+ skip() {
12754
+ while (this.index < this.text.length && WHITESPACE.has(this.text[this.index])) this.index += 1;
12755
+ }
12756
+ /** Carácter actual, o `undefined` si se acabó. */
12757
+ peek() {
12758
+ return this.text[this.index];
12759
+ }
12760
+ /** Intenta consumir un literal (`true`, `false`, `null`). */
12761
+ tryLiteral(literal) {
12762
+ if (!this.text.startsWith(literal, this.index)) return void 0;
12763
+ const end = this.index + literal.length;
12764
+ if (end > this.text.length) {
12765
+ this.index = this.text.length;
12766
+ this.truncated = true;
12767
+ return { $pending: true };
12768
+ }
12769
+ if (this.text.slice(this.index, end) !== literal) {
12770
+ const prefix = this.text.slice(this.index);
12771
+ if (literal.startsWith(prefix)) {
12772
+ this.index = this.text.length;
12773
+ this.truncated = true;
12774
+ return { $pending: true };
12775
+ }
12776
+ return void 0;
12777
+ }
12778
+ this.index = end;
12779
+ if (literal === "true") return true;
12780
+ if (literal === "false") return false;
12781
+ return null;
12782
+ }
12783
+ /** Lee una cadena. Marca pendiente si no encuentra la comilla de cierre. */
12784
+ readString() {
12785
+ this.index += 1;
12786
+ let out = "";
12787
+ while (this.index < this.text.length) {
12788
+ const char = this.text[this.index];
12789
+ if (char === "\\") {
12790
+ const next = this.text[this.index + 1];
12791
+ if (next === void 0) {
12792
+ this.index = this.text.length;
12793
+ this.truncated = true;
12794
+ return { $pending: true };
12795
+ }
12796
+ out += unescapeChar(next);
12797
+ this.index += 2;
12798
+ continue;
12799
+ }
12800
+ if (char === '"') {
12801
+ this.index += 1;
12802
+ return out;
12803
+ }
12804
+ out += char;
12805
+ this.index += 1;
12806
+ }
12807
+ this.truncated = true;
12808
+ return { $pending: true };
12809
+ }
12810
+ /** Lee un número. Devuelve el texto crudo como número, o pendiente. */
12811
+ readNumber() {
12812
+ const start = this.index;
12813
+ if (this.peek() === "-") this.index += 1;
12814
+ while (this.index < this.text.length && /[0-9.eE+-]/.test(this.text[this.index])) this.index += 1;
12815
+ const raw = this.text.slice(start, this.index);
12816
+ if (raw === "" || raw === "-") {
12817
+ this.index = this.text.length;
12818
+ this.truncated = true;
12819
+ return { $pending: true };
12820
+ }
12821
+ const value = Number(raw);
12822
+ if (Number.isNaN(value)) {
12823
+ this.broken = true;
12824
+ return { $pending: true };
12825
+ }
12826
+ return value;
12827
+ }
12828
+ /** Marca un contenedor como truncado (se cerró por falta de texto). */
12829
+ markTruncated(container) {
12830
+ this.truncated = true;
12831
+ TRUNCATED_CONTAINERS.add(container);
12832
+ }
12833
+ /** Lee un array. */
12834
+ readArray() {
12835
+ this.index += 1;
12836
+ const items = [];
12837
+ this.skip();
12838
+ if (this.peek() === "]") {
12839
+ this.index += 1;
12840
+ return items;
12841
+ }
12842
+ for (; ; ) {
12843
+ this.skip();
12844
+ if (this.peek() === void 0) {
12845
+ if (items.length === 0) {
12846
+ this.truncated = true;
12847
+ return { $pending: true };
12848
+ }
12849
+ this.markTruncated(items);
12850
+ return items;
12851
+ }
12852
+ const value = this.readValue();
12853
+ if (isPending(value)) {
12854
+ if (items.length === 0) {
12855
+ this.truncated = true;
12856
+ return { $pending: true };
12857
+ }
12858
+ this.markTruncated(items);
12859
+ return items;
12860
+ }
12861
+ items.push(value);
12862
+ this.skip();
12863
+ const char = this.peek();
12864
+ if (char === ",") {
12865
+ this.index += 1;
12866
+ continue;
12867
+ }
12868
+ if (char === "]") {
12869
+ this.index += 1;
12870
+ return items;
12871
+ }
12872
+ if (char === void 0) {
12873
+ this.markTruncated(items);
12874
+ return items;
12875
+ }
12876
+ this.broken = true;
12877
+ return items;
12878
+ }
12879
+ }
12880
+ /** Lee un objeto. */
12881
+ readObject() {
12882
+ this.index += 1;
12883
+ const out = {};
12884
+ this.skip();
12885
+ if (this.peek() === "}") {
12886
+ this.index += 1;
12887
+ return out;
12888
+ }
12889
+ for (; ; ) {
12890
+ this.skip();
12891
+ const char = this.peek();
12892
+ if (char === void 0) {
12893
+ if (!Object.keys(out).length) {
12894
+ this.truncated = true;
12895
+ return { $pending: true };
12896
+ }
12897
+ this.markTruncated(out);
12898
+ return out;
12899
+ }
12900
+ if (char !== '"') {
12901
+ this.broken = true;
12902
+ if (!Object.keys(out).length) return { $pending: true };
12903
+ this.markTruncated(out);
12904
+ return out;
12905
+ }
12906
+ const key = this.readString();
12907
+ if (isPending(key)) {
12908
+ if (!Object.keys(out).length) {
12909
+ this.truncated = true;
12910
+ return { $pending: true };
12911
+ }
12912
+ this.markTruncated(out);
12913
+ return out;
12914
+ }
12915
+ this.skip();
12916
+ if (this.peek() !== ":") {
12917
+ this.broken = this.peek() !== void 0;
12918
+ if (!Object.keys(out).length) {
12919
+ this.truncated = true;
12920
+ return { $pending: true };
12921
+ }
12922
+ this.markTruncated(out);
12923
+ return out;
12924
+ }
12925
+ this.index += 1;
12926
+ this.skip();
12927
+ const value = this.readValue();
12928
+ if (isPending(value)) {
12929
+ if (!Object.keys(out).length) {
12930
+ this.truncated = true;
12931
+ return { $pending: true };
12932
+ }
12933
+ this.markTruncated(out);
12934
+ return out;
12935
+ }
12936
+ out[key] = value;
12937
+ this.skip();
12938
+ const separator = this.peek();
12939
+ if (separator === ",") {
12940
+ this.index += 1;
12941
+ continue;
12942
+ }
12943
+ if (separator === "}") {
12944
+ this.index += 1;
12945
+ return out;
12946
+ }
12947
+ if (separator === void 0) {
12948
+ this.markTruncated(out);
12949
+ return out;
12950
+ }
12951
+ this.broken = true;
12952
+ return out;
12953
+ }
12954
+ }
12955
+ /** Lee cualquier valor. */
12956
+ readValue() {
12957
+ this.skip();
12958
+ const char = this.peek();
12959
+ if (char === void 0) {
12960
+ this.truncated = true;
12961
+ return { $pending: true };
12962
+ }
12963
+ if (char === "{") return this.readObject();
12964
+ if (char === "[") return this.readArray();
12965
+ if (char === '"') {
12966
+ const value = this.readString();
12967
+ return isPending(value) ? { $pending: true } : value;
12968
+ }
12969
+ if (char === "t" || char === "f" || char === "n") {
12970
+ const literal = char === "t" ? this.tryLiteral("true") : char === "f" ? this.tryLiteral("false") : this.tryLiteral("null");
12971
+ return literal === void 0 ? { $pending: true } : literal;
12972
+ }
12973
+ if (char === "-" || /[0-9]/.test(char)) return this.readNumber();
12974
+ this.broken = true;
12975
+ this.index = this.text.length;
12976
+ return { $pending: true };
12977
+ }
12978
+ /** Parsea el documento completo (o hasta donde llegue). */
12979
+ parse() {
12980
+ this.skip();
12981
+ if (this.peek() === void 0) {
12982
+ return { value: void 0, truncated: true, broken: false };
12983
+ }
12984
+ const value = this.readValue();
12985
+ this.skip();
12986
+ const truncated = this.truncated || this.index < this.text.length;
12987
+ return { value, truncated, broken: this.broken };
12988
+ }
12989
+ };
12990
+ function unescapeChar(char) {
12991
+ switch (char) {
12992
+ case "n":
12993
+ return "\n";
12994
+ case "t":
12995
+ return " ";
12996
+ case "r":
12997
+ return "\r";
12998
+ case "b":
12999
+ return "\b";
13000
+ case "f":
13001
+ return "\f";
13002
+ default:
13003
+ return char;
13004
+ }
13005
+ }
13006
+ function parsePartialSchema(text) {
13007
+ const parser = new TolerantParser(text);
13008
+ const { value, truncated, broken } = parser.parse();
13009
+ if (value === void 0) {
13010
+ return { tree: null, status: "pending", offset: parser.offset, broken, pendingNodes: 0 };
13011
+ }
13012
+ const counter = { pending: 0 };
13013
+ const finalized = finalize(value, counter);
13014
+ if (finalized === void 0 || finalized === null) {
13015
+ return { tree: null, status: "pending", offset: parser.offset, broken, pendingNodes: counter.pending };
13016
+ }
13017
+ const tree = finalized;
13018
+ return {
13019
+ tree,
13020
+ status: truncated || counter.pending > 0 ? "pending" : "complete",
13021
+ offset: parser.offset,
13022
+ broken,
13023
+ pendingNodes: counter.pending
13024
+ };
13025
+ }
13026
+ function isNodePending(node) {
13027
+ return node?.$status === "pending";
13028
+ }
13029
+
13030
+ // src/json-renderer/kernel/renderNode.tsx
13031
+ import React17 from "react";
13032
+
13033
+ // src/json-renderer/shared/paths.ts
13034
+ function pushPath(path, segment) {
13035
+ return [...path, segment];
13036
+ }
13037
+ function formatPath(path) {
13038
+ let out = "";
13039
+ for (const segment of path) {
13040
+ if (typeof segment === "number") out += `[${segment}]`;
13041
+ else out += out ? `.${segment}` : segment;
13042
+ }
13043
+ return out;
13044
+ }
13045
+ function parsePath(rendered) {
13046
+ if (!rendered) return [];
13047
+ return rendered.split(/\.(?![^[]*])/).flatMap((part) => {
13048
+ const match = part.match(/^([^[\]]*)((?:\[\d+\])*)$/);
13049
+ if (!match) return [part];
13050
+ const [, key, indexes] = match;
13051
+ const segments = key ? [key] : [];
13052
+ for (const index of indexes.match(/\d+/g) ?? []) segments.push(Number(index));
13053
+ return segments;
13054
+ });
13055
+ }
13056
+ function readPath(source, path) {
13057
+ let cursor = source;
13058
+ for (const segment of path) {
13059
+ if (cursor === null || typeof cursor !== "object") return void 0;
13060
+ cursor = cursor[segment];
13061
+ }
13062
+ return cursor;
13063
+ }
13064
+ function hasPath(source, path) {
13065
+ if (path.length === 0) return true;
13066
+ const parent = readPath(source, path.slice(0, -1));
13067
+ if (parent === null || typeof parent !== "object") return false;
13068
+ return Object.prototype.hasOwnProperty.call(parent, path[path.length - 1]);
13069
+ }
13070
+ function propPath(nodePath, prop) {
13071
+ return pushPath(pushPath(nodePath, "props"), prop);
13072
+ }
13073
+
13074
+ // src/json-renderer/catalog/resolve.ts
13075
+ function isSchemaReference(value) {
13076
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
13077
+ const keys = Object.keys(value);
13078
+ if (keys.length === 0) return false;
13079
+ return keys.some((key) => key === "i18n" || key.startsWith("$"));
13080
+ }
13081
+ function coerce(value, spec) {
13082
+ switch (spec.kind) {
13083
+ case "string":
13084
+ if (typeof value === "string") return value;
13085
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
13086
+ return void 0;
13087
+ case "number":
13088
+ case "integer": {
13089
+ if (typeof value === "number" && Number.isFinite(value)) {
13090
+ return spec.kind === "integer" ? Math.trunc(value) : value;
13091
+ }
13092
+ if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) {
13093
+ const parsed = Number(value);
13094
+ return spec.kind === "integer" ? Math.trunc(parsed) : parsed;
13095
+ }
13096
+ return void 0;
13097
+ }
13098
+ case "boolean":
13099
+ if (typeof value === "boolean") return value;
13100
+ if (value === "true") return true;
13101
+ if (value === "false") return false;
13102
+ return void 0;
13103
+ case "enum":
13104
+ if (typeof value !== "string") return void 0;
13105
+ return spec.values?.includes(value) ? value : void 0;
13106
+ case "array":
13107
+ return Array.isArray(value) ? value : void 0;
13108
+ case "object":
13109
+ return value && typeof value === "object" ? value : void 0;
13110
+ default:
13111
+ return value;
13112
+ }
13113
+ }
13114
+ function resolveNode(node, catalog, path) {
13115
+ const issues = [];
13116
+ const type = node.type;
13117
+ if (typeof type !== "string" || type === "") {
13118
+ issues.push(issue("JR021", "El nodo no declara `type`.", formatPath(path), { severity: "error" }));
13119
+ return { ok: false, issues };
13120
+ }
13121
+ if (isExcludedType(catalog, type)) {
13122
+ const reason = getExclusionReason(catalog, type);
13123
+ issues.push(
13124
+ issue("JR010", `El tipo \`${type}\` est\xE1 excluido del cat\xE1logo.`, formatPath(path), {
13125
+ severity: "error",
13126
+ hint: reason
13127
+ })
13128
+ );
13129
+ return { ok: false, issues };
13130
+ }
13131
+ const entry = catalog.entries[type];
13132
+ if (!entry) {
13133
+ const known = Object.keys(catalog.entries).slice(0, 8).join(", ");
13134
+ issues.push(
13135
+ issue("JR010", `El tipo \`${type}\` no est\xE1 en el cat\xE1logo.`, formatPath(path), {
13136
+ severity: "error",
13137
+ hint: `Tipos disponibles (primeros 8): ${known}\u2026`
13138
+ })
13139
+ );
13140
+ return { ok: false, issues };
13141
+ }
13142
+ const specs = entry.props ?? {};
13143
+ const props = {};
13144
+ const actions = {};
13145
+ const input = node.props ?? {};
13146
+ for (const [name, spec] of Object.entries(specs)) {
13147
+ if (spec.default !== void 0) props[name] = spec.default;
13148
+ }
13149
+ for (const [name, raw] of Object.entries(input)) {
13150
+ const forbiddenByEntry = entry.forbidden?.includes(name);
13151
+ const forbiddenGlobally = GLOBALLY_FORBIDDEN_PROPS.includes(name);
13152
+ if (forbiddenByEntry || forbiddenGlobally) {
13153
+ issues.push(
13154
+ issue("JR011", `La prop \`${name}\` est\xE1 prohibida en \`${type}\`.`, formatPath(propPath(path, name)), {
13155
+ severity: "warning",
13156
+ hint: "Los nodos React se declaran como hijos del esquema, no como props."
13157
+ })
13158
+ );
13159
+ continue;
13160
+ }
13161
+ const spec = specs[name];
13162
+ if (!spec) {
13163
+ issues.push(
13164
+ issue("JR011", `La prop \`${name}\` no est\xE1 declarada para \`${type}\`.`, formatPath(propPath(path, name)), {
13165
+ severity: "warning",
13166
+ hint: "Se ignora. Si es necesaria, a\xF1\xE1dela al cat\xE1logo con su tipo."
13167
+ })
13168
+ );
13169
+ continue;
13170
+ }
13171
+ if (spec.kind === "action") {
13172
+ actions[name] = raw;
13173
+ continue;
13174
+ }
13175
+ if (isSchemaReference(raw)) {
13176
+ props[name] = raw;
13177
+ continue;
13178
+ }
13179
+ const value = coerce(raw, spec);
13180
+ if (value === void 0) {
13181
+ issues.push(
13182
+ issue(
13183
+ "JR011",
13184
+ `Valor inv\xE1lido para \`${name}\` en \`${type}\`.`,
13185
+ formatPath(propPath(path, name)),
13186
+ { severity: "warning", hint: spec.values ? `Admitidos: ${spec.values.join(", ")}` : `Se esperaba ${spec.kind}.` }
13187
+ )
13188
+ );
13189
+ continue;
13190
+ }
13191
+ props[name] = value;
13192
+ }
13193
+ for (const [name, spec] of Object.entries(specs)) {
13194
+ if (spec.required && props[name] === void 0) {
13195
+ issues.push(
13196
+ issue("JR011", `Falta la prop obligatoria \`${name}\` en \`${type}\`.`, formatPath(propPath(path, name)), {
13197
+ severity: "error"
13198
+ })
13199
+ );
13200
+ }
13201
+ }
13202
+ if (node.children !== void 0 && !entry.children) {
13203
+ issues.push(
13204
+ issue("JR011", `\`${type}\` no acepta \`children\`.`, formatPath([...path, "children"]), {
13205
+ severity: "warning",
13206
+ hint: "Los hijos se ignoran."
13207
+ })
13208
+ );
13209
+ }
13210
+ return { ok: true, entry, props, actions, issues };
13211
+ }
13212
+
13213
+ // src/json-renderer/kernel/renderNode.tsx
13214
+ function childList(node) {
13215
+ if (!node || node.children === void 0 || node.children === null) return [];
13216
+ return Array.isArray(node.children) ? node.children : [node.children];
13217
+ }
13218
+ function renderNode(node, options) {
13219
+ const { catalog, path, issues, renderChildren } = options;
13220
+ if (!node || typeof node !== "object") {
13221
+ return null;
13222
+ }
13223
+ if (isNodePending(node)) {
13224
+ return options.pendingFallback ?? null;
13225
+ }
13226
+ const resolved = resolveNode(node, catalog, path);
13227
+ issues.push(...resolved.issues);
13228
+ if (!resolved.ok) {
13229
+ return null;
13230
+ }
13231
+ const { entry, props, actions } = resolved;
13232
+ const finalProps = {};
13233
+ for (const [name, value] of Object.entries(props)) {
13234
+ finalProps[name] = options.resolveValue ? options.resolveValue(value, path) : value;
13235
+ }
13236
+ for (const [name, action] of Object.entries(actions)) {
13237
+ const handler = options.resolveAction?.(node, name, action, path);
13238
+ if (typeof handler === "function") finalProps[name] = handler;
13239
+ }
13240
+ const content = renderChildren ? renderChildren(node, path) : null;
13241
+ const rawText = entry.text && node.text !== void 0 ? node.text : void 0;
13242
+ const text = rawText === void 0 ? void 0 : options.resolveValue ? options.resolveValue(rawText, path) : rawText;
13243
+ const children = content ?? text;
13244
+ const element = React17.createElement(
13245
+ entry.component,
13246
+ { ...finalProps, key: node.id ?? path.join("-"), id: node.id },
13247
+ children
13248
+ );
13249
+ return options.wrap ? options.wrap(node, path, element) : element;
13250
+ }
13251
+
13252
+ // src/json-renderer/kernel/partial.ts
13253
+ function auditTree(schema, limits) {
13254
+ const tracker = createLimitTracker(limits);
13255
+ const issues = [];
13256
+ let pending = 0;
13257
+ let depth = 0;
13258
+ const walk = (node, path, level) => {
13259
+ if (!node || typeof node !== "object") return;
13260
+ if (!tracker.visit(level)) return;
13261
+ if (level > depth) depth = level;
13262
+ if (isNodePending(node)) pending += 1;
13263
+ const children = childList(node);
13264
+ children.forEach((child, index) => {
13265
+ walk(child, `${path}[${index}]`, level + 1);
13266
+ });
13267
+ if (node.fallback) walk(node.fallback, `${path}.fallback`, level + 1);
13268
+ };
13269
+ const content = Array.isArray(schema.content) ? schema.content : [schema.content];
13270
+ content.forEach((node, index) => walk(node, `content[${index}]`, 0));
13271
+ if (tracker.exceeded) {
13272
+ issues.push(
13273
+ issue(
13274
+ "JR013",
13275
+ `El esquema supera el presupuesto (${tracker.nodes} nodos, profundidad ${tracker.deepest}).`,
13276
+ "content",
13277
+ {
13278
+ severity: "warning",
13279
+ hint: `M\xE1ximo configurado: ${limits.maxNodes} nodos y profundidad ${limits.maxDepth}. La parte que sobra no se pinta.`
13280
+ }
13281
+ )
13282
+ );
13283
+ }
13284
+ return { nodes: tracker.nodes, depth: tracker.deepest, pending, exceeded: tracker.exceeded, issues };
13285
+ }
13286
+ function countPendingNodes(schema) {
13287
+ if (!schema) return 0;
13288
+ let total = 0;
13289
+ const walk = (node) => {
13290
+ if (!node || typeof node !== "object") return;
13291
+ if (isNodePending(node)) total += 1;
13292
+ for (const child of childList(node)) walk(child);
13293
+ };
13294
+ const content = Array.isArray(schema.content) ? schema.content : [schema.content];
13295
+ for (const node of content) walk(node);
13296
+ return total;
13297
+ }
13298
+
13299
+ // src/json-renderer/kernel/SchemaRenderer.tsx
13300
+ import { Fragment as Fragment13, jsx as jsx75 } from "react/jsx-runtime";
13301
+ function renderTree(node, path, context, level) {
13302
+ if (!node || typeof node !== "object") return null;
13303
+ if (level > context.limits.maxDepth) return null;
13304
+ const issues = context.issues;
13305
+ if (node.id) context.nodeIds.add(node.id);
13306
+ const reportIssue = (issue2) => {
13307
+ issues.push(issue2);
13308
+ context.onIssue?.(issue2);
13309
+ };
13310
+ const issuesBefore = issues.length;
13311
+ const element = renderNode(node, {
13312
+ catalog: context.catalog,
13313
+ path,
13314
+ issues,
13315
+ resolveValue: context.resolveValue,
13316
+ resolveAction: context.resolveAction,
13317
+ pendingFallback: context.pendingFallback,
13318
+ renderChildren: (current, currentPath) => {
13319
+ const children = childList(current);
13320
+ if (children.length === 0) return void 0;
13321
+ return children.map(
13322
+ (child, index) => renderTree(child, [...currentPath, "children", index], context, level + 1)
13323
+ );
13324
+ }
13325
+ });
13326
+ for (let index = issuesBefore; index < issues.length; index += 1) {
13327
+ context.onIssue?.(issues[index]);
13328
+ }
13329
+ const fallback = node.fallback ? renderTree(node.fallback, [...path, "fallback"], context, level + 1) : context.pendingFallback ?? null;
13330
+ const wrapped = /* @__PURE__ */ jsx75(
13331
+ NodeBoundary,
13332
+ {
13333
+ path: path.join("."),
13334
+ fallback,
13335
+ onError: (error, errorPath) => reportIssue({
13336
+ code: "JR012",
13337
+ severity: "error",
13338
+ message: error.message,
13339
+ path: errorPath,
13340
+ hint: "El nodo se ha aislado; el resto de la pantalla sigue pint\xE1ndose."
13341
+ }),
13342
+ children: element
13343
+ },
13344
+ String(path.join("-"))
13345
+ );
13346
+ return wrapped;
13347
+ }
13348
+ function ITSchemaRenderer({
13349
+ schema,
13350
+ catalog = axzyCatalog,
13351
+ limits,
13352
+ resolveValue,
13353
+ resolveAction,
13354
+ pendingFallback,
13355
+ onIssue,
13356
+ className
13357
+ }) {
13358
+ const resolvedLimits = useMemo16(() => resolveLimits(limits), [limits]);
13359
+ const issues = [];
13360
+ const nodeIds = /* @__PURE__ */ new Set();
13361
+ const audit = useMemo16(
13362
+ () => schema ? auditTree(schema, resolvedLimits) : null,
13363
+ [schema, resolvedLimits]
13364
+ );
13365
+ const context = useMemo16(
13366
+ () => ({
13367
+ catalog,
13368
+ nodeIds,
13369
+ limits: resolvedLimits,
13370
+ issues,
13371
+ onIssue,
13372
+ resolveValue,
13373
+ resolveAction,
13374
+ pendingFallback
13375
+ }),
13376
+ // `issues` es un array nuevo en cada render a propósito: acumular avisos
13377
+ // entre renders duplicaría los avisos de esquemas que no han cambiado.
13378
+ // eslint-disable-next-line react-hooks/exhaustive-deps
13379
+ [catalog, resolvedLimits, onIssue, resolveValue, resolveAction, pendingFallback]
13380
+ );
13381
+ const content = schema ? (Array.isArray(schema.content) ? schema.content : [schema.content]).filter(
13382
+ (node) => Boolean(node) && typeof node === "object"
13383
+ ) : [];
13384
+ const children = content.slice(0, resolvedLimits.maxNodes).map((node, index) => renderTree(node, ["content", index], context, 0)).filter(Boolean);
13385
+ const collected = [...audit?.issues ?? [], ...issues];
13386
+ const signature = collected.map((issue2) => `${issue2.code}:${issue2.path}`).join("|");
13387
+ const reported = useRef23("");
13388
+ useEffect18(() => {
13389
+ const all = [...collected];
13390
+ for (const id of nodeIds) {
13391
+ if (!document.getElementById(id)) {
13392
+ all.push({
13393
+ code: "JR014",
13394
+ severity: "warning",
13395
+ message: `El \`id\` "${id}" no lleg\xF3 al DOM.`,
13396
+ path: id,
13397
+ hint: "El componente no reenv\xEDa props al elemento. Pon el id en un nodo que s\xED lo haga (por ejemplo ITText) o en un contenedor del host."
13398
+ });
13399
+ }
13400
+ }
13401
+ const firma = all.map((issue2) => `${issue2.code}:${issue2.path}`).join("|");
13402
+ if (!onIssue || reported.current === firma) return;
13403
+ reported.current = firma;
13404
+ for (const issue2 of all) onIssue(issue2);
13405
+ }, [signature, onIssue]);
13406
+ if (!schema || children.length === 0) return null;
13407
+ return className ? /* @__PURE__ */ jsx75("div", { className, children }) : /* @__PURE__ */ jsx75(Fragment13, { children });
13408
+ }
13409
+
13410
+ // src/json-renderer/validation/validate.ts
13411
+ var CURRENT_SCHEMA_VERSION = 1;
13412
+ function validateNodes(node, path, catalog, errors, warnings) {
13413
+ if (!node || typeof node !== "object") {
13414
+ errors.push(issue("JR021", "El nodo no es un objeto.", formatPath(path), { severity: "error" }));
13415
+ return 0;
13416
+ }
13417
+ if (isNodePending(node)) return 1;
13418
+ const resolved = resolveNode(node, catalog, path);
13419
+ for (const item of resolved.issues) {
13420
+ (item.severity === "error" ? errors : warnings).push(item);
13421
+ }
13422
+ let pending = 0;
13423
+ const children = node.children === void 0 ? [] : Array.isArray(node.children) ? node.children : [node.children];
13424
+ children.forEach((child, index) => {
13425
+ pending += validateNodes(child, [...path, "children", index], catalog, errors, warnings);
13426
+ });
13427
+ return pending;
13428
+ }
13429
+ function validateSchema(schema, options = {}) {
13430
+ const catalog = options.catalog ?? axzyCatalog;
13431
+ const maxVersion = options.maxVersion ?? CURRENT_SCHEMA_VERSION;
13432
+ const errors = [];
13433
+ const warnings = [];
13434
+ if (schema === null || schema === void 0) {
13435
+ return { verdict: "invalid", errors: [issue("JR020", "No hay esquema que validar.", "")], warnings, pendingNodes: 0 };
13436
+ }
13437
+ if (typeof schema !== "object" || Array.isArray(schema)) {
13438
+ return {
13439
+ verdict: "invalid",
13440
+ errors: [issue("JR020", "El esquema debe ser un objeto.", "", { severity: "error" })],
13441
+ warnings,
13442
+ pendingNodes: 0
13443
+ };
13444
+ }
13445
+ const candidate = schema;
13446
+ if (candidate.$schema !== void 0 && candidate.$schema !== "axzy/screen") {
13447
+ errors.push(
13448
+ issue("JR020", `El formato declarado no es \`axzy/screen\`.`, "$schema", {
13449
+ severity: "error",
13450
+ hint: 'Usa `$schema: "axzy/screen"` o quita la propiedad.'
13451
+ })
13452
+ );
13453
+ }
13454
+ if (candidate.version === void 0) {
13455
+ errors.push(issue("JR020", "Falta `version` en el esquema.", "version", { severity: "error" }));
13456
+ } else if (typeof candidate.version !== "number" || !Number.isInteger(candidate.version)) {
13457
+ errors.push(issue("JR020", "`version` debe ser un entero.", "version", { severity: "error" }));
13458
+ } else if (candidate.version > maxVersion) {
13459
+ errors.push(
13460
+ issue("JR020", `La versi\xF3n ${candidate.version} es m\xE1s nueva que la soportada (${maxVersion}).`, "version", {
13461
+ severity: "error",
13462
+ hint: "Actualiza el motor o migra el esquema."
13463
+ })
13464
+ );
13465
+ }
13466
+ if (typeof candidate.id !== "string" || candidate.id.trim() === "") {
13467
+ errors.push(issue("JR020", "Falta `id` en el esquema.", "id", { severity: "error" }));
13468
+ }
13469
+ if (candidate.content === void 0) {
13470
+ errors.push(issue("JR020", "El esquema no declara `content`.", "content", { severity: "error" }));
13471
+ return { verdict: "invalid", errors, warnings, pendingNodes: 0, version: candidate.version };
13472
+ }
13473
+ const content = Array.isArray(candidate.content) ? candidate.content : [candidate.content];
13474
+ if (content.length === 0) {
13475
+ warnings.push(
13476
+ issue("JR021", "`content` est\xE1 vac\xEDo: la pantalla se pinta sin nodos.", "content", { severity: "warning" })
13477
+ );
13478
+ }
13479
+ let pendingNodes = 0;
13480
+ content.map((node, index) => ({ node, index })).filter(({ node }) => node !== void 0 && node !== null).forEach(({ node, index }) => {
13481
+ pendingNodes += validateNodes(node, ["content", index], catalog, errors, warnings);
13482
+ });
13483
+ const verdict = errors.length > 0 ? "invalid" : pendingNodes > 0 ? "partial" : "valid";
13484
+ return { verdict, errors, warnings, pendingNodes, version: candidate.version };
13485
+ }
13486
+
13487
+ // src/json-renderer/validation/migrate.ts
13488
+ var DEFAULT_MIGRATIONS = {};
13489
+ function migrateSchema(schema, targetVersion, migrations = DEFAULT_MIGRATIONS) {
13490
+ const from = typeof schema.version === "number" ? schema.version : 0;
13491
+ const issues = [];
13492
+ if (from === targetVersion) {
13493
+ return { schema, migrated: false, from, to: targetVersion, issues };
13494
+ }
13495
+ if (from > targetVersion) {
13496
+ issues.push(
13497
+ issue("JR020", `El esquema es de una versi\xF3n posterior (${from}) a la del motor (${targetVersion}).`, "version", {
13498
+ severity: "error",
13499
+ hint: "Actualiza el motor; no se puede degradar un esquema."
13500
+ })
13501
+ );
13502
+ return { schema, migrated: false, from, to: targetVersion, issues };
13503
+ }
13504
+ let current = schema;
13505
+ let version = from;
13506
+ while (version < targetVersion) {
13507
+ const migration = migrations[version];
13508
+ if (!migration) {
13509
+ issues.push(
13510
+ issue("JR070", `No hay migraci\xF3n registrada de la versi\xF3n ${version} a la ${version + 1}.`, "version", {
13511
+ severity: "error",
13512
+ hint: "Registra la migraci\xF3n en `migrations` o guarda el esquema en la versi\xF3n actual."
13513
+ })
13514
+ );
13515
+ return { schema: current, migrated: false, from, to: version, issues };
13516
+ }
13517
+ current = { ...migration(current), version: version + 1 };
13518
+ version += 1;
13519
+ }
13520
+ return { schema: current, migrated: version !== from, from, to: version, issues };
13521
+ }
13522
+
13523
+ // src/json-renderer/vocabulary/buildContract.ts
13524
+ var RULES = [
13525
+ 'Emite SOLO JSON v\xE1lido con la forma: { $schema: "axzy/screen", version, id, content }.',
13526
+ "`content` es un nodo o un array de nodos; cada nodo necesita `type` del cat\xE1logo.",
13527
+ "Usa solo props declaradas para ese `type`; el resto se ignora y se avisa.",
13528
+ "Los hijos se expresan con `children` (nodos) y los textos con `text`, nunca con props de nodo React.",
13529
+ 'Las acciones se declaran por nombre: `"onClick": { "action": "nombre.registrado" }`. No hay c\xF3digo en el JSON.',
13530
+ "Prohibido: HTML crudo, URLs, fetch, expresiones JS y props como icon/actions/render.",
13531
+ 'Los textos visibles deben ser claves de i18n: { "i18n": "namespace.clave" }.'
13532
+ ];
13533
+ function buildMinimal(entry) {
13534
+ const props = {};
13535
+ for (const [name, spec] of Object.entries(entry.props ?? {})) {
13536
+ if (!spec.required) continue;
13537
+ props[name] = sampleValue(name, spec);
13538
+ }
13539
+ const node = { type: entry.type };
13540
+ if (Object.keys(props).length > 0) node.props = props;
13541
+ if (entry.text) node.text = "Texto";
13542
+ return node;
13543
+ }
13544
+ function sampleValue(name, spec) {
13545
+ if (spec.values?.length) return spec.values[0];
13546
+ if (spec.kind === "number" || spec.kind === "integer") return 1;
13547
+ if (spec.kind === "boolean") return false;
13548
+ if (spec.kind === "i18n") return { i18n: `ejemplo.${name}` };
13549
+ return name === "src" ? "/imagen.png" : `${name}`;
13550
+ }
13551
+ function buildVocabularyContract(catalog = axzyCatalog, schemaVersion = CURRENT_SCHEMA_VERSION) {
13552
+ const components2 = Object.values(catalog.entries).map((entry) => ({
13553
+ type: entry.type,
13554
+ summary: entry.summary,
13555
+ children: Boolean(entry.children),
13556
+ text: Boolean(entry.text),
13557
+ props: Object.entries(entry.props ?? {}).map(([name, spec]) => ({
13558
+ name,
13559
+ kind: spec.kind,
13560
+ required: Boolean(spec.required),
13561
+ values: spec.values ? [...spec.values] : void 0,
13562
+ default: spec.default,
13563
+ doc: spec.doc
13564
+ })),
13565
+ forbidden: [...entry.forbidden ?? []],
13566
+ minimal: buildMinimal(entry)
13567
+ })).sort((a, b) => a.type.localeCompare(b.type));
13568
+ return {
13569
+ $schema: "axzy/vocabulary",
13570
+ schemaVersion,
13571
+ rules: RULES,
13572
+ components: components2,
13573
+ excluded: catalog.excluded ?? {}
13574
+ };
13575
+ }
13576
+ function formatVocabularyForPrompt(contract) {
13577
+ const lines = [
13578
+ `# Contrato de vocabulario AXZY (formato v${contract.schemaVersion})`,
13579
+ "",
13580
+ "Reglas:",
13581
+ ...contract.rules.map((rule) => `- ${rule}`),
13582
+ "",
13583
+ "Componentes:"
13584
+ ];
13585
+ for (const component of contract.components) {
13586
+ const props = component.props.map((prop) => {
13587
+ const parts = [`${prop.name}:${prop.kind}${prop.required ? "*" : ""}`];
13588
+ if (prop.values?.length) parts.push(`(${prop.values.join("|")})`);
13589
+ return parts.join(" ");
13590
+ }).join(", ");
13591
+ lines.push(`- ${component.type}${component.summary ? ` \u2014 ${component.summary}` : ""}`);
13592
+ if (props) lines.push(` props: ${props}`);
13593
+ if (component.children) lines.push(" children: s\xED");
13594
+ if (component.text) lines.push(" text: s\xED");
13595
+ lines.push(` m\xEDnimo: ${JSON.stringify(component.minimal)}`);
13596
+ }
13597
+ return lines.join("\n");
13598
+ }
13599
+
12152
13600
  // src/components/organisms/dropfile/dropfile.tsx
12153
- import { useState as useState37, useEffect as useEffect18 } from "react";
13601
+ import { useState as useState37, useEffect as useEffect19 } from "react";
12154
13602
  import { useDropzone } from "react-dropzone";
12155
13603
  import clsx54 from "clsx";
12156
13604
 
@@ -12180,7 +13628,7 @@ var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
12180
13628
  })(UploadStatus || {});
12181
13629
 
12182
13630
  // src/components/organisms/dropfile/dropfile.tsx
12183
- import { Fragment as Fragment13, jsx as jsx74, jsxs as jsxs54 } from "react/jsx-runtime";
13631
+ import { Fragment as Fragment14, jsx as jsx76, jsxs as jsxs54 } from "react/jsx-runtime";
12184
13632
  var ITDropfile = ({
12185
13633
  onFileSelect,
12186
13634
  onCancel,
@@ -12205,7 +13653,7 @@ var ITDropfile = ({
12205
13653
  const [internalUploadStatus, setInternalUploadStatus] = useState37(
12206
13654
  initialPreviewUrl ? "subido" /* UPLOADED */ : "pendiente" /* PENDING */
12207
13655
  );
12208
- useEffect18(() => {
13656
+ useEffect19(() => {
12209
13657
  if (initialPreviewUrl && !selectedFile) {
12210
13658
  setImagePreview(initialPreviewUrl);
12211
13659
  if (externalStatus === void 0) setInternalUploadStatus("subido" /* UPLOADED */);
@@ -12321,8 +13769,8 @@ var ITDropfile = ({
12321
13769
  };
12322
13770
  const { label, color, dotColor } = config2[status];
12323
13771
  return /* @__PURE__ */ jsxs54("div", { className: `inline-flex items-center gap-2 px-2.5 py-1 rounded-full border ${color}`, children: [
12324
- /* @__PURE__ */ jsx74("div", { className: `w-2 h-2 rounded-full ${dotColor}` }),
12325
- /* @__PURE__ */ jsx74(ITText, { as: "span", className: "text-xs font-medium flex items-center gap-1.5", children: label })
13772
+ /* @__PURE__ */ jsx76("div", { className: `w-2 h-2 rounded-full ${dotColor}` }),
13773
+ /* @__PURE__ */ jsx76(ITText, { as: "span", className: "text-xs font-medium flex items-center gap-1.5", children: label })
12326
13774
  ] });
12327
13775
  };
12328
13776
  const onDrop = (acceptedFiles) => {
@@ -12354,12 +13802,12 @@ var ITDropfile = ({
12354
13802
  accept: getAcceptedFileTypes(),
12355
13803
  maxFiles: 1
12356
13804
  });
12357
- useEffect18(() => {
13805
+ useEffect19(() => {
12358
13806
  const renderPDF = async () => {
12359
13807
  };
12360
13808
  renderPDF();
12361
13809
  }, [selectedFile, fileType]);
12362
- useEffect18(() => {
13810
+ useEffect19(() => {
12363
13811
  return () => {
12364
13812
  if (imagePreview) {
12365
13813
  URL.revokeObjectURL(imagePreview);
@@ -12396,7 +13844,7 @@ var ITDropfile = ({
12396
13844
  const handleDelete = () => {
12397
13845
  handleCancel();
12398
13846
  };
12399
- useEffect18(() => {
13847
+ useEffect19(() => {
12400
13848
  if (view === "button" && isConfirmed && uploadStatus === "subido" /* UPLOADED */) {
12401
13849
  const timeout = setTimeout(() => {
12402
13850
  setIsModalOpen(false);
@@ -12425,9 +13873,9 @@ var ITDropfile = ({
12425
13873
  ")"
12426
13874
  ] })
12427
13875
  ] }),
12428
- showStatusBadge && selectedFile && /* @__PURE__ */ jsx74(StatusBadge, { status: uploadStatus })
13876
+ showStatusBadge && selectedFile && /* @__PURE__ */ jsx76(StatusBadge, { status: uploadStatus })
12429
13877
  ] });
12430
- const dropZoneOrPreview = /* @__PURE__ */ jsx74(Fragment13, { children: !selectedFile && !imagePreview ? /* @__PURE__ */ jsxs54(
13878
+ const dropZoneOrPreview = /* @__PURE__ */ jsx76(Fragment14, { children: !selectedFile && !imagePreview ? /* @__PURE__ */ jsxs54(
12431
13879
  "div",
12432
13880
  {
12433
13881
  ...getRootProps(),
@@ -12437,29 +13885,29 @@ var ITDropfile = ({
12437
13885
  ${isDragActive ? "border-primary-500 bg-primary-50 scale-[1.01]" : "border-secondary-300 bg-white hover:border-primary-400 hover:bg-secondary-50"}
12438
13886
  `,
12439
13887
  children: [
12440
- /* @__PURE__ */ jsx74("input", { ...getInputProps() }),
12441
- /* @__PURE__ */ jsx74("div", { className: `mb-3 p-3 rounded-full transition-colors duration-300 ${isDragActive ? "bg-primary-100" : "bg-secondary-100 group-hover:bg-primary-50"}`, children: /* @__PURE__ */ jsx74(
13888
+ /* @__PURE__ */ jsx76("input", { ...getInputProps() }),
13889
+ /* @__PURE__ */ jsx76("div", { className: `mb-3 p-3 rounded-full transition-colors duration-300 ${isDragActive ? "bg-primary-100" : "bg-secondary-100 group-hover:bg-primary-50"}`, children: /* @__PURE__ */ jsx76(
12442
13890
  "svg",
12443
13891
  {
12444
13892
  className: `w-6 h-6 transition-colors duration-300 ${isDragActive ? "text-primary-600" : "text-secondary-400 group-hover:text-primary-500"}`,
12445
13893
  fill: "none",
12446
13894
  viewBox: "0 0 24 24",
12447
13895
  stroke: "currentColor",
12448
- children: /* @__PURE__ */ jsx74("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" })
13896
+ children: /* @__PURE__ */ jsx76("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" })
12449
13897
  }
12450
13898
  ) }),
12451
- /* @__PURE__ */ jsx74("div", { className: "text-center space-y-1", children: /* @__PURE__ */ jsx74(ITText, { as: "p", className: `text-sm font-medium transition-colors duration-300 ${isDragActive ? "text-primary-700" : "text-secondary-700"}`, children: isDragActive ? t("dropfile.dropHere") : t("dropfile.clickOrDrag") }) })
13899
+ /* @__PURE__ */ jsx76("div", { className: "text-center space-y-1", children: /* @__PURE__ */ jsx76(ITText, { as: "p", className: `text-sm font-medium transition-colors duration-300 ${isDragActive ? "text-primary-700" : "text-secondary-700"}`, children: isDragActive ? t("dropfile.dropHere") : t("dropfile.clickOrDrag") }) })
12452
13900
  ]
12453
13901
  }
12454
13902
  ) : /* @__PURE__ */ jsxs54("div", { className: "w-full bg-white border border-secondary-200 rounded-xl shadow-sm overflow-hidden animate-fade-in", children: [
12455
- /* @__PURE__ */ jsx74("div", { className: "flex items-center justify-between p-3 bg-secondary-50 border-b border-secondary-100", children: /* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-3 overflow-hidden", children: [
12456
- /* @__PURE__ */ jsx74("div", { className: "flex-shrink-0 w-8 h-8 rounded-lg bg-primary-100 flex items-center justify-center text-primary-600", children: selectedFile && fileType?.startsWith("image/") || !selectedFile && imagePreview ? /* @__PURE__ */ jsx74("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx74("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }) : /* @__PURE__ */ jsx74("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx74("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) }),
13903
+ /* @__PURE__ */ jsx76("div", { className: "flex items-center justify-between p-3 bg-secondary-50 border-b border-secondary-100", children: /* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-3 overflow-hidden", children: [
13904
+ /* @__PURE__ */ jsx76("div", { className: "flex-shrink-0 w-8 h-8 rounded-lg bg-primary-100 flex items-center justify-center text-primary-600", children: selectedFile && fileType?.startsWith("image/") || !selectedFile && imagePreview ? /* @__PURE__ */ jsx76("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx76("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }) : /* @__PURE__ */ jsx76("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx76("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) }),
12457
13905
  /* @__PURE__ */ jsxs54("div", { className: "min-w-0", children: [
12458
- /* @__PURE__ */ jsx74(ITText, { as: "p", className: "text-xs font-medium text-secondary-900 truncate", title: selectedFile?.name || t("dropfile.imageLoaded"), children: selectedFile?.name || t("dropfile.imageLoaded") }),
12459
- /* @__PURE__ */ jsx74(ITText, { as: "p", className: "text-[10px] text-secondary-500", children: selectedFile ? (selectedFile.size / 1024 / 1024).toFixed(2) + " MB" : "" })
13906
+ /* @__PURE__ */ jsx76(ITText, { as: "p", className: "text-xs font-medium text-secondary-900 truncate", title: selectedFile?.name || t("dropfile.imageLoaded"), children: selectedFile?.name || t("dropfile.imageLoaded") }),
13907
+ /* @__PURE__ */ jsx76(ITText, { as: "p", className: "text-[10px] text-secondary-500", children: selectedFile ? (selectedFile.size / 1024 / 1024).toFixed(2) + " MB" : "" })
12460
13908
  ] })
12461
13909
  ] }) }),
12462
- /* @__PURE__ */ jsx74("div", { className: clsx54("relative bg-secondary-100 flex items-center justify-center", !contentClassName ? "max-h-[200px] min-h-[100px] overflow-auto" : contentClassName), children: selectedFile && fileType?.startsWith("image/") || !selectedFile && imagePreview ? /* @__PURE__ */ jsx74(
13910
+ /* @__PURE__ */ jsx76("div", { className: clsx54("relative bg-secondary-100 flex items-center justify-center", !contentClassName ? "max-h-[200px] min-h-[100px] overflow-auto" : contentClassName), children: selectedFile && fileType?.startsWith("image/") || !selectedFile && imagePreview ? /* @__PURE__ */ jsx76(
12463
13911
  "img",
12464
13912
  {
12465
13913
  src: imagePreview,
@@ -12467,11 +13915,11 @@ var ITDropfile = ({
12467
13915
  className: "w-full h-full object-contain max-h-[200px]"
12468
13916
  }
12469
13917
  ) : /* @__PURE__ */ jsxs54("div", { className: "py-8 flex flex-col items-center text-secondary-400", children: [
12470
- /* @__PURE__ */ jsx74("svg", { className: "w-10 h-10 mb-2 opacity-50", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx74("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
12471
- /* @__PURE__ */ jsx74(ITText, { as: "span", className: "text-xs", children: t("dropfile.noPreview") })
13918
+ /* @__PURE__ */ jsx76("svg", { className: "w-10 h-10 mb-2 opacity-50", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx76("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
13919
+ /* @__PURE__ */ jsx76(ITText, { as: "span", className: "text-xs", children: t("dropfile.noPreview") })
12472
13920
  ] }) }),
12473
- /* @__PURE__ */ jsx74("div", { className: "px-3 py-2 bg-white border-t border-secondary-100 flex justify-end gap-2", children: !isConfirmed ? /* @__PURE__ */ jsxs54(Fragment13, { children: [
12474
- /* @__PURE__ */ jsx74(
13921
+ /* @__PURE__ */ jsx76("div", { className: "px-3 py-2 bg-white border-t border-secondary-100 flex justify-end gap-2", children: !isConfirmed ? /* @__PURE__ */ jsxs54(Fragment14, { children: [
13922
+ /* @__PURE__ */ jsx76(
12475
13923
  ITButton,
12476
13924
  {
12477
13925
  type: "button",
@@ -12479,10 +13927,10 @@ var ITDropfile = ({
12479
13927
  color: "secondary",
12480
13928
  size: "sm",
12481
13929
  onClick: handleCancel,
12482
- children: /* @__PURE__ */ jsx74(ITText, { children: t("common.cancel") })
13930
+ children: /* @__PURE__ */ jsx76(ITText, { children: t("common.cancel") })
12483
13931
  }
12484
13932
  ),
12485
- /* @__PURE__ */ jsx74(
13933
+ /* @__PURE__ */ jsx76(
12486
13934
  ITButton,
12487
13935
  {
12488
13936
  type: "button",
@@ -12491,8 +13939,8 @@ var ITDropfile = ({
12491
13939
  size: "sm",
12492
13940
  onClick: handleConfirm,
12493
13941
  children: /* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-2", children: [
12494
- /* @__PURE__ */ jsx74(ITText, { children: t("common.confirm") }),
12495
- /* @__PURE__ */ jsx74("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx74("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })
13942
+ /* @__PURE__ */ jsx76(ITText, { children: t("common.confirm") }),
13943
+ /* @__PURE__ */ jsx76("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx76("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })
12496
13944
  ] })
12497
13945
  }
12498
13946
  )
@@ -12505,12 +13953,12 @@ var ITDropfile = ({
12505
13953
  size: "sm",
12506
13954
  onClick: handleDelete,
12507
13955
  children: [
12508
- /* @__PURE__ */ jsx74("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx74("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
12509
- /* @__PURE__ */ jsx74(ITText, { children: t("common.delete") })
13956
+ /* @__PURE__ */ jsx76("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx76("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
13957
+ /* @__PURE__ */ jsx76(ITText, { children: t("common.delete") })
12510
13958
  ]
12511
13959
  }
12512
13960
  ) }),
12513
- uploadStatus === "subiendo" /* UPLOADING */ && /* @__PURE__ */ jsx74("div", { className: "px-4 pb-2", children: /* @__PURE__ */ jsx74("div", { className: "w-full bg-secondary-200 rounded-full h-1.5", children: /* @__PURE__ */ jsx74(
13961
+ uploadStatus === "subiendo" /* UPLOADING */ && /* @__PURE__ */ jsx76("div", { className: "px-4 pb-2", children: /* @__PURE__ */ jsx76("div", { className: "w-full bg-secondary-200 rounded-full h-1.5", children: /* @__PURE__ */ jsx76(
12514
13962
  "div",
12515
13963
  {
12516
13964
  className: "bg-primary-600 h-1.5 rounded-full transition-all duration-1000 ease-out",
@@ -12524,7 +13972,7 @@ var ITDropfile = ({
12524
13972
  if (view === "button") {
12525
13973
  const hasFile = Boolean(selectedFile || imagePreview);
12526
13974
  return /* @__PURE__ */ jsxs54("div", { className: clsx54("inline-block", containerClassName), children: [
12527
- /* @__PURE__ */ jsx74(
13975
+ /* @__PURE__ */ jsx76(
12528
13976
  ITButton,
12529
13977
  {
12530
13978
  type: "button",
@@ -12533,13 +13981,13 @@ var ITDropfile = ({
12533
13981
  size: "sm",
12534
13982
  onClick: () => setIsModalOpen(true),
12535
13983
  children: /* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-2 max-w-[220px]", children: [
12536
- /* @__PURE__ */ jsx74("svg", { className: "w-4 h-4 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx74("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
12537
- /* @__PURE__ */ jsx74(ITText, { className: "truncate", children: selectedFile?.name || (hasFile ? t("dropfile.fileLoaded") : buttonLabel ?? t("dropfile.upload")) }),
12538
- showStatusBadge && hasFile && /* @__PURE__ */ jsx74(StatusBadge, { status: uploadStatus })
13984
+ /* @__PURE__ */ jsx76("svg", { className: "w-4 h-4 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx76("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
13985
+ /* @__PURE__ */ jsx76(ITText, { className: "truncate", children: selectedFile?.name || (hasFile ? t("dropfile.fileLoaded") : buttonLabel ?? t("dropfile.upload")) }),
13986
+ showStatusBadge && hasFile && /* @__PURE__ */ jsx76(StatusBadge, { status: uploadStatus })
12539
13987
  ] })
12540
13988
  }
12541
13989
  ),
12542
- /* @__PURE__ */ jsx74(ITDialog, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), title: modalTitle ?? buttonLabel ?? t("dropfile.upload"), children: /* @__PURE__ */ jsxs54("div", { className: "w-full transition-all duration-300", children: [
13990
+ /* @__PURE__ */ jsx76(ITDialog, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), title: modalTitle ?? buttonLabel ?? t("dropfile.upload"), children: /* @__PURE__ */ jsxs54("div", { className: "w-full transition-all duration-300", children: [
12543
13991
  headerRow,
12544
13992
  dropZoneOrPreview
12545
13993
  ] }) })
@@ -12558,8 +14006,8 @@ import clsx55 from "clsx";
12558
14006
 
12559
14007
  // src/components/organisms/topbar/topbar.tsx
12560
14008
  import { FaUserCircle as FaUserCircle2, FaBars } from "react-icons/fa";
12561
- import { useRef as useRef23, useState as useState38 } from "react";
12562
- import { jsx as jsx75, jsxs as jsxs55 } from "react/jsx-runtime";
14009
+ import { useRef as useRef24, useState as useState38 } from "react";
14010
+ import { jsx as jsx77, jsxs as jsxs55 } from "react/jsx-runtime";
12563
14011
  function ITTopBar({
12564
14012
  logo,
12565
14013
  logoText,
@@ -12577,9 +14025,9 @@ function ITTopBar({
12577
14025
  const { t } = useITTranslation();
12578
14026
  const initials = (userMenu?.userName ?? "").trim().split(/\s+/).slice(0, 2).map((word) => word.charAt(0).toUpperCase()).join("");
12579
14027
  const [isUserMenuOpen, setIsUserMenuOpen] = useState38(false);
12580
- const userMenuRef = useRef23(null);
14028
+ const userMenuRef = useRef24(null);
12581
14029
  useClickOutside_default(userMenuRef, () => setIsUserMenuOpen(false));
12582
- return /* @__PURE__ */ jsx75(
14030
+ return /* @__PURE__ */ jsx77(
12583
14031
  "header",
12584
14032
  {
12585
14033
  className: `sticky top-0 z-40 transition-all duration-300 ${flat ? "" : "backdrop-blur-md"}`,
@@ -12590,7 +14038,7 @@ function ITTopBar({
12590
14038
  },
12591
14039
  children: /* @__PURE__ */ jsxs55("div", { className: `flex items-center justify-between px-6 lg:px-8 ${flat ? "h-[64px]" : "h-[72px]"}`, children: [
12592
14040
  /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-5", children: [
12593
- showMobileMenuButton && /* @__PURE__ */ jsx75(
14041
+ showMobileMenuButton && /* @__PURE__ */ jsx77(
12594
14042
  "button",
12595
14043
  {
12596
14044
  type: "button",
@@ -12602,12 +14050,12 @@ function ITTopBar({
12602
14050
  onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "var(--it-topbar-user-hover, #f1f5f9)",
12603
14051
  onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
12604
14052
  onClick: onToggleMobileMenu,
12605
- children: /* @__PURE__ */ jsx75(FaBars, { className: "w-[1.125rem] h-[1.125rem]" })
14053
+ children: /* @__PURE__ */ jsx77(FaBars, { className: "w-[1.125rem] h-[1.125rem]" })
12606
14054
  }
12607
14055
  ),
12608
14056
  /* @__PURE__ */ jsxs55("div", { className: `items-center gap-3 ${hideBrandOnDesktop ? "flex lg:hidden" : "flex"}`, children: [
12609
- logo && /* @__PURE__ */ jsx75("div", { className: "flex-shrink-0 drop-shadow-sm", children: logo }),
12610
- logoText && /* @__PURE__ */ jsx75(
14057
+ logo && /* @__PURE__ */ jsx77("div", { className: "flex-shrink-0 drop-shadow-sm", children: logo }),
14058
+ logoText && /* @__PURE__ */ jsx77(
12611
14059
  ITText,
12612
14060
  {
12613
14061
  as: "span",
@@ -12617,7 +14065,7 @@ function ITTopBar({
12617
14065
  }
12618
14066
  )
12619
14067
  ] }),
12620
- navItems && navItems.length > 0 && /* @__PURE__ */ jsx75("nav", { className: "hidden md:flex ml-8 space-x-1 border-l pl-8", style: { borderColor: "var(--it-topbar-border, rgba(15, 23, 42, 0.06))" }, children: navItems.map((item) => /* @__PURE__ */ jsx75(
14068
+ navItems && navItems.length > 0 && /* @__PURE__ */ jsx77("nav", { className: "hidden md:flex ml-8 space-x-1 border-l pl-8", style: { borderColor: "var(--it-topbar-border, rgba(15, 23, 42, 0.06))" }, children: navItems.map((item) => /* @__PURE__ */ jsx77(
12621
14069
  "button",
12622
14070
  {
12623
14071
  onClick: () => onNavItemClick?.(item.id),
@@ -12632,14 +14080,14 @@ function ITTopBar({
12632
14080
  e.currentTarget.style.backgroundColor = "transparent";
12633
14081
  },
12634
14082
  children: /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-2", children: [
12635
- item.icon && /* @__PURE__ */ jsx75("span", { className: "opacity-70", children: item.icon }),
12636
- /* @__PURE__ */ jsx75(ITText, { as: "span", children: item.label })
14083
+ item.icon && /* @__PURE__ */ jsx77("span", { className: "opacity-70", children: item.icon }),
14084
+ /* @__PURE__ */ jsx77(ITText, { as: "span", children: item.label })
12637
14085
  ] })
12638
14086
  },
12639
14087
  item.id
12640
14088
  )) })
12641
14089
  ] }),
12642
- centerContent && /* @__PURE__ */ jsx75("div", { className: `hidden lg:flex flex-1 min-w-0 items-center ${hideBrandOnDesktop ? "justify-start pr-4" : "justify-center px-4"}`, children: /* @__PURE__ */ jsx75("div", { className: "w-full max-w-[420px]", children: centerContent }) }),
14090
+ centerContent && /* @__PURE__ */ jsx77("div", { className: `hidden lg:flex flex-1 min-w-0 items-center ${hideBrandOnDesktop ? "justify-start pr-4" : "justify-center px-4"}`, children: /* @__PURE__ */ jsx77("div", { className: "w-full max-w-[420px]", children: centerContent }) }),
12643
14091
  (children || userMenu) && /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-2", children: [
12644
14092
  children,
12645
14093
  userMenu && /* @__PURE__ */ jsxs55("div", { className: "relative", children: [
@@ -12660,14 +14108,14 @@ function ITTopBar({
12660
14108
  onClick: () => setIsUserMenuOpen(!isUserMenuOpen),
12661
14109
  children: [
12662
14110
  /* @__PURE__ */ jsxs55("div", { className: "relative", children: [
12663
- userMenu.userImage ? /* @__PURE__ */ jsx75(
14111
+ userMenu.userImage ? /* @__PURE__ */ jsx77(
12664
14112
  "img",
12665
14113
  {
12666
14114
  className: "w-9 h-9 rounded-full object-cover ring-2 ring-white shadow-sm",
12667
14115
  src: userMenu.userImage,
12668
14116
  alt: t("common.userAvatar")
12669
14117
  }
12670
- ) : flat && initials ? /* @__PURE__ */ jsx75(
14118
+ ) : flat && initials ? /* @__PURE__ */ jsx77(
12671
14119
  "div",
12672
14120
  {
12673
14121
  "aria-hidden": "true",
@@ -12678,11 +14126,11 @@ function ITTopBar({
12678
14126
  },
12679
14127
  children: initials
12680
14128
  }
12681
- ) : /* @__PURE__ */ jsx75("div", { className: "w-9 h-9 rounded-full bg-slate-100 flex items-center justify-center ring-2 ring-white shadow-sm", children: /* @__PURE__ */ jsx75(FaUserCircle2, { className: "w-6 h-6", style: { color: "var(--it-topbar-icon, #94a3b8)" } }) }),
12682
- !flat && /* @__PURE__ */ jsx75("div", { className: "absolute bottom-0 right-0 w-2.5 h-2.5 bg-green-500 border-2 border-white rounded-full" })
14129
+ ) : /* @__PURE__ */ jsx77("div", { className: "w-9 h-9 rounded-full bg-slate-100 flex items-center justify-center ring-2 ring-white shadow-sm", children: /* @__PURE__ */ jsx77(FaUserCircle2, { className: "w-6 h-6", style: { color: "var(--it-topbar-icon, #94a3b8)" } }) }),
14130
+ !flat && /* @__PURE__ */ jsx77("div", { className: "absolute bottom-0 right-0 w-2.5 h-2.5 bg-green-500 border-2 border-white rounded-full" })
12683
14131
  ] }),
12684
14132
  /* @__PURE__ */ jsxs55("div", { className: `hidden sm:flex flex-col py-0.5 ${flat ? "text-right" : "text-left"}`, children: [
12685
- /* @__PURE__ */ jsx75(
14133
+ /* @__PURE__ */ jsx77(
12686
14134
  ITText,
12687
14135
  {
12688
14136
  as: "span",
@@ -12691,7 +14139,7 @@ function ITTopBar({
12691
14139
  children: userMenu.userName
12692
14140
  }
12693
14141
  ),
12694
- /* @__PURE__ */ jsx75(
14142
+ /* @__PURE__ */ jsx77(
12695
14143
  ITText,
12696
14144
  {
12697
14145
  as: "span",
@@ -12718,14 +14166,14 @@ function ITTopBar({
12718
14166
  },
12719
14167
  children: [
12720
14168
  /* @__PURE__ */ jsxs55("div", { className: "px-5 py-4 border-b", style: { borderColor: "var(--it-topbar-user-dropdown-border, #f1f5f9)", backgroundColor: "var(--it-topbar-user-bg, #f8fafc)" }, children: [
12721
- /* @__PURE__ */ jsx75(ITText, { as: "span", className: "block font-bold text-[0.9rem]", style: { color: "var(--it-topbar-user-text, #0f172a)" }, children: userMenu.userName }),
12722
- /* @__PURE__ */ jsx75(ITText, { as: "span", className: "block text-xs font-medium truncate mt-0.5", style: { color: "var(--it-topbar-user-subtitle, #64748b)" }, children: userMenu.userEmail })
14169
+ /* @__PURE__ */ jsx77(ITText, { as: "span", className: "block font-bold text-[0.9rem]", style: { color: "var(--it-topbar-user-text, #0f172a)" }, children: userMenu.userName }),
14170
+ /* @__PURE__ */ jsx77(ITText, { as: "span", className: "block text-xs font-medium truncate mt-0.5", style: { color: "var(--it-topbar-user-subtitle, #64748b)" }, children: userMenu.userEmail })
12723
14171
  ] }),
12724
- /* @__PURE__ */ jsx75("ul", { className: "py-2", children: userMenu.menuItems.map((m, i) => {
14172
+ /* @__PURE__ */ jsx77("ul", { className: "py-2", children: userMenu.menuItems.map((m, i) => {
12725
14173
  const isDestructive = m.label.toLowerCase().includes("salir") || m.label.toLowerCase().includes("cerrar") || m.label.toLowerCase().includes("logout");
12726
14174
  return /* @__PURE__ */ jsxs55("li", { className: "px-2", children: [
12727
- i === userMenu.menuItems.length - 1 && isDestructive && i > 0 && /* @__PURE__ */ jsx75("div", { className: "h-px bg-slate-100 my-1 mx-2" }),
12728
- /* @__PURE__ */ jsx75(
14175
+ i === userMenu.menuItems.length - 1 && isDestructive && i > 0 && /* @__PURE__ */ jsx77("div", { className: "h-px bg-slate-100 my-1 mx-2" }),
14176
+ /* @__PURE__ */ jsx77(
12729
14177
  "button",
12730
14178
  {
12731
14179
  onClick: () => {
@@ -12740,7 +14188,7 @@ function ITTopBar({
12740
14188
  onMouseLeave: (e) => {
12741
14189
  e.currentTarget.style.backgroundColor = "transparent";
12742
14190
  },
12743
- children: /* @__PURE__ */ jsx75(ITText, { as: "span", children: m.label })
14191
+ children: /* @__PURE__ */ jsx77(ITText, { as: "span", children: m.label })
12744
14192
  }
12745
14193
  )
12746
14194
  ] }, i);
@@ -12756,7 +14204,7 @@ function ITTopBar({
12756
14204
  }
12757
14205
 
12758
14206
  // src/components/templates/layout/layout.tsx
12759
- import { jsx as jsx76, jsxs as jsxs56 } from "react/jsx-runtime";
14207
+ import { jsx as jsx78, jsxs as jsxs56 } from "react/jsx-runtime";
12760
14208
  function ITLayout({
12761
14209
  topBar,
12762
14210
  sidebar,
@@ -12780,7 +14228,7 @@ function ITLayout({
12780
14228
  else setMobileSidebarOpen((v) => !v);
12781
14229
  };
12782
14230
  const brand = sidebarFullHeight ? sidebar.brand ?? { logo: topBar.logo, text: topBar.logoText } : sidebar.brand;
12783
- const topBarNode = /* @__PURE__ */ jsx76(
14231
+ const topBarNode = /* @__PURE__ */ jsx78(
12784
14232
  ITTopBar,
12785
14233
  {
12786
14234
  ...topBar,
@@ -12794,8 +14242,8 @@ function ITLayout({
12794
14242
  // Full-height: the sidebar sits beside the top bar, so it needs to win the
12795
14243
  // stacking order when the collapsed rail expands over the content on hover.
12796
14244
  /* @__PURE__ */ jsxs56("div", { className: `hidden lg:block relative h-full ${sidebarFullHeight ? "z-50" : "z-40"}`, children: [
12797
- /* @__PURE__ */ jsx76("div", { className: `${reservedWidth} h-full flex-shrink-0` }),
12798
- /* @__PURE__ */ jsx76("div", { className: "absolute top-0 left-0 h-full", children: /* @__PURE__ */ jsx76(
14245
+ /* @__PURE__ */ jsx78("div", { className: `${reservedWidth} h-full flex-shrink-0` }),
14246
+ /* @__PURE__ */ jsx78("div", { className: "absolute top-0 left-0 h-full", children: /* @__PURE__ */ jsx78(
12799
14247
  ITSidebar,
12800
14248
  {
12801
14249
  ...sidebar,
@@ -12808,17 +14256,17 @@ function ITLayout({
12808
14256
  ) })
12809
14257
  ] })
12810
14258
  );
12811
- const mobileSidebar = mobileSidebarOpen && /* @__PURE__ */ jsx76(
14259
+ const mobileSidebar = mobileSidebarOpen && /* @__PURE__ */ jsx78(
12812
14260
  "div",
12813
14261
  {
12814
14262
  className: "lg:hidden fixed inset-0 z-[40] transition-opacity duration-300 backdrop-blur-sm bg-black/40",
12815
14263
  onClick: () => setMobileSidebarOpen(false),
12816
- children: /* @__PURE__ */ jsx76(
14264
+ children: /* @__PURE__ */ jsx78(
12817
14265
  "div",
12818
14266
  {
12819
14267
  className: "h-full w-fit flex transform transition-transform duration-300 ease-[cubic-bezier(0.2,0,0,1)]",
12820
14268
  onClick: (e) => e.stopPropagation(),
12821
- children: /* @__PURE__ */ jsx76(
14269
+ children: /* @__PURE__ */ jsx78(
12822
14270
  ITSidebar,
12823
14271
  {
12824
14272
  ...sidebar,
@@ -12835,7 +14283,7 @@ function ITLayout({
12835
14283
  )
12836
14284
  }
12837
14285
  );
12838
- const main = /* @__PURE__ */ jsx76("main", { className: "flex-1 overflow-y-auto w-full custom-scrollbar relative z-0", children: /* @__PURE__ */ jsx76("div", { className: clsx55("mx-auto w-full max-w-7xl px-4 sm:px-6 lg:px-8 py-6 h-full", contentClassName), children }) });
14286
+ const main = /* @__PURE__ */ jsx78("main", { className: "flex-1 overflow-y-auto w-full custom-scrollbar relative z-0", children: /* @__PURE__ */ jsx78("div", { className: clsx55("mx-auto w-full max-w-7xl px-4 sm:px-6 lg:px-8 py-6 h-full", contentClassName), children }) });
12839
14287
  if (sidebarFullHeight) {
12840
14288
  return /* @__PURE__ */ jsxs56(
12841
14289
  "div",
@@ -12870,97 +14318,11 @@ function ITLayout({
12870
14318
  ] });
12871
14319
  }
12872
14320
 
12873
- // src/types/loader.types.ts
12874
- var sizeClasses = {
12875
- sm: "h-4 w-4",
12876
- md: "h-8 w-8",
12877
- lg: "h-12 w-12",
12878
- xl: "h-16 w-16"
12879
- };
12880
-
12881
- // src/components/atoms/loader/loader.tsx
12882
- import { jsx as jsx77 } from "react/jsx-runtime";
12883
- function ITLoader({
12884
- size = "md",
12885
- variant = "spinner",
12886
- color = "primary",
12887
- // Default to semantic primary
12888
- className = ""
12889
- }) {
12890
- const { t } = useITTranslation();
12891
- const isSemantic = color in theme.colors;
12892
- const resolvedColor = isSemantic ? theme.colors[color][500] : color;
12893
- const isCssValue = isSemantic || color.startsWith("#") || color.startsWith("rgb");
12894
- const style = isCssValue ? { color: resolvedColor } : {};
12895
- const bgStyle = isCssValue ? { backgroundColor: resolvedColor } : {};
12896
- const colorClass = !isCssValue ? color : "";
12897
- if (variant === "spinner") {
12898
- return /* @__PURE__ */ jsx77(
12899
- "div",
12900
- {
12901
- className: `inline-block ${sizeClasses[size]} animate-spin rounded-full border-2 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${colorClass} ${className}`,
12902
- role: "status",
12903
- style,
12904
- children: /* @__PURE__ */ jsx77(ITText, { as: "span", className: "!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]", children: t("common.loading") })
12905
- }
12906
- );
12907
- }
12908
- if (variant === "dots") {
12909
- return /* @__PURE__ */ jsx77(
12910
- "div",
12911
- {
12912
- className: `flex items-center justify-center space-x-2 ${className}`,
12913
- children: [...Array(3)].map((_, i) => /* @__PURE__ */ jsx77(
12914
- "div",
12915
- {
12916
- className: `${sizeClasses[size.replace(/l|g/, "")]} animate-bounce rounded-full ${colorClass}`,
12917
- style: {
12918
- ...bgStyle,
12919
- animationDelay: `${i * 0.1}s`
12920
- }
12921
- },
12922
- i
12923
- ))
12924
- }
12925
- );
12926
- }
12927
- if (variant === "bar") {
12928
- return /* @__PURE__ */ jsx77(
12929
- "div",
12930
- {
12931
- className: `w-full ${size === "sm" ? "h-1" : size === "md" ? "h-1.5" : size === "lg" ? "h-2" : "h-2.5"} bg-secondary-200 rounded-full overflow-hidden ${className}`,
12932
- children: /* @__PURE__ */ jsx77(
12933
- "div",
12934
- {
12935
- className: `h-full animate-progress ${colorClass}`,
12936
- style: {
12937
- backgroundColor: resolvedColor,
12938
- // Simplified gradient for modern look, or keep it solid
12939
- backgroundImage: isCssValue ? `linear-gradient(to right, ${resolvedColor}DD, ${resolvedColor})` : void 0,
12940
- animation: "progress 1.5s ease-in-out infinite"
12941
- }
12942
- }
12943
- )
12944
- }
12945
- );
12946
- }
12947
- if (variant === "pulse") {
12948
- return /* @__PURE__ */ jsx77(
12949
- "div",
12950
- {
12951
- className: `rounded-full ${sizeClasses[size]} animate-pulse ${colorClass} ${className}`,
12952
- style: bgStyle
12953
- }
12954
- );
12955
- }
12956
- return null;
12957
- }
12958
-
12959
14321
  // src/components/molecules/stepper/stepper.tsx
12960
14322
  import clsx56 from "clsx";
12961
- import { useEffect as useEffect19, useRef as useRef24, useState as useState40 } from "react";
14323
+ import { useEffect as useEffect20, useRef as useRef25, useState as useState40 } from "react";
12962
14324
  import { FaChevronLeft as FaChevronLeft4, FaChevronRight as FaChevronRight7, FaCheck as FaCheck6 } from "react-icons/fa";
12963
- import { jsx as jsx78, jsxs as jsxs57 } from "react/jsx-runtime";
14325
+ import { jsx as jsx79, jsxs as jsxs57 } from "react/jsx-runtime";
12964
14326
  function ITStepper({
12965
14327
  steps,
12966
14328
  currentStep,
@@ -12977,14 +14339,14 @@ function ITStepper({
12977
14339
  }) {
12978
14340
  const { t } = useITTranslation();
12979
14341
  const [direction, setDirection] = useState40("next");
12980
- const contentRef = useRef24(null);
12981
- const progressRef = useRef24(null);
14342
+ const contentRef = useRef25(null);
14343
+ const progressRef = useRef25(null);
12982
14344
  const isThemeColor = color in theme.colors;
12983
14345
  const resolvedColor = isThemeColor ? theme.colors[color][500] : color;
12984
- useEffect19(() => {
14346
+ useEffect20(() => {
12985
14347
  onStepChange?.(currentStep);
12986
14348
  }, [currentStep, onStepChange]);
12987
- useEffect19(() => {
14349
+ useEffect20(() => {
12988
14350
  const pct = currentStep / Math.max(1, steps.length - 1) * 100;
12989
14351
  if (progressRef.current) {
12990
14352
  progressRef.current.style.width = `${pct}%`;
@@ -13028,23 +14390,23 @@ function ITStepper({
13028
14390
  const renderStepContent = (index, isCompleted) => {
13029
14391
  const step = steps[index];
13030
14392
  if (isCompleted) {
13031
- return /* @__PURE__ */ jsx78(FaCheck6, { className: "w-4 h-4" });
14393
+ return /* @__PURE__ */ jsx79(FaCheck6, { className: "w-4 h-4" });
13032
14394
  }
13033
14395
  if (step.icon && useIcons) {
13034
- return /* @__PURE__ */ jsx78("div", { className: "flex items-center justify-center w-5 h-5", children: step.icon });
14396
+ return /* @__PURE__ */ jsx79("div", { className: "flex items-center justify-center w-5 h-5", children: step.icon });
13035
14397
  }
13036
- return /* @__PURE__ */ jsx78(ITText, { as: "span", className: "text-sm font-semibold", children: index + 1 });
14398
+ return /* @__PURE__ */ jsx79(ITText, { as: "span", className: "text-sm font-semibold", children: index + 1 });
13037
14399
  };
13038
14400
  return /* @__PURE__ */ jsxs57("div", { className: clsx56("w-full max-w-5xl mx-auto px-4", containerClassName), children: [
13039
14401
  /* @__PURE__ */ jsxs57("div", { className: "relative mb-8", children: [
13040
- /* @__PURE__ */ jsx78(
14402
+ /* @__PURE__ */ jsx79(
13041
14403
  "div",
13042
14404
  {
13043
14405
  className: "absolute left-6 right-6 top-5 h-1 bg-secondary-200 rounded-full z-0",
13044
14406
  "aria-hidden": true
13045
14407
  }
13046
14408
  ),
13047
- /* @__PURE__ */ jsx78(
14409
+ /* @__PURE__ */ jsx79(
13048
14410
  "div",
13049
14411
  {
13050
14412
  ref: progressRef,
@@ -13052,11 +14414,11 @@ function ITStepper({
13052
14414
  "aria-hidden": true
13053
14415
  }
13054
14416
  ),
13055
- /* @__PURE__ */ jsx78("div", { className: "flex items-start justify-between space-x-2 relative z-20", children: steps.map((step, idx) => {
14417
+ /* @__PURE__ */ jsx79("div", { className: "flex items-start justify-between space-x-2 relative z-20", children: steps.map((step, idx) => {
13056
14418
  const isActive = idx === currentStep;
13057
14419
  const isCompleted = idx < currentStep;
13058
14420
  const hasIcon = step.icon && useIcons;
13059
- return /* @__PURE__ */ jsx78(
14421
+ return /* @__PURE__ */ jsx79(
13060
14422
  "button",
13061
14423
  {
13062
14424
  type: "button",
@@ -13067,7 +14429,7 @@ function ITStepper({
13067
14429
  className: "flex-1 group",
13068
14430
  title: step.label,
13069
14431
  children: /* @__PURE__ */ jsxs57("div", { className: "flex flex-col items-center", children: [
13070
- /* @__PURE__ */ jsx78(
14432
+ /* @__PURE__ */ jsx79(
13071
14433
  "div",
13072
14434
  {
13073
14435
  className: clsx56(
@@ -13081,7 +14443,7 @@ function ITStepper({
13081
14443
  children: renderStepContent(idx, isCompleted)
13082
14444
  }
13083
14445
  ),
13084
- /* @__PURE__ */ jsx78(
14446
+ /* @__PURE__ */ jsx79(
13085
14447
  ITText,
13086
14448
  {
13087
14449
  as: "span",
@@ -13099,7 +14461,7 @@ function ITStepper({
13099
14461
  );
13100
14462
  }) })
13101
14463
  ] }),
13102
- /* @__PURE__ */ jsx78(
14464
+ /* @__PURE__ */ jsx79(
13103
14465
  "div",
13104
14466
  {
13105
14467
  ref: contentRef,
@@ -13116,7 +14478,7 @@ function ITStepper({
13116
14478
  }
13117
14479
  ),
13118
14480
  /* @__PURE__ */ jsxs57("div", { className: "flex justify-between items-center mt-6", children: [
13119
- /* @__PURE__ */ jsx78(
14481
+ /* @__PURE__ */ jsx79(
13120
14482
  ITButton,
13121
14483
  {
13122
14484
  variant: "outlined",
@@ -13124,14 +14486,14 @@ function ITStepper({
13124
14486
  disabled: currentStep === 0,
13125
14487
  onClick: prevStep,
13126
14488
  children: /* @__PURE__ */ jsxs57("div", { className: "flex items-center gap-2", children: [
13127
- /* @__PURE__ */ jsx78(FaChevronLeft4, {}),
13128
- /* @__PURE__ */ jsx78(ITText, { as: "span", children: t("common.back") })
14489
+ /* @__PURE__ */ jsx79(FaChevronLeft4, {}),
14490
+ /* @__PURE__ */ jsx79(ITText, { as: "span", children: t("common.back") })
13129
14491
  ] })
13130
14492
  }
13131
14493
  ),
13132
14494
  /* @__PURE__ */ jsxs57("div", { className: "flex items-center gap-3", children: [
13133
- /* @__PURE__ */ jsx78(ITText, { as: "div", className: "text-sm text-secondary-500 mr-2 hidden sm:block", children: t("stepper.stepOf", { current: currentStep + 1, total: steps.length }) }),
13134
- /* @__PURE__ */ jsx78(
14495
+ /* @__PURE__ */ jsx79(ITText, { as: "div", className: "text-sm text-secondary-500 mr-2 hidden sm:block", children: t("stepper.stepOf", { current: currentStep + 1, total: steps.length }) }),
14496
+ /* @__PURE__ */ jsx79(
13135
14497
  ITButton,
13136
14498
  {
13137
14499
  variant: "solid",
@@ -13139,8 +14501,8 @@ function ITStepper({
13139
14501
  disabled: disableNext,
13140
14502
  onClick: nextStep,
13141
14503
  children: /* @__PURE__ */ jsxs57("div", { className: "flex items-center gap-2", children: [
13142
- /* @__PURE__ */ jsx78(ITText, { as: "span", children: currentStep === steps.length - 1 ? t("common.finish") : t("common.next") }),
13143
- currentStep === steps.length - 1 ? /* @__PURE__ */ jsx78(FaCheck6, {}) : /* @__PURE__ */ jsx78(FaChevronRight7, {})
14504
+ /* @__PURE__ */ jsx79(ITText, { as: "span", children: currentStep === steps.length - 1 ? t("common.finish") : t("common.next") }),
14505
+ currentStep === steps.length - 1 ? /* @__PURE__ */ jsx79(FaCheck6, {}) : /* @__PURE__ */ jsx79(FaChevronRight7, {})
13144
14506
  ] })
13145
14507
  }
13146
14508
  )
@@ -13150,7 +14512,7 @@ function ITStepper({
13150
14512
  }
13151
14513
 
13152
14514
  // src/components/theme-provider/themeProvider.tsx
13153
- import { useState as useState41, useEffect as useEffect20, useLayoutEffect as useLayoutEffect5 } from "react";
14515
+ import { useState as useState41, useEffect as useEffect21, useLayoutEffect as useLayoutEffect5 } from "react";
13154
14516
  import { MdPalette, MdClose, MdRefresh } from "react-icons/md";
13155
14517
 
13156
14518
  // src/components/theme-provider/themePresets.ts
@@ -13328,7 +14690,7 @@ var PRESETS = [
13328
14690
  ];
13329
14691
 
13330
14692
  // src/components/theme-provider/themeProvider.tsx
13331
- import { jsx as jsx79, jsxs as jsxs58 } from "react/jsx-runtime";
14693
+ import { jsx as jsx80, jsxs as jsxs58 } from "react/jsx-runtime";
13332
14694
  var STORAGE_KEY = "it-theme-palette";
13333
14695
  var SHADOW_LEVELS = {
13334
14696
  0: {
@@ -13497,7 +14859,7 @@ function ITThemeProvider({
13497
14859
  return "system";
13498
14860
  }
13499
14861
  );
13500
- useEffect20(() => {
14862
+ useEffect21(() => {
13501
14863
  localStorage.setItem("it-theme-dark-mode", darkModeMode);
13502
14864
  const applyDarkMode = (isDark) => {
13503
14865
  if (isDark) {
@@ -13522,7 +14884,7 @@ function ITThemeProvider({
13522
14884
  applyDarkMode(darkModeMode === "dark");
13523
14885
  }
13524
14886
  }, [darkModeMode]);
13525
- useEffect20(() => {
14887
+ useEffect21(() => {
13526
14888
  if (!showFab) {
13527
14889
  setPaletteState({
13528
14890
  ...DEFAULT_PALETTE,
@@ -13579,7 +14941,7 @@ function ITThemeProvider({
13579
14941
  surfaceStyle?.remove();
13580
14942
  };
13581
14943
  }, [radius, shadow]);
13582
- useEffect20(() => {
14944
+ useEffect21(() => {
13583
14945
  const injectStyles = (obj, prefix = "") => {
13584
14946
  Object.entries(obj).forEach(([key, val]) => {
13585
14947
  if (typeof val === "object" && val !== null) {
@@ -14740,7 +16102,7 @@ function ITThemeProvider({
14740
16102
  children: [
14741
16103
  /* @__PURE__ */ jsxs58("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [
14742
16104
  /* @__PURE__ */ jsxs58("div", { className: "relative w-10 h-10 rounded-xl border-2 border-slate-200 dark:border-slate-700 overflow-hidden cursor-pointer flex-shrink-0 shadow-sm hover:scale-105 transition-transform", children: [
14743
- /* @__PURE__ */ jsx79(
16105
+ /* @__PURE__ */ jsx80(
14744
16106
  "input",
14745
16107
  {
14746
16108
  type: "color",
@@ -14749,23 +16111,23 @@ function ITThemeProvider({
14749
16111
  className: "absolute inset-0 opacity-0 cursor-pointer w-full h-full"
14750
16112
  }
14751
16113
  ),
14752
- /* @__PURE__ */ jsx79("div", { className: "w-full h-full", style: { backgroundColor: value } })
16114
+ /* @__PURE__ */ jsx80("div", { className: "w-full h-full", style: { backgroundColor: value } })
14753
16115
  ] }),
14754
16116
  /* @__PURE__ */ jsxs58("div", { className: "flex flex-col min-w-0", children: [
14755
- /* @__PURE__ */ jsx79(ITText, { as: "span", className: "text-xs font-bold text-slate-700 dark:text-slate-300 truncate capitalize", children: label.replace(/([A-Z])/g, " $1").trim() }),
16117
+ /* @__PURE__ */ jsx80(ITText, { as: "span", className: "text-xs font-bold text-slate-700 dark:text-slate-300 truncate capitalize", children: label.replace(/([A-Z])/g, " $1").trim() }),
14756
16118
  /* @__PURE__ */ jsxs58("div", { className: "flex items-center gap-2 mt-0.5", children: [
14757
- /* @__PURE__ */ jsx79(
16119
+ /* @__PURE__ */ jsx80(
14758
16120
  "span",
14759
16121
  {
14760
16122
  className: "w-3 h-3 rounded-full border border-slate-200 dark:border-slate-600",
14761
16123
  style: { backgroundColor: value }
14762
16124
  }
14763
16125
  ),
14764
- /* @__PURE__ */ jsx79(ITText, { as: "span", className: "font-mono text-[11px] text-slate-400", children: value })
16126
+ /* @__PURE__ */ jsx80(ITText, { as: "span", className: "font-mono text-[11px] text-slate-400", children: value })
14765
16127
  ] })
14766
16128
  ] })
14767
16129
  ] }),
14768
- /* @__PURE__ */ jsx79(
16130
+ /* @__PURE__ */ jsx80(
14769
16131
  "input",
14770
16132
  {
14771
16133
  type: "text",
@@ -14791,7 +16153,7 @@ function ITThemeProvider({
14791
16153
  onClick: () => applyPreset(preset.colors),
14792
16154
  className: `relative flex flex-col items-start p-2.5 rounded-xl border text-left transition-all group ${isSelected ? "border-primary-500 bg-primary-500/5 shadow-sm ring-1 ring-primary-500/20" : "border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900/50 hover:border-slate-300 dark:hover:border-slate-600"}`,
14793
16155
  children: [
14794
- isCustom && /* @__PURE__ */ jsx79(
16156
+ isCustom && /* @__PURE__ */ jsx80(
14795
16157
  "span",
14796
16158
  {
14797
16159
  onClick: (e) => {
@@ -14800,11 +16162,11 @@ function ITThemeProvider({
14800
16162
  },
14801
16163
  className: "absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 p-0.5 rounded-md hover:bg-danger-500/10 hover:text-danger-500 text-slate-400 dark:text-slate-500 cursor-pointer transition-all z-10",
14802
16164
  title: t("themeProvider.designer.deletePreset"),
14803
- children: /* @__PURE__ */ jsx79(MdClose, { size: 12 })
16165
+ children: /* @__PURE__ */ jsx80(MdClose, { size: 12 })
14804
16166
  }
14805
16167
  ),
14806
- /* @__PURE__ */ jsx79(ITText, { as: "span", className: "text-xs font-semibold truncate w-full mb-1.5 pr-4 text-slate-700 dark:text-slate-300", children: PRESET_I18N_KEY[preset.name] ? t(PRESET_I18N_KEY[preset.name]) : preset.name }),
14807
- /* @__PURE__ */ jsx79("div", { className: "flex gap-1", children: ["primary", "secondary", "ternary", "success"].map((c) => /* @__PURE__ */ jsx79(
16168
+ /* @__PURE__ */ jsx80(ITText, { as: "span", className: "text-xs font-semibold truncate w-full mb-1.5 pr-4 text-slate-700 dark:text-slate-300", children: PRESET_I18N_KEY[preset.name] ? t(PRESET_I18N_KEY[preset.name]) : preset.name }),
16169
+ /* @__PURE__ */ jsx80("div", { className: "flex gap-1", children: ["primary", "secondary", "ternary", "success"].map((c) => /* @__PURE__ */ jsx80(
14808
16170
  "span",
14809
16171
  {
14810
16172
  className: "w-3 h-3 rounded-full border border-black/10",
@@ -14833,17 +16195,17 @@ function ITThemeProvider({
14833
16195
  },
14834
16196
  children: [
14835
16197
  children,
14836
- showFab && /* @__PURE__ */ jsx79(
16198
+ showFab && /* @__PURE__ */ jsx80(
14837
16199
  "button",
14838
16200
  {
14839
16201
  onClick: () => setIsOpen((prev) => !prev),
14840
16202
  className: "it-theme-fab it-theme-bounce",
14841
16203
  style: { backgroundColor: "var(--color-primary)" },
14842
16204
  "aria-label": t("themeProvider.fab.ariaLabel"),
14843
- children: /* @__PURE__ */ jsx79(MdPalette, { size: 28 })
16205
+ children: /* @__PURE__ */ jsx80(MdPalette, { size: 28 })
14844
16206
  }
14845
16207
  ),
14846
- showFab && /* @__PURE__ */ jsx79(
16208
+ showFab && /* @__PURE__ */ jsx80(
14847
16209
  ITDialog,
14848
16210
  {
14849
16211
  isOpen,
@@ -14853,8 +16215,8 @@ function ITThemeProvider({
14853
16215
  children: /* @__PURE__ */ jsxs58("div", { className: "flex gap-6 h-[580px]", children: [
14854
16216
  /* @__PURE__ */ jsxs58("div", { className: "w-64 flex-shrink-0 flex flex-col gap-5 overflow-y-auto pr-1", children: [
14855
16217
  /* @__PURE__ */ jsxs58("div", { children: [
14856
- /* @__PURE__ */ jsx79(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block", children: t("themeProvider.designer.appearance") }),
14857
- /* @__PURE__ */ jsx79(
16218
+ /* @__PURE__ */ jsx80(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block", children: t("themeProvider.designer.appearance") }),
16219
+ /* @__PURE__ */ jsx80(
14858
16220
  ITSegmentedControl,
14859
16221
  {
14860
16222
  options: [
@@ -14869,15 +16231,15 @@ function ITThemeProvider({
14869
16231
  )
14870
16232
  ] }),
14871
16233
  /* @__PURE__ */ jsxs58("div", { children: [
14872
- /* @__PURE__ */ jsx79("div", { className: "flex items-center justify-between mb-2.5", children: /* @__PURE__ */ jsx79(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500", children: t("themeProvider.designer.presets") }) }),
14873
- /* @__PURE__ */ jsx79("div", { className: "grid grid-cols-2 gap-2", children: PRESETS.map((preset) => /* @__PURE__ */ jsx79(PresetCard, { preset }, preset.name)) })
16234
+ /* @__PURE__ */ jsx80("div", { className: "flex items-center justify-between mb-2.5", children: /* @__PURE__ */ jsx80(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500", children: t("themeProvider.designer.presets") }) }),
16235
+ /* @__PURE__ */ jsx80("div", { className: "grid grid-cols-2 gap-2", children: PRESETS.map((preset) => /* @__PURE__ */ jsx80(PresetCard, { preset }, preset.name)) })
14874
16236
  ] }),
14875
16237
  customPresets.length > 0 && /* @__PURE__ */ jsxs58("div", { children: [
14876
- /* @__PURE__ */ jsx79(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block", children: t("themeProvider.designer.myThemes") }),
14877
- /* @__PURE__ */ jsx79("div", { className: "flex flex-col gap-1.5", children: customPresets.map((preset) => /* @__PURE__ */ jsx79(PresetCard, { preset, isCustom: true }, preset.name)) })
16238
+ /* @__PURE__ */ jsx80(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block", children: t("themeProvider.designer.myThemes") }),
16239
+ /* @__PURE__ */ jsx80("div", { className: "flex flex-col gap-1.5", children: customPresets.map((preset) => /* @__PURE__ */ jsx80(PresetCard, { preset, isCustom: true }, preset.name)) })
14878
16240
  ] }),
14879
16241
  isSavingPreset && /* @__PURE__ */ jsxs58("div", { className: "flex flex-col gap-2 p-3 rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900/50", children: [
14880
- /* @__PURE__ */ jsx79(
16242
+ /* @__PURE__ */ jsx80(
14881
16243
  ITInput,
14882
16244
  {
14883
16245
  name: "presetName",
@@ -14896,7 +16258,7 @@ function ITThemeProvider({
14896
16258
  }
14897
16259
  ),
14898
16260
  /* @__PURE__ */ jsxs58("div", { className: "flex gap-2", children: [
14899
- /* @__PURE__ */ jsx79(
16261
+ /* @__PURE__ */ jsx80(
14900
16262
  ITButton,
14901
16263
  {
14902
16264
  label: t("themeProvider.designer.save"),
@@ -14907,7 +16269,7 @@ function ITThemeProvider({
14907
16269
  className: "flex-1"
14908
16270
  }
14909
16271
  ),
14910
- /* @__PURE__ */ jsx79(
16272
+ /* @__PURE__ */ jsx80(
14911
16273
  ITButton,
14912
16274
  {
14913
16275
  label: t("themeProvider.designer.cancelSave"),
@@ -14921,31 +16283,31 @@ function ITThemeProvider({
14921
16283
  )
14922
16284
  ] })
14923
16285
  ] }),
14924
- !isSavingPreset && /* @__PURE__ */ jsx79(
16286
+ !isSavingPreset && /* @__PURE__ */ jsx80(
14925
16287
  ITButton,
14926
16288
  {
14927
16289
  variant: "outlined",
14928
- icon: /* @__PURE__ */ jsx79(MdPalette, { size: 14 }),
16290
+ icon: /* @__PURE__ */ jsx80(MdPalette, { size: 14 }),
14929
16291
  label: t("themeProvider.designer.saveCurrent"),
14930
16292
  onClick: () => setIsSavingPreset(true),
14931
16293
  size: "sm"
14932
16294
  }
14933
16295
  ),
14934
- /* @__PURE__ */ jsx79(
16296
+ /* @__PURE__ */ jsx80(
14935
16297
  ITButton,
14936
16298
  {
14937
16299
  variant: "outlined",
14938
16300
  color: "danger",
14939
- icon: /* @__PURE__ */ jsx79(MdRefresh, { size: 14 }),
16301
+ icon: /* @__PURE__ */ jsx80(MdRefresh, { size: 14 }),
14940
16302
  label: t("themeProvider.designer.reset"),
14941
16303
  onClick: resetTheme,
14942
16304
  size: "sm"
14943
16305
  }
14944
16306
  )
14945
16307
  ] }),
14946
- /* @__PURE__ */ jsx79(ITDivider, { orientation: "vertical" }),
16308
+ /* @__PURE__ */ jsx80(ITDivider, { orientation: "vertical" }),
14947
16309
  /* @__PURE__ */ jsxs58("div", { className: "flex-1 flex flex-col min-w-0", children: [
14948
- /* @__PURE__ */ jsx79(
16310
+ /* @__PURE__ */ jsx80(
14949
16311
  tabs_default,
14950
16312
  {
14951
16313
  variant: "pill",
@@ -14953,7 +16315,7 @@ function ITThemeProvider({
14953
16315
  {
14954
16316
  id: "brand",
14955
16317
  label: t("themeProvider.tabs.brand"),
14956
- content: /* @__PURE__ */ jsx79("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
16318
+ content: /* @__PURE__ */ jsx80("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
14957
16319
  "primary",
14958
16320
  "secondary",
14959
16321
  "ternary",
@@ -14962,35 +16324,35 @@ function ITThemeProvider({
14962
16324
  "info",
14963
16325
  "alert",
14964
16326
  "warning"
14965
- ].map((key) => /* @__PURE__ */ jsx79(ColorRow, { colorKey: key }, key)) })
16327
+ ].map((key) => /* @__PURE__ */ jsx80(ColorRow, { colorKey: key }, key)) })
14966
16328
  },
14967
16329
  {
14968
16330
  id: "layout",
14969
16331
  label: t("themeProvider.tabs.layout"),
14970
- content: /* @__PURE__ */ jsx79("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
16332
+ content: /* @__PURE__ */ jsx80("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
14971
16333
  "layout.sidebarBg",
14972
16334
  "layout.sidebarText",
14973
16335
  "layout.navbarBg",
14974
16336
  "layout.navbarText"
14975
- ].map((key) => /* @__PURE__ */ jsx79(ColorRow, { colorKey: key }, key)) })
16337
+ ].map((key) => /* @__PURE__ */ jsx80(ColorRow, { colorKey: key }, key)) })
14976
16338
  },
14977
16339
  {
14978
16340
  id: "tables",
14979
16341
  label: t("themeProvider.tabs.tables"),
14980
- content: /* @__PURE__ */ jsx79("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
16342
+ content: /* @__PURE__ */ jsx80("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
14981
16343
  "table.headerBg",
14982
16344
  "table.headerText",
14983
16345
  "table.rowBg",
14984
16346
  "table.rowText",
14985
16347
  "table.rowHover"
14986
- ].map((key) => /* @__PURE__ */ jsx79(ColorRow, { colorKey: key }, key)) })
16348
+ ].map((key) => /* @__PURE__ */ jsx80(ColorRow, { colorKey: key }, key)) })
14987
16349
  }
14988
16350
  ]
14989
16351
  }
14990
16352
  ),
14991
16353
  /* @__PURE__ */ jsxs58("div", { className: "flex items-center justify-end gap-3 mt-auto pt-4 border-t border-slate-100 dark:border-slate-800", children: [
14992
- /* @__PURE__ */ jsx79(ITText, { as: "p", className: "text-[11px] text-slate-400 mr-auto", children: t("themeProvider.designer.autosave") }),
14993
- /* @__PURE__ */ jsx79(
16354
+ /* @__PURE__ */ jsx80(ITText, { as: "p", className: "text-[11px] text-slate-400 mr-auto", children: t("themeProvider.designer.autosave") }),
16355
+ /* @__PURE__ */ jsx80(
14994
16356
  ITButton,
14995
16357
  {
14996
16358
  label: t("themeProvider.designer.close"),
@@ -15020,7 +16382,13 @@ var createValidationSchema = (fields) => Yup.object().shape(
15020
16382
  }, {})
15021
16383
  );
15022
16384
  export {
16385
+ AXZY_CATALOG_ENTRIES,
16386
+ AXZY_EXCLUDED_TYPES,
16387
+ CURRENT_SCHEMA_VERSION,
16388
+ DEFAULT_LIMITS,
16389
+ DEFAULT_MIGRATIONS,
15023
16390
  FileTypeEnum,
16391
+ GLOBALLY_FORBIDDEN_PROPS,
15024
16392
  ITAccordion,
15025
16393
  ITAlert,
15026
16394
  ITAvatar,
@@ -15064,6 +16432,7 @@ export {
15064
16432
  ITPopover,
15065
16433
  ITProgress,
15066
16434
  ITRadioGroup,
16435
+ ITSchemaRenderer,
15067
16436
  ITSearchSelect,
15068
16437
  ITSearchTable,
15069
16438
  ITSegmentedControl,
@@ -15084,13 +16453,39 @@ export {
15084
16453
  ITToast,
15085
16454
  tripleFilter_default as ITTripleFilter,
15086
16455
  ITWysiwyg,
16456
+ JsonEngineError,
16457
+ NodeBoundary,
15087
16458
  UploadStatus,
16459
+ auditTree,
16460
+ axzyCatalog,
16461
+ axzyCatalogTypes,
16462
+ buildVocabularyContract,
16463
+ countPendingNodes,
16464
+ createCatalog,
16465
+ createLimitTracker,
15088
16466
  createValidationSchema,
15089
16467
  en_default as enMessages,
15090
16468
  es_default as esMessages,
16469
+ formatPath,
16470
+ formatVocabularyForPrompt,
16471
+ getCatalogEntry,
15091
16472
  getContrastTextColor,
16473
+ getExclusionReason,
16474
+ hasPath,
16475
+ isExcludedType,
15092
16476
  isLightColor,
16477
+ isNodePending,
16478
+ issue,
16479
+ migrateSchema,
16480
+ parsePartialSchema,
16481
+ parsePath,
16482
+ propPath,
16483
+ pushPath,
16484
+ readPath,
16485
+ renderNode,
15093
16486
  resolveCssColor,
16487
+ resolveLimits,
16488
+ resolveNode,
15094
16489
  useClickOutside_default as useClickOutside,
15095
16490
  useDebouncedSearch,
15096
16491
  useEditableRow,
@@ -15100,6 +16495,7 @@ export {
15100
16495
  useITThemeSafe,
15101
16496
  useITTranslation,
15102
16497
  useJsonRender_default as useJsonRender,
15103
- useTableState
16498
+ useTableState,
16499
+ validateSchema
15104
16500
  };
15105
16501
  //# sourceMappingURL=index.js.map