@axzydev/axzy_ui_system 1.7.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/index.cjs +1938 -491
  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 +1830 -417
  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/atoms/segmented-control/segmented-control.tsx +3 -0
  14. package/src/components/molecules/card/card.tsx +12 -0
  15. package/src/components/molecules/stat-card/stat-card.tsx +10 -0
  16. package/src/components/organisms/dialog/dialog.props.ts +2 -0
  17. package/src/components/organisms/dialog/dialog.tsx +4 -3
  18. package/src/dev.css +6 -0
  19. package/src/index.ts +90 -1
  20. package/src/json-renderer/catalog/axzyCatalog.ts +362 -0
  21. package/src/json-renderer/catalog/catalog.props.ts +128 -0
  22. package/src/json-renderer/catalog/resolve.ts +225 -0
  23. package/src/json-renderer/index.ts +70 -0
  24. package/src/json-renderer/kernel/NodeBoundary.tsx +53 -0
  25. package/src/json-renderer/kernel/SchemaRenderer.tsx +197 -0
  26. package/src/json-renderer/kernel/kernel.test.tsx +341 -0
  27. package/src/json-renderer/kernel/partial.ts +92 -0
  28. package/src/json-renderer/kernel/renderNode.tsx +113 -0
  29. package/src/json-renderer/kernel/schemaRenderer.props.ts +42 -0
  30. package/src/json-renderer/kernel/types.ts +159 -0
  31. package/src/json-renderer/shared/errors.ts +92 -0
  32. package/src/json-renderer/shared/limits.ts +87 -0
  33. package/src/json-renderer/shared/paths.ts +66 -0
  34. package/src/json-renderer/shared/shared.test.ts +108 -0
  35. package/src/json-renderer/stream/tolerantParse.test.ts +152 -0
  36. package/src/json-renderer/stream/tolerantParse.ts +449 -0
  37. package/src/json-renderer/test/setup.ts +38 -0
  38. package/src/json-renderer/validation/migrate.ts +83 -0
  39. package/src/json-renderer/validation/validate.ts +161 -0
  40. package/src/json-renderer/validation/validation.test.ts +165 -0
  41. package/src/json-renderer/vocabulary/buildContract.ts +158 -0
  42. package/src/sandbox/axzyConfig.test.ts +40 -0
  43. package/src/sandbox/axzyConfig.ts +77 -0
  44. package/src/sandbox/i18n.ts +218 -0
  45. package/src/sandbox/navigation.ts +1 -0
  46. package/src/sandbox/useHashRoute.ts +39 -9
  47. package/src/showcases/DemoJsonDashboard.tsx +489 -0
  48. package/src/showcases/DemoJsonDocs.tsx +339 -0
  49. package/src/showcases/DemoJsonPortfolio.tsx +257 -0
  50. package/src/showcases/JsonScreenShowcase.tsx +341 -0
  51. package/src/showcases/demoApp/demoData.ts +181 -0
  52. package/src/showcases/demoApp/nodeTree.test.ts +39 -0
  53. package/src/showcases/demoApp/nodeTree.ts +35 -0
  54. package/src/showcases/demoApp/schemas.test.ts +54 -0
package/dist/index.js CHANGED
@@ -1527,6 +1527,14 @@ function ITCard({
1527
1527
  onClick,
1528
1528
  onMouseEnter: () => onClick && setIsHovered(true),
1529
1529
  onMouseLeave: () => onClick && setIsHovered(false),
1530
+ role: onClick ? "button" : void 0,
1531
+ tabIndex: onClick ? 0 : void 0,
1532
+ onKeyDown: onClick ? (e) => {
1533
+ if (e.key === "Enter" || e.key === " ") {
1534
+ e.preventDefault();
1535
+ onClick();
1536
+ }
1537
+ } : void 0,
1530
1538
  className: clsx2("overflow-hidden flex flex-col", className),
1531
1539
  style: containerStyle,
1532
1540
  children: [
@@ -1823,7 +1831,7 @@ function ITJsonRenderer({
1823
1831
  json,
1824
1832
  className
1825
1833
  }) {
1826
- const renderNode = (node) => {
1834
+ const renderNode2 = (node) => {
1827
1835
  if (node == null || typeof node === "boolean") {
1828
1836
  return null;
1829
1837
  }
@@ -1834,10 +1842,10 @@ function ITJsonRenderer({
1834
1842
  return node;
1835
1843
  }
1836
1844
  if (Array.isArray(node)) {
1837
- return node.map((child, idx) => /* @__PURE__ */ jsx9(React.Fragment, { children: renderNode(child) }, idx));
1845
+ return node.map((child, idx) => /* @__PURE__ */ jsx9(React.Fragment, { children: renderNode2(child) }, idx));
1838
1846
  }
1839
1847
  const { type, props = {}, children, text } = node;
1840
- const childContent = children !== void 0 ? renderNode(children) : text;
1848
+ const childContent = children !== void 0 ? renderNode2(children) : text;
1841
1849
  switch (type) {
1842
1850
  case "button":
1843
1851
  return /* @__PURE__ */ jsx9(ITButton, { ...props, children: childContent });
@@ -1859,9 +1867,9 @@ function ITJsonRenderer({
1859
1867
  }
1860
1868
  };
1861
1869
  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)) });
1870
+ return /* @__PURE__ */ jsx9("div", { className: clsx7(className), children: json.map((n, idx) => /* @__PURE__ */ jsx9(React.Fragment, { children: renderNode2(n) }, idx)) });
1863
1871
  }
1864
- return /* @__PURE__ */ jsx9("div", { className: clsx7(className), children: renderNode(json) });
1872
+ return /* @__PURE__ */ jsx9("div", { className: clsx7(className), children: renderNode2(json) });
1865
1873
  }
1866
1874
 
1867
1875
  // src/hooks/useJsonRender.tsx
@@ -5970,7 +5978,8 @@ function ITDialog({
5970
5978
  className,
5971
5979
  title,
5972
5980
  useFormHeader = false,
5973
- fullScreen = false
5981
+ fullScreen = false,
5982
+ padded = true
5974
5983
  }) {
5975
5984
  const { t } = useITTranslation();
5976
5985
  const modalRef = useRef14(null);
@@ -5999,7 +6008,7 @@ function ITDialog({
5999
6008
  "div",
6000
6009
  {
6001
6010
  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"}`}`,
6011
+ 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
6012
  style: {
6004
6013
  backgroundColor: theme.card.backgroundColor,
6005
6014
  borderRadius: fullScreen ? "0" : theme.card.borderRadius,
@@ -6021,8 +6030,8 @@ function ITDialog({
6021
6030
  children: /* @__PURE__ */ jsx31(FaRegTimesCircle, {})
6022
6031
  }
6023
6032
  ),
6024
- title && /* @__PURE__ */ jsx31(ITText, { as: "h2", className: "text-xl font-semibold mb-4", children: title }),
6025
- /* @__PURE__ */ jsx31("div", { children })
6033
+ 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 }) })),
6034
+ /* @__PURE__ */ jsx31("div", { className: padded ? void 0 : "min-h-0 flex-1 flex flex-col", children })
6026
6035
  ] })
6027
6036
  }
6028
6037
  )
@@ -6949,7 +6958,8 @@ var ITImage = ({
6949
6958
  src,
6950
6959
  alt,
6951
6960
  className = "",
6952
- fallback = ""
6961
+ fallback = "",
6962
+ fit = "cover"
6953
6963
  }) => {
6954
6964
  const [imageError, setImageError] = useState23(false);
6955
6965
  const { t } = useITTranslation();
@@ -6965,7 +6975,8 @@ var ITImage = ({
6965
6975
  {
6966
6976
  src: fallback,
6967
6977
  alt: t("image.fallbackAlt"),
6968
- className: "w-full h-full object-cover"
6978
+ className: "w-full h-full",
6979
+ style: { objectFit: fit }
6969
6980
  }
6970
6981
  ) : /* @__PURE__ */ jsx39(
6971
6982
  "img",
@@ -6973,7 +6984,8 @@ var ITImage = ({
6973
6984
  src,
6974
6985
  alt,
6975
6986
  onError: handleImageError,
6976
- className: "w-full h-full object-cover"
6987
+ className: "w-full h-full",
6988
+ style: { objectFit: fit }
6977
6989
  }
6978
6990
  )
6979
6991
  }
@@ -8247,6 +8259,7 @@ function ITSegmentedControl({
8247
8259
  return /* @__PURE__ */ jsx59(
8248
8260
  "div",
8249
8261
  {
8262
+ role: "group",
8250
8263
  className: clsx40(
8251
8264
  "inline-flex rounded-xl bg-slate-100 dark:bg-slate-800 border border-slate-200 dark:border-slate-700",
8252
8265
  container,
@@ -8258,6 +8271,8 @@ function ITSegmentedControl({
8258
8271
  return /* @__PURE__ */ jsxs41(
8259
8272
  "button",
8260
8273
  {
8274
+ type: "button",
8275
+ "aria-pressed": isActive,
8261
8276
  onClick: () => !disabled && onChange(opt.value),
8262
8277
  disabled,
8263
8278
  className: clsx40(
@@ -8934,6 +8949,12 @@ function ITStatCard({
8934
8949
  onClick,
8935
8950
  role: onClick ? "button" : void 0,
8936
8951
  tabIndex: onClick ? 0 : void 0,
8952
+ onKeyDown: onClick ? (e) => {
8953
+ if (e.key === "Enter" || e.key === " ") {
8954
+ e.preventDefault();
8955
+ onClick();
8956
+ }
8957
+ } : void 0,
8937
8958
  children: [
8938
8959
  /* @__PURE__ */ jsxs44("div", { className: "flex items-start justify-between mb-1", children: [
8939
8960
  /* @__PURE__ */ jsx63(ITText, { as: "span", className: "text-xs font-medium text-slate-400 dark:text-slate-500", children: label }),
@@ -11106,7 +11127,7 @@ function ITCodeTreeView({
11106
11127
  const line = analysis.nodeLines.get(pathKey(node.path))?.line;
11107
11128
  const isRoot = node.key === "";
11108
11129
  const isCollapsed = collapsed[node.key] ?? (node.childCount > 0 && node.level >= AUTO_EXPANDED_LEVELS);
11109
- const hasChildren = node.childCount > 0;
11130
+ const hasChildren2 = node.childCount > 0;
11110
11131
  const isPrimitive = node.kind !== "object" && node.kind !== "array";
11111
11132
  return /* @__PURE__ */ jsxs52(
11112
11133
  "div",
@@ -11114,7 +11135,7 @@ function ITCodeTreeView({
11114
11135
  className: "it-json-editor-tree-row",
11115
11136
  style: { paddingLeft: node.level * 14 },
11116
11137
  children: [
11117
- hasChildren ? /* @__PURE__ */ jsx72(
11138
+ hasChildren2 ? /* @__PURE__ */ jsx72(
11118
11139
  "button",
11119
11140
  {
11120
11141
  type: "button",
@@ -11129,7 +11150,7 @@ function ITCodeTreeView({
11129
11150
  /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tk-key", children: node.label }),
11130
11151
  /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tk-punct", children: ":" })
11131
11152
  ] }),
11132
- hasChildren ? /* @__PURE__ */ jsxs52(Fragment11, { children: [
11153
+ hasChildren2 ? /* @__PURE__ */ jsxs52(Fragment11, { children: [
11133
11154
  /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tk-punct", children: node.kind === "array" ? "[" : "{" }),
11134
11155
  isCollapsed && /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tk-punct", children: node.kind === "array" ? "]" : "}" }),
11135
11156
  /* @__PURE__ */ jsx72("span", { className: "it-json-editor-tree-badge", children: t("jsonEditor.childCount", { count: node.childCount }) })
@@ -12149,201 +12170,1645 @@ function EditorToggle({
12149
12170
  );
12150
12171
  }
12151
12172
 
12152
- // src/components/organisms/dropfile/dropfile.tsx
12153
- import { useState as useState37, useEffect as useEffect18 } from "react";
12154
- import { useDropzone } from "react-dropzone";
12155
- import clsx54 from "clsx";
12173
+ // src/json-renderer/kernel/SchemaRenderer.tsx
12174
+ import { useEffect as useEffect18, useMemo as useMemo16, useRef as useRef23 } from "react";
12156
12175
 
12157
- // src/components/organisms/dropfile/dropfile.props.ts
12158
- var FileTypeEnum = /* @__PURE__ */ ((FileTypeEnum2) => {
12159
- FileTypeEnum2["PDF"] = "application/pdf";
12160
- FileTypeEnum2["XLS"] = "application/vnd.ms-excel";
12161
- FileTypeEnum2["XLSX"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
12162
- FileTypeEnum2["CSV"] = "text/csv";
12163
- FileTypeEnum2["PNG"] = "image/png";
12164
- FileTypeEnum2["JPG"] = "image/jpg";
12165
- FileTypeEnum2["JPEG"] = "image/jpeg";
12166
- FileTypeEnum2["MP4"] = "video/mp4";
12167
- FileTypeEnum2["MOV"] = "video/quicktime";
12168
- FileTypeEnum2["AVI"] = "video/x-msvideo";
12169
- FileTypeEnum2["MKV"] = "video/x-matroska";
12170
- FileTypeEnum2["VIDEO_3GPP"] = "video/3gpp";
12171
- FileTypeEnum2["WEBM"] = "video/webm";
12172
- return FileTypeEnum2;
12173
- })(FileTypeEnum || {});
12174
- var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
12175
- UploadStatus2["PENDING"] = "pendiente";
12176
- UploadStatus2["UPLOADING"] = "subiendo";
12177
- UploadStatus2["UPLOADED"] = "subido";
12178
- UploadStatus2["ERROR"] = "error";
12179
- return UploadStatus2;
12180
- })(UploadStatus || {});
12176
+ // src/types/loader.types.ts
12177
+ var sizeClasses = {
12178
+ sm: "h-4 w-4",
12179
+ md: "h-8 w-8",
12180
+ lg: "h-12 w-12",
12181
+ xl: "h-16 w-16"
12182
+ };
12181
12183
 
12182
- // src/components/organisms/dropfile/dropfile.tsx
12183
- import { Fragment as Fragment13, jsx as jsx74, jsxs as jsxs54 } from "react/jsx-runtime";
12184
- var ITDropfile = ({
12185
- onFileSelect,
12186
- onCancel,
12187
- onSubmit,
12188
- contentClassName,
12189
- containerClassName,
12190
- acceptedFileTypes = ["application/pdf" /* PDF */, "application/vnd.ms-excel" /* XLS */, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* XLSX */, "image/jpg" /* JPG */, "image/png" /* PNG */, "image/jpeg" /* JPEG */],
12191
- showStatusBadge = true,
12192
- uploadStatus: externalStatus,
12193
- onStatusChange,
12194
- initialPreviewUrl,
12195
- view = "drop",
12196
- buttonLabel,
12197
- modalTitle
12198
- }) => {
12184
+ // src/components/atoms/loader/loader.tsx
12185
+ import { jsx as jsx74 } from "react/jsx-runtime";
12186
+ function ITLoader({
12187
+ size = "md",
12188
+ variant = "spinner",
12189
+ color = "primary",
12190
+ // Default to semantic primary
12191
+ className = ""
12192
+ }) {
12199
12193
  const { t } = useITTranslation();
12200
- const [isModalOpen, setIsModalOpen] = useState37(false);
12201
- const [selectedFile, setSelectedFile] = useState37(null);
12202
- const [fileType, setFileType] = useState37(null);
12203
- const [imagePreview, setImagePreview] = useState37(initialPreviewUrl || null);
12204
- const [isConfirmed, setIsConfirmed] = useState37(false);
12205
- const [internalUploadStatus, setInternalUploadStatus] = useState37(
12206
- initialPreviewUrl ? "subido" /* UPLOADED */ : "pendiente" /* PENDING */
12207
- );
12208
- useEffect18(() => {
12209
- if (initialPreviewUrl && !selectedFile) {
12210
- setImagePreview(initialPreviewUrl);
12211
- if (externalStatus === void 0) setInternalUploadStatus("subido" /* UPLOADED */);
12212
- }
12213
- }, [initialPreviewUrl, selectedFile, externalStatus]);
12214
- const uploadStatus = externalStatus || internalUploadStatus;
12215
- const setUploadStatus = (status) => {
12216
- if (externalStatus === void 0) {
12217
- setInternalUploadStatus(status);
12218
- }
12219
- onStatusChange?.(status);
12220
- };
12221
- const getAcceptedFileTypes = () => {
12222
- const accept = {};
12223
- acceptedFileTypes.forEach((type) => {
12224
- switch (type) {
12225
- case "application/pdf" /* PDF */:
12226
- accept["application/pdf" /* PDF */] = [".pdf"];
12227
- break;
12228
- case "application/vnd.ms-excel" /* XLS */:
12229
- accept["application/vnd.ms-excel" /* XLS */] = [".xls"];
12230
- break;
12231
- case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* XLSX */:
12232
- accept["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* XLSX */] = [".xlsx"];
12233
- break;
12234
- case "text/csv" /* CSV */:
12235
- accept["text/csv" /* CSV */] = [".csv"];
12236
- break;
12237
- case "image/png" /* PNG */:
12238
- accept["image/png" /* PNG */] = [".png"];
12239
- break;
12240
- case "image/jpg" /* JPG */:
12241
- accept["image/jpg" /* JPG */] = [".jpg", ".jpeg"];
12242
- break;
12243
- case "image/jpeg" /* JPEG */:
12244
- accept["image/jpeg" /* JPEG */] = [".jpeg", ".jpg"];
12245
- break;
12246
- case "video/mp4" /* MP4 */:
12247
- accept["video/mp4" /* MP4 */] = [".mp4"];
12248
- break;
12249
- case "video/quicktime" /* MOV */:
12250
- accept["video/quicktime" /* MOV */] = [".mov"];
12251
- break;
12252
- case "video/x-msvideo" /* AVI */:
12253
- accept["video/x-msvideo" /* AVI */] = [".avi"];
12254
- break;
12255
- case "video/x-matroska" /* MKV */:
12256
- accept["video/x-matroska" /* MKV */] = [".mkv"];
12257
- break;
12258
- case "video/3gpp" /* VIDEO_3GPP */:
12259
- accept["video/3gpp" /* VIDEO_3GPP */] = [".3gp"];
12260
- break;
12261
- case "video/webm" /* WEBM */:
12262
- accept["video/webm" /* WEBM */] = [".webm"];
12263
- break;
12194
+ const isSemantic = color in theme.colors;
12195
+ const resolvedColor = isSemantic ? theme.colors[color][500] : color;
12196
+ const isCssValue = isSemantic || color.startsWith("#") || color.startsWith("rgb");
12197
+ const style = isCssValue ? { color: resolvedColor } : {};
12198
+ const bgStyle = isCssValue ? { backgroundColor: resolvedColor } : {};
12199
+ const colorClass = !isCssValue ? color : "";
12200
+ if (variant === "spinner") {
12201
+ return /* @__PURE__ */ jsx74(
12202
+ "div",
12203
+ {
12204
+ 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}`,
12205
+ role: "status",
12206
+ style,
12207
+ 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") })
12264
12208
  }
12265
- });
12266
- return accept;
12267
- };
12268
- const getFileExtensions = () => {
12269
- const extensions = [];
12270
- acceptedFileTypes.forEach((type) => {
12271
- switch (type) {
12272
- case "application/pdf" /* PDF */:
12273
- if (!extensions.includes("PDF")) extensions.push("PDF");
12274
- break;
12275
- case "application/vnd.ms-excel" /* XLS */:
12276
- case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* XLSX */:
12277
- if (!extensions.includes("EXCEL")) extensions.push("EXCEL");
12278
- break;
12279
- case "text/csv" /* CSV */:
12280
- if (!extensions.includes("CSV")) extensions.push("CSV");
12281
- break;
12282
- case "image/png" /* PNG */:
12283
- case "image/jpg" /* JPG */:
12284
- case "image/jpeg" /* JPEG */:
12285
- if (!extensions.includes("IMAGEN")) extensions.push("IMAGEN");
12286
- break;
12287
- case "video/mp4" /* MP4 */:
12288
- case "video/quicktime" /* MOV */:
12289
- case "video/x-msvideo" /* AVI */:
12290
- case "video/x-matroska" /* MKV */:
12291
- case "video/3gpp" /* VIDEO_3GPP */:
12292
- case "video/webm" /* WEBM */:
12293
- if (!extensions.includes("VIDEO")) extensions.push("VIDEO");
12294
- break;
12209
+ );
12210
+ }
12211
+ if (variant === "dots") {
12212
+ return /* @__PURE__ */ jsx74(
12213
+ "div",
12214
+ {
12215
+ className: `flex items-center justify-center space-x-2 ${className}`,
12216
+ children: [...Array(3)].map((_, i) => /* @__PURE__ */ jsx74(
12217
+ "div",
12218
+ {
12219
+ className: `${sizeClasses[size.replace(/l|g/, "")]} animate-bounce rounded-full ${colorClass}`,
12220
+ style: {
12221
+ ...bgStyle,
12222
+ animationDelay: `${i * 0.1}s`
12223
+ }
12224
+ },
12225
+ i
12226
+ ))
12295
12227
  }
12296
- });
12297
- return extensions.join(", ");
12298
- };
12299
- const StatusBadge = ({ status }) => {
12300
- const config2 = {
12301
- ["pendiente" /* PENDING */]: {
12302
- label: t("dropfile.status.pending"),
12303
- color: "bg-warning-100 text-warning-800 border-warning-200",
12304
- dotColor: "bg-warning-400"
12305
- },
12306
- ["subiendo" /* UPLOADING */]: {
12307
- label: t("dropfile.status.uploading"),
12308
- color: "bg-primary-100 text-primary-800 border-primary-200",
12309
- dotColor: "bg-primary-400 animate-pulse"
12310
- },
12311
- ["subido" /* UPLOADED */]: {
12312
- label: t("dropfile.status.uploaded"),
12313
- color: "bg-success-100 text-success-800 border-success-200",
12314
- dotColor: "bg-success-400"
12315
- },
12316
- ["error" /* ERROR */]: {
12317
- label: t("dropfile.status.error"),
12318
- color: "bg-danger-100 text-danger-800 border-danger-200",
12319
- dotColor: "bg-danger-400"
12228
+ );
12229
+ }
12230
+ if (variant === "bar") {
12231
+ return /* @__PURE__ */ jsx74(
12232
+ "div",
12233
+ {
12234
+ 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}`,
12235
+ children: /* @__PURE__ */ jsx74(
12236
+ "div",
12237
+ {
12238
+ className: `h-full animate-progress ${colorClass}`,
12239
+ style: {
12240
+ backgroundColor: resolvedColor,
12241
+ // Simplified gradient for modern look, or keep it solid
12242
+ backgroundImage: isCssValue ? `linear-gradient(to right, ${resolvedColor}DD, ${resolvedColor})` : void 0,
12243
+ animation: "progress 1.5s ease-in-out infinite"
12244
+ }
12245
+ }
12246
+ )
12320
12247
  }
12321
- };
12322
- const { label, color, dotColor } = config2[status];
12323
- 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 })
12326
- ] });
12327
- };
12328
- const onDrop = (acceptedFiles) => {
12329
- const file = acceptedFiles[0];
12330
- if (file) {
12331
- if (acceptedFileTypes.includes(file.type)) {
12332
- setSelectedFile(file);
12333
- setFileType(file.type);
12334
- setUploadStatus("pendiente" /* PENDING */);
12335
- if (imagePreview) {
12336
- URL.revokeObjectURL(imagePreview);
12337
- setImagePreview(null);
12338
- }
12339
- if (file.type.startsWith("image/")) {
12340
- const previewUrl = URL.createObjectURL(file);
12341
- setImagePreview(previewUrl);
12342
- }
12343
- } else {
12344
- alert(t("dropfile.fileTypeNotAllowed"));
12345
- setSelectedFile(null);
12346
- setFileType(null);
12248
+ );
12249
+ }
12250
+ if (variant === "pulse") {
12251
+ return /* @__PURE__ */ jsx74(
12252
+ "div",
12253
+ {
12254
+ className: `rounded-full ${sizeClasses[size]} animate-pulse ${colorClass} ${className}`,
12255
+ style: bgStyle
12256
+ }
12257
+ );
12258
+ }
12259
+ return null;
12260
+ }
12261
+
12262
+ // src/json-renderer/catalog/catalog.props.ts
12263
+ var GLOBALLY_FORBIDDEN_PROPS = [
12264
+ "dangerouslySetInnerHTML",
12265
+ "render",
12266
+ "component",
12267
+ "children",
12268
+ // los hijos se declaran como nodos, nunca como prop
12269
+ "ref",
12270
+ "key",
12271
+ "style",
12272
+ // se permite solo si el catálogo lo declara explícitamente
12273
+ "icon",
12274
+ "actions",
12275
+ "action",
12276
+ "emptyAction",
12277
+ "fallback",
12278
+ "logo",
12279
+ "badge"
12280
+ ];
12281
+ function createCatalog(entries, excluded = {}) {
12282
+ const index = {};
12283
+ for (const entry of entries) {
12284
+ if (index[entry.type]) {
12285
+ throw new Error(`Cat\xE1logo duplicado: ${entry.type}`);
12286
+ }
12287
+ index[entry.type] = entry;
12288
+ }
12289
+ return { entries: index, excluded };
12290
+ }
12291
+ function getCatalogEntry(catalog, type) {
12292
+ return catalog.entries[type];
12293
+ }
12294
+ function isExcludedType(catalog, type) {
12295
+ return Boolean(catalog.excluded && type in catalog.excluded);
12296
+ }
12297
+ function getExclusionReason(catalog, type) {
12298
+ return catalog.excluded?.[type];
12299
+ }
12300
+
12301
+ // src/json-renderer/catalog/axzyCatalog.ts
12302
+ var COLORS = ["primary", "secondary", "success", "danger", "warning", "info", "purple", "error", "gray"];
12303
+ var SIZES = ["sm", "md", "lg"];
12304
+ var DIRECTIONS = ["row", "column"];
12305
+ var ALIGNS = ["start", "center", "end", "stretch", "baseline"];
12306
+ var JUSTIFIES = ["start", "center", "end", "between", "around", "evenly"];
12307
+ var WRAPS = ["nowrap", "wrap", "wrap-reverse"];
12308
+ var TEXT_PROPS = {
12309
+ className: { kind: "string", doc: "Clases extra del componente." }
12310
+ };
12311
+ var AXZY_CATALOG_ENTRIES = [
12312
+ {
12313
+ type: "ITText",
12314
+ component: ITText,
12315
+ children: true,
12316
+ text: true,
12317
+ summary: "Texto sem\xE1ntico. Usa `text` o `children` para el contenido.",
12318
+ props: {
12319
+ as: { kind: "enum", values: ["span", "p", "h1", "h2", "h3", "h4", "label", "div", "strong", "em"], default: "span", doc: "Etiqueta HTML sem\xE1ntica." },
12320
+ muted: { kind: "boolean", default: false, doc: "Aten\xFAa el color del texto." },
12321
+ ...TEXT_PROPS
12322
+ }
12323
+ },
12324
+ {
12325
+ type: "ITButton",
12326
+ component: ITButton,
12327
+ children: true,
12328
+ text: true,
12329
+ summary: "Bot\xF3n. `onClick` es una acci\xF3n registrada por el host.",
12330
+ props: {
12331
+ label: { kind: "string", doc: "Texto del bot\xF3n (alternativa a `text`)." },
12332
+ color: { kind: "enum", values: COLORS, default: "primary" },
12333
+ size: { kind: "enum", values: SIZES, default: "md" },
12334
+ variant: {
12335
+ kind: "enum",
12336
+ values: ["filled", "outlined", "raised", "rounded", "text", "raised-text", "icon-only", "link"],
12337
+ default: "filled"
12338
+ },
12339
+ disabled: { kind: "boolean", default: false },
12340
+ type: { kind: "enum", values: ["button", "submit", "reset"], default: "button" },
12341
+ ariaLabel: { kind: "string", doc: "Etiqueta accesible cuando el bot\xF3n no lleva texto." },
12342
+ title: { kind: "string" },
12343
+ onClick: { kind: "action", doc: "Nombre de una acci\xF3n registrada." },
12344
+ ...TEXT_PROPS
12345
+ },
12346
+ forbidden: ["icon"]
12347
+ },
12348
+ {
12349
+ type: "ITCard",
12350
+ component: ITCard,
12351
+ children: true,
12352
+ summary: "Tarjeta con t\xEDtulo, imagen y contenido.",
12353
+ props: {
12354
+ title: { kind: "string" },
12355
+ image: { kind: "string", doc: "URL de la imagen de cabecera." },
12356
+ alt: { kind: "string" },
12357
+ onClick: { kind: "action" },
12358
+ imageClassName: { kind: "string" },
12359
+ titleClassName: { kind: "string" },
12360
+ contentClassName: { kind: "string" },
12361
+ actionClassName: { kind: "string" },
12362
+ ...TEXT_PROPS
12363
+ },
12364
+ forbidden: ["actions"]
12365
+ },
12366
+ {
12367
+ type: "ITAlert",
12368
+ component: ITAlert,
12369
+ children: true,
12370
+ text: true,
12371
+ summary: "Aviso con variante sem\xE1ntica.",
12372
+ props: {
12373
+ variant: { kind: "enum", values: ["info", "success", "warning", "error"], default: "info" },
12374
+ title: { kind: "string" },
12375
+ dismissible: { kind: "boolean", default: false },
12376
+ onDismiss: { kind: "action" },
12377
+ ...TEXT_PROPS
12378
+ },
12379
+ forbidden: ["icon"]
12380
+ },
12381
+ {
12382
+ type: "ITEmptyState",
12383
+ component: ITEmptyState,
12384
+ text: true,
12385
+ summary: "Estado vac\xEDo con t\xEDtulo, descripci\xF3n y acci\xF3n.",
12386
+ props: {
12387
+ title: { kind: "string", required: true },
12388
+ description: { kind: "string" },
12389
+ ...TEXT_PROPS
12390
+ },
12391
+ forbidden: ["icon", "action"]
12392
+ },
12393
+ {
12394
+ type: "ITStatCard",
12395
+ component: ITStatCard,
12396
+ summary: "M\xE9trica con valor y tendencia.",
12397
+ props: {
12398
+ label: { kind: "string", required: true },
12399
+ value: { kind: "string", required: true, doc: "Valor ya formateado o n\xFAmero." },
12400
+ trend: { kind: "string" },
12401
+ trendDirection: { kind: "enum", values: ["up", "down", "neutral"] },
12402
+ color: { kind: "string", doc: "Color CSS del icono." },
12403
+ onClick: { kind: "action" },
12404
+ ...TEXT_PROPS
12405
+ },
12406
+ forbidden: ["icon"]
12407
+ },
12408
+ {
12409
+ type: "ITChip",
12410
+ component: ITChip,
12411
+ children: true,
12412
+ text: true,
12413
+ summary: "Etiqueta compacta, opcionalmente removible o seleccionable.",
12414
+ props: {
12415
+ label: { kind: "string" },
12416
+ color: { kind: "enum", values: COLORS, default: "gray" },
12417
+ size: { kind: "enum", values: SIZES, default: "md" },
12418
+ variant: { kind: "enum", values: ["soft", "filled", "outlined"], default: "soft" },
12419
+ removable: { kind: "boolean", default: false },
12420
+ selected: { kind: "boolean", default: false },
12421
+ disabled: { kind: "boolean", default: false },
12422
+ onRemove: { kind: "action" },
12423
+ onClick: { kind: "action" },
12424
+ ...TEXT_PROPS
12425
+ },
12426
+ forbidden: ["icon"]
12427
+ },
12428
+ {
12429
+ type: "ITBadget",
12430
+ component: ITBadget,
12431
+ children: true,
12432
+ text: true,
12433
+ summary: "Insignia de estado.",
12434
+ props: {
12435
+ label: { kind: "string" },
12436
+ color: { kind: "enum", values: COLORS, default: "primary" },
12437
+ size: { kind: "enum", values: SIZES, default: "md" },
12438
+ variant: { kind: "enum", values: ["soft", "filled", "outlined"], default: "soft" },
12439
+ ...TEXT_PROPS
12440
+ }
12441
+ },
12442
+ {
12443
+ type: "ITAvatar",
12444
+ component: ITAvatar,
12445
+ summary: "Avatar con imagen o iniciales.",
12446
+ props: {
12447
+ src: { kind: "string" },
12448
+ alt: { kind: "string" },
12449
+ initials: { kind: "string", doc: "Se usa cuando no hay imagen." },
12450
+ size: { kind: "enum", values: ["xs", "sm", "md", "lg", "xl"] },
12451
+ color: { kind: "string" },
12452
+ onClick: { kind: "action" },
12453
+ ...TEXT_PROPS
12454
+ },
12455
+ forbidden: ["badge"]
12456
+ },
12457
+ {
12458
+ type: "ITDivider",
12459
+ component: ITDivider,
12460
+ summary: "Separador horizontal o vertical.",
12461
+ props: {
12462
+ orientation: { kind: "enum", values: ["horizontal", "vertical"], default: "horizontal" },
12463
+ color: { kind: "string" },
12464
+ thickness: { kind: "string" },
12465
+ ...TEXT_PROPS
12466
+ }
12467
+ },
12468
+ {
12469
+ type: "ITStack",
12470
+ component: ITStack,
12471
+ children: true,
12472
+ summary: "Pila con direcci\xF3n y separaci\xF3n uniforme.",
12473
+ props: {
12474
+ direction: { kind: "enum", values: DIRECTIONS, default: "column" },
12475
+ spacing: { kind: "number", default: 0 },
12476
+ alignItems: { kind: "enum", values: ALIGNS },
12477
+ justifyContent: { kind: "enum", values: JUSTIFIES },
12478
+ flexWrap: { kind: "enum", values: WRAPS },
12479
+ ...TEXT_PROPS
12480
+ },
12481
+ forbidden: ["divider", "style"]
12482
+ },
12483
+ {
12484
+ type: "ITFlex",
12485
+ component: ITFlex,
12486
+ children: true,
12487
+ summary: "Contenedor flex completo.",
12488
+ props: {
12489
+ direction: { kind: "enum", values: DIRECTIONS, default: "row" },
12490
+ align: { kind: "enum", values: ALIGNS },
12491
+ justify: { kind: "enum", values: JUSTIFIES },
12492
+ wrap: { kind: "enum", values: WRAPS },
12493
+ gap: { kind: "number", default: 0 },
12494
+ grow: { kind: "boolean" },
12495
+ shrink: { kind: "boolean" },
12496
+ basis: { kind: "string" },
12497
+ ...TEXT_PROPS
12498
+ },
12499
+ forbidden: ["style", "onClick"]
12500
+ },
12501
+ {
12502
+ type: "ITGrid",
12503
+ component: ITGrid,
12504
+ children: true,
12505
+ summary: "Rejilla de 12 columnas; `item` para una celda.",
12506
+ props: {
12507
+ container: { kind: "boolean", default: false },
12508
+ item: { kind: "boolean", default: false },
12509
+ spacing: { kind: "number", default: 0 },
12510
+ columns: { kind: "integer", default: 12, doc: "Columnas del contenedor." },
12511
+ xs: { kind: "integer" },
12512
+ sm: { kind: "integer" },
12513
+ md: { kind: "integer" },
12514
+ lg: { kind: "integer" },
12515
+ xl: { kind: "integer" },
12516
+ ...TEXT_PROPS
12517
+ },
12518
+ forbidden: ["style"]
12519
+ },
12520
+ {
12521
+ type: "ITLoader",
12522
+ component: ITLoader,
12523
+ summary: "Indicador de carga.",
12524
+ props: {
12525
+ variant: { kind: "enum", values: ["spinner", "dots", "bar", "pulse"], default: "spinner" },
12526
+ size: { kind: "enum", values: ["xs", "sm", "md", "lg", "xl"], default: "md" },
12527
+ color: { kind: "string" },
12528
+ ...TEXT_PROPS
12529
+ }
12530
+ },
12531
+ {
12532
+ type: "ITSkeleton",
12533
+ component: ITSkeleton,
12534
+ summary: "Marcador de carga con forma.",
12535
+ props: {
12536
+ variant: { kind: "enum", values: ["text", "rect", "circle"], default: "text" },
12537
+ width: { kind: "string" },
12538
+ height: { kind: "string" },
12539
+ count: { kind: "integer", default: 1 },
12540
+ ...TEXT_PROPS
12541
+ },
12542
+ forbidden: ["style"]
12543
+ },
12544
+ {
12545
+ type: "ITProgress",
12546
+ component: ITProgress,
12547
+ summary: "Barra de progreso.",
12548
+ props: {
12549
+ value: { kind: "number", default: 0 },
12550
+ max: { kind: "number", default: 100 },
12551
+ variant: { kind: "enum", values: ["determinate", "indeterminate"], default: "determinate" },
12552
+ color: { kind: "enum", values: COLORS, default: "primary" },
12553
+ size: { kind: "enum", values: SIZES, default: "md" },
12554
+ ...TEXT_PROPS
12555
+ },
12556
+ forbidden: ["style"]
12557
+ },
12558
+ {
12559
+ type: "ITDataTable",
12560
+ component: ITDataTable,
12561
+ summary: "Tabla con paginaci\xF3n, orden y filtros. Los datos llegan de una fuente que el host resuelve (`$source`).",
12562
+ props: {
12563
+ columns: {
12564
+ kind: "columns",
12565
+ required: true,
12566
+ doc: "Columnas: { key, label, type, sortable, filter, currencyMX }."
12567
+ },
12568
+ fetchData: {
12569
+ kind: "data",
12570
+ required: true,
12571
+ doc: 'Referencia a una fuente: { "$source": "usuarios" }. El host la convierte en un fetcher.'
12572
+ },
12573
+ title: { kind: "string", doc: "T\xEDtulo opcional sobre la tabla." },
12574
+ defaultItemsPerPage: { kind: "integer", default: 5, doc: "Filas por p\xE1gina al abrir." },
12575
+ itemsPerPageOptions: { kind: "array", doc: "Opciones del paginador, p. ej. [5, 10, 20]." },
12576
+ debounceMs: { kind: "integer", default: 400, doc: "Espera antes de refiltrar al teclear." },
12577
+ variant: { kind: "enum", values: ["default", "striped", "bordered", "minimal"], default: "default" },
12578
+ size: { kind: "enum", values: SIZES, default: "md" },
12579
+ density: { kind: "enum", values: ["compact", "normal", "comfortable"], default: "normal" },
12580
+ layout: { kind: "enum", values: ["auto", "fixed"], default: "auto" },
12581
+ showVerticalBorder: { kind: "boolean", default: true },
12582
+ autoCardBreakpoint: { kind: "integer", default: 0, doc: "Ancho (px) por debajo del cual cae a tarjetas." },
12583
+ onRowClick: { kind: "action", doc: "Nombre de una acci\xF3n registrada; recibe la fila." },
12584
+ className: { kind: "string" },
12585
+ containerClassName: { kind: "string" }
12586
+ },
12587
+ forbidden: ["renderCard", "loadingIndicator"]
12588
+ },
12589
+ {
12590
+ type: "ITImage",
12591
+ component: image_default,
12592
+ summary: "Imagen con respaldo si falla la carga.",
12593
+ props: {
12594
+ src: { kind: "string", required: true },
12595
+ alt: { kind: "string" },
12596
+ fallback: { kind: "string", doc: "URL de respaldo." },
12597
+ onClick: { kind: "action" },
12598
+ ...TEXT_PROPS
12599
+ }
12600
+ }
12601
+ ];
12602
+ var AXZY_EXCLUDED_TYPES = {
12603
+ ITJsonRenderer: "Recursi\xF3n: un esquema no puede pedir otro renderer.",
12604
+ ITSchemaRenderer: "Recursi\xF3n: un esquema no puede pedir otro renderer.",
12605
+ ITJSONEditor: "Ejecuta entrada del usuario como c\xF3digo.",
12606
+ ITFormBuilder: "Se sustituye por el nodo `form` del motor.",
12607
+ ITWysiwyg: "Produce HTML, que se salta la lista blanca.",
12608
+ ITI18nProvider: "Lo monta el host, no el esquema.",
12609
+ ITThemeProvider: "Lo monta el host, no el esquema.",
12610
+ ITLayout: "El shell lo declara el router, no un nodo suelto.",
12611
+ ITNavbar: "El shell lo declara el router, no un nodo suelto.",
12612
+ ITSidebar: "El shell lo declara el router, no un nodo suelto.",
12613
+ ITTopBar: "El shell lo declara el router, no un nodo suelto."
12614
+ };
12615
+ var axzyCatalog = createCatalog(AXZY_CATALOG_ENTRIES, AXZY_EXCLUDED_TYPES);
12616
+ var axzyCatalogTypes = Object.keys(axzyCatalog.entries);
12617
+
12618
+ // src/json-renderer/shared/limits.ts
12619
+ var DEFAULT_LIMITS = {
12620
+ maxNodes: 5e3,
12621
+ maxDepth: 40,
12622
+ maxMsPerChunk: 8,
12623
+ actionTimeoutMs: 15e3,
12624
+ maxEffectChain: 5
12625
+ };
12626
+ function resolveLimits(overrides = {}) {
12627
+ const merged = { ...DEFAULT_LIMITS, ...overrides };
12628
+ for (const [key, value] of Object.entries(merged)) {
12629
+ if (!Number.isFinite(value) || value < 0) {
12630
+ throw new RangeError(`L\xEDmite inv\xE1lido: ${key} = ${String(value)}`);
12631
+ }
12632
+ }
12633
+ return merged;
12634
+ }
12635
+ function createLimitTracker(limits = DEFAULT_LIMITS) {
12636
+ let nodes = 0;
12637
+ let deepest = 0;
12638
+ let exceeded = false;
12639
+ return {
12640
+ visit(depth) {
12641
+ if (depth > deepest) deepest = depth;
12642
+ if (nodes >= limits.maxNodes || depth > limits.maxDepth) {
12643
+ exceeded = true;
12644
+ return false;
12645
+ }
12646
+ nodes += 1;
12647
+ return true;
12648
+ },
12649
+ get nodes() {
12650
+ return nodes;
12651
+ },
12652
+ get deepest() {
12653
+ return deepest;
12654
+ },
12655
+ get exceeded() {
12656
+ return exceeded;
12657
+ }
12658
+ };
12659
+ }
12660
+
12661
+ // src/json-renderer/kernel/NodeBoundary.tsx
12662
+ import React16 from "react";
12663
+
12664
+ // src/json-renderer/shared/errors.ts
12665
+ var JsonEngineError = class extends Error {
12666
+ constructor(code, message, path, hint) {
12667
+ super(`${code} ${path ? `en ${path}: ` : ""}${message}`);
12668
+ /** Código estable del catálogo de avisos. */
12669
+ __publicField(this, "code");
12670
+ /** Ruta del esquema donde se produjo. */
12671
+ __publicField(this, "path");
12672
+ /** Sugerencia accionable. */
12673
+ __publicField(this, "hint");
12674
+ this.name = "JsonEngineError";
12675
+ this.code = code;
12676
+ this.path = path;
12677
+ this.hint = hint;
12678
+ }
12679
+ /** Convierte el error en el aviso que consume la interfaz y el informe. */
12680
+ toIssue(severity = "error") {
12681
+ return {
12682
+ code: this.code,
12683
+ severity,
12684
+ message: this.message.replace(/^JR\d{3}\s?(en .*?: )?/, ""),
12685
+ path: this.path,
12686
+ hint: this.hint
12687
+ };
12688
+ }
12689
+ };
12690
+ function issue(code, message, path = "", options = {}) {
12691
+ return {
12692
+ code,
12693
+ severity: options.severity ?? "error",
12694
+ message,
12695
+ path,
12696
+ hint: options.hint
12697
+ };
12698
+ }
12699
+
12700
+ // src/json-renderer/kernel/NodeBoundary.tsx
12701
+ var NodeBoundary = class extends React16.Component {
12702
+ constructor() {
12703
+ super(...arguments);
12704
+ __publicField(this, "state", { failed: false });
12705
+ }
12706
+ static getDerivedStateFromError() {
12707
+ return { failed: true };
12708
+ }
12709
+ componentDidCatch(error) {
12710
+ this.props.onError?.(error, this.props.path);
12711
+ }
12712
+ render() {
12713
+ if (this.state.failed) return this.props.fallback ?? null;
12714
+ return this.props.children;
12715
+ }
12716
+ };
12717
+
12718
+ // src/json-renderer/stream/tolerantParse.ts
12719
+ function isPending(value) {
12720
+ return typeof value === "object" && value !== null && value.$pending === true;
12721
+ }
12722
+ var TRUNCATED_CONTAINERS = /* @__PURE__ */ new WeakSet();
12723
+ function finalize(value, counter) {
12724
+ if (Array.isArray(value)) {
12725
+ return value.map((item) => finalize(item, counter)).filter((item) => item !== void 0);
12726
+ }
12727
+ if (value && typeof value === "object") {
12728
+ if (isPending(value)) {
12729
+ counter.pending += 1;
12730
+ return void 0;
12731
+ }
12732
+ const out = { ...value };
12733
+ let hasPendingChild = false;
12734
+ for (const [key, nested] of Object.entries(out)) {
12735
+ const resolved = finalize(nested, counter);
12736
+ if (resolved === void 0 && isPending(nested)) {
12737
+ hasPendingChild = true;
12738
+ delete out[key];
12739
+ } else {
12740
+ out[key] = resolved;
12741
+ }
12742
+ }
12743
+ const truncated = TRUNCATED_CONTAINERS.has(value);
12744
+ if ((hasPendingChild || truncated) && "type" in out) {
12745
+ out.$status = "pending";
12746
+ }
12747
+ return out;
12748
+ }
12749
+ return value;
12750
+ }
12751
+ var WHITESPACE = /* @__PURE__ */ new Set([" ", " ", "\n", "\r"]);
12752
+ var TolerantParser = class {
12753
+ constructor(text) {
12754
+ __publicField(this, "text", text);
12755
+ __publicField(this, "index", 0);
12756
+ /** `true` cuando se detuvo porque el texto se acabó (y no por un error). */
12757
+ __publicField(this, "truncated", false);
12758
+ /** `true` cuando encontró algo que no puede interpretar. */
12759
+ __publicField(this, "broken", false);
12760
+ }
12761
+ /** Offset actual. */
12762
+ get offset() {
12763
+ return this.index;
12764
+ }
12765
+ /** `true` si el consumo se detuvo por falta de texto. */
12766
+ get isTruncated() {
12767
+ return this.truncated;
12768
+ }
12769
+ /** Salta el espacio en blanco. */
12770
+ skip() {
12771
+ while (this.index < this.text.length && WHITESPACE.has(this.text[this.index])) this.index += 1;
12772
+ }
12773
+ /** Carácter actual, o `undefined` si se acabó. */
12774
+ peek() {
12775
+ return this.text[this.index];
12776
+ }
12777
+ /** Intenta consumir un literal (`true`, `false`, `null`). */
12778
+ tryLiteral(literal) {
12779
+ if (!this.text.startsWith(literal, this.index)) return void 0;
12780
+ const end = this.index + literal.length;
12781
+ if (end > this.text.length) {
12782
+ this.index = this.text.length;
12783
+ this.truncated = true;
12784
+ return { $pending: true };
12785
+ }
12786
+ if (this.text.slice(this.index, end) !== literal) {
12787
+ const prefix = this.text.slice(this.index);
12788
+ if (literal.startsWith(prefix)) {
12789
+ this.index = this.text.length;
12790
+ this.truncated = true;
12791
+ return { $pending: true };
12792
+ }
12793
+ return void 0;
12794
+ }
12795
+ this.index = end;
12796
+ if (literal === "true") return true;
12797
+ if (literal === "false") return false;
12798
+ return null;
12799
+ }
12800
+ /** Lee una cadena. Marca pendiente si no encuentra la comilla de cierre. */
12801
+ readString() {
12802
+ this.index += 1;
12803
+ let out = "";
12804
+ while (this.index < this.text.length) {
12805
+ const char = this.text[this.index];
12806
+ if (char === "\\") {
12807
+ const next = this.text[this.index + 1];
12808
+ if (next === void 0) {
12809
+ this.index = this.text.length;
12810
+ this.truncated = true;
12811
+ return { $pending: true };
12812
+ }
12813
+ out += unescapeChar(next);
12814
+ this.index += 2;
12815
+ continue;
12816
+ }
12817
+ if (char === '"') {
12818
+ this.index += 1;
12819
+ return out;
12820
+ }
12821
+ out += char;
12822
+ this.index += 1;
12823
+ }
12824
+ this.truncated = true;
12825
+ return { $pending: true };
12826
+ }
12827
+ /** Lee un número. Devuelve el texto crudo como número, o pendiente. */
12828
+ readNumber() {
12829
+ const start = this.index;
12830
+ if (this.peek() === "-") this.index += 1;
12831
+ while (this.index < this.text.length && /[0-9.eE+-]/.test(this.text[this.index])) this.index += 1;
12832
+ const raw = this.text.slice(start, this.index);
12833
+ if (raw === "" || raw === "-") {
12834
+ this.index = this.text.length;
12835
+ this.truncated = true;
12836
+ return { $pending: true };
12837
+ }
12838
+ const value = Number(raw);
12839
+ if (Number.isNaN(value)) {
12840
+ this.broken = true;
12841
+ return { $pending: true };
12842
+ }
12843
+ return value;
12844
+ }
12845
+ /** Marca un contenedor como truncado (se cerró por falta de texto). */
12846
+ markTruncated(container) {
12847
+ this.truncated = true;
12848
+ TRUNCATED_CONTAINERS.add(container);
12849
+ }
12850
+ /** Lee un array. */
12851
+ readArray() {
12852
+ this.index += 1;
12853
+ const items = [];
12854
+ this.skip();
12855
+ if (this.peek() === "]") {
12856
+ this.index += 1;
12857
+ return items;
12858
+ }
12859
+ for (; ; ) {
12860
+ this.skip();
12861
+ if (this.peek() === void 0) {
12862
+ if (items.length === 0) {
12863
+ this.truncated = true;
12864
+ return { $pending: true };
12865
+ }
12866
+ this.markTruncated(items);
12867
+ return items;
12868
+ }
12869
+ const value = this.readValue();
12870
+ if (isPending(value)) {
12871
+ if (items.length === 0) {
12872
+ this.truncated = true;
12873
+ return { $pending: true };
12874
+ }
12875
+ this.markTruncated(items);
12876
+ return items;
12877
+ }
12878
+ items.push(value);
12879
+ this.skip();
12880
+ const char = this.peek();
12881
+ if (char === ",") {
12882
+ this.index += 1;
12883
+ continue;
12884
+ }
12885
+ if (char === "]") {
12886
+ this.index += 1;
12887
+ return items;
12888
+ }
12889
+ if (char === void 0) {
12890
+ this.markTruncated(items);
12891
+ return items;
12892
+ }
12893
+ this.broken = true;
12894
+ return items;
12895
+ }
12896
+ }
12897
+ /** Lee un objeto. */
12898
+ readObject() {
12899
+ this.index += 1;
12900
+ const out = {};
12901
+ this.skip();
12902
+ if (this.peek() === "}") {
12903
+ this.index += 1;
12904
+ return out;
12905
+ }
12906
+ for (; ; ) {
12907
+ this.skip();
12908
+ const char = this.peek();
12909
+ if (char === void 0) {
12910
+ if (!Object.keys(out).length) {
12911
+ this.truncated = true;
12912
+ return { $pending: true };
12913
+ }
12914
+ this.markTruncated(out);
12915
+ return out;
12916
+ }
12917
+ if (char !== '"') {
12918
+ this.broken = true;
12919
+ if (!Object.keys(out).length) return { $pending: true };
12920
+ this.markTruncated(out);
12921
+ return out;
12922
+ }
12923
+ const key = this.readString();
12924
+ if (isPending(key)) {
12925
+ if (!Object.keys(out).length) {
12926
+ this.truncated = true;
12927
+ return { $pending: true };
12928
+ }
12929
+ this.markTruncated(out);
12930
+ return out;
12931
+ }
12932
+ this.skip();
12933
+ if (this.peek() !== ":") {
12934
+ this.broken = this.peek() !== void 0;
12935
+ if (!Object.keys(out).length) {
12936
+ this.truncated = true;
12937
+ return { $pending: true };
12938
+ }
12939
+ this.markTruncated(out);
12940
+ return out;
12941
+ }
12942
+ this.index += 1;
12943
+ this.skip();
12944
+ const value = this.readValue();
12945
+ if (isPending(value)) {
12946
+ if (!Object.keys(out).length) {
12947
+ this.truncated = true;
12948
+ return { $pending: true };
12949
+ }
12950
+ this.markTruncated(out);
12951
+ return out;
12952
+ }
12953
+ out[key] = value;
12954
+ this.skip();
12955
+ const separator = this.peek();
12956
+ if (separator === ",") {
12957
+ this.index += 1;
12958
+ continue;
12959
+ }
12960
+ if (separator === "}") {
12961
+ this.index += 1;
12962
+ return out;
12963
+ }
12964
+ if (separator === void 0) {
12965
+ this.markTruncated(out);
12966
+ return out;
12967
+ }
12968
+ this.broken = true;
12969
+ return out;
12970
+ }
12971
+ }
12972
+ /** Lee cualquier valor. */
12973
+ readValue() {
12974
+ this.skip();
12975
+ const char = this.peek();
12976
+ if (char === void 0) {
12977
+ this.truncated = true;
12978
+ return { $pending: true };
12979
+ }
12980
+ if (char === "{") return this.readObject();
12981
+ if (char === "[") return this.readArray();
12982
+ if (char === '"') {
12983
+ const value = this.readString();
12984
+ return isPending(value) ? { $pending: true } : value;
12985
+ }
12986
+ if (char === "t" || char === "f" || char === "n") {
12987
+ const literal = char === "t" ? this.tryLiteral("true") : char === "f" ? this.tryLiteral("false") : this.tryLiteral("null");
12988
+ return literal === void 0 ? { $pending: true } : literal;
12989
+ }
12990
+ if (char === "-" || /[0-9]/.test(char)) return this.readNumber();
12991
+ this.broken = true;
12992
+ this.index = this.text.length;
12993
+ return { $pending: true };
12994
+ }
12995
+ /** Parsea el documento completo (o hasta donde llegue). */
12996
+ parse() {
12997
+ this.skip();
12998
+ if (this.peek() === void 0) {
12999
+ return { value: void 0, truncated: true, broken: false };
13000
+ }
13001
+ const value = this.readValue();
13002
+ this.skip();
13003
+ const truncated = this.truncated || this.index < this.text.length;
13004
+ return { value, truncated, broken: this.broken };
13005
+ }
13006
+ };
13007
+ function unescapeChar(char) {
13008
+ switch (char) {
13009
+ case "n":
13010
+ return "\n";
13011
+ case "t":
13012
+ return " ";
13013
+ case "r":
13014
+ return "\r";
13015
+ case "b":
13016
+ return "\b";
13017
+ case "f":
13018
+ return "\f";
13019
+ default:
13020
+ return char;
13021
+ }
13022
+ }
13023
+ function parsePartialSchema(text) {
13024
+ const parser = new TolerantParser(text);
13025
+ const { value, truncated, broken } = parser.parse();
13026
+ if (value === void 0) {
13027
+ return { tree: null, status: "pending", offset: parser.offset, broken, pendingNodes: 0 };
13028
+ }
13029
+ const counter = { pending: 0 };
13030
+ const finalized = finalize(value, counter);
13031
+ if (finalized === void 0 || finalized === null) {
13032
+ return { tree: null, status: "pending", offset: parser.offset, broken, pendingNodes: counter.pending };
13033
+ }
13034
+ const tree = finalized;
13035
+ return {
13036
+ tree,
13037
+ status: truncated || counter.pending > 0 ? "pending" : "complete",
13038
+ offset: parser.offset,
13039
+ broken,
13040
+ pendingNodes: counter.pending
13041
+ };
13042
+ }
13043
+ function isNodePending(node) {
13044
+ return node?.$status === "pending";
13045
+ }
13046
+
13047
+ // src/json-renderer/kernel/renderNode.tsx
13048
+ import React17 from "react";
13049
+
13050
+ // src/json-renderer/shared/paths.ts
13051
+ function pushPath(path, segment) {
13052
+ return [...path, segment];
13053
+ }
13054
+ function formatPath(path) {
13055
+ let out = "";
13056
+ for (const segment of path) {
13057
+ if (typeof segment === "number") out += `[${segment}]`;
13058
+ else out += out ? `.${segment}` : segment;
13059
+ }
13060
+ return out;
13061
+ }
13062
+ function parsePath(rendered) {
13063
+ if (!rendered) return [];
13064
+ return rendered.split(/\.(?![^[]*])/).flatMap((part) => {
13065
+ const match = part.match(/^([^[\]]*)((?:\[\d+\])*)$/);
13066
+ if (!match) return [part];
13067
+ const [, key, indexes] = match;
13068
+ const segments = key ? [key] : [];
13069
+ for (const index of indexes.match(/\d+/g) ?? []) segments.push(Number(index));
13070
+ return segments;
13071
+ });
13072
+ }
13073
+ function readPath(source, path) {
13074
+ let cursor = source;
13075
+ for (const segment of path) {
13076
+ if (cursor === null || typeof cursor !== "object") return void 0;
13077
+ cursor = cursor[segment];
13078
+ }
13079
+ return cursor;
13080
+ }
13081
+ function hasPath(source, path) {
13082
+ if (path.length === 0) return true;
13083
+ const parent = readPath(source, path.slice(0, -1));
13084
+ if (parent === null || typeof parent !== "object") return false;
13085
+ return Object.prototype.hasOwnProperty.call(parent, path[path.length - 1]);
13086
+ }
13087
+ function propPath(nodePath, prop) {
13088
+ return pushPath(pushPath(nodePath, "props"), prop);
13089
+ }
13090
+
13091
+ // src/json-renderer/catalog/resolve.ts
13092
+ function isSchemaReference(value) {
13093
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
13094
+ const keys = Object.keys(value);
13095
+ if (keys.length === 0) return false;
13096
+ return keys.some((key) => key === "i18n" || key.startsWith("$"));
13097
+ }
13098
+ function coerce(value, spec) {
13099
+ switch (spec.kind) {
13100
+ case "string":
13101
+ if (typeof value === "string") return value;
13102
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
13103
+ return void 0;
13104
+ case "number":
13105
+ case "integer": {
13106
+ if (typeof value === "number" && Number.isFinite(value)) {
13107
+ return spec.kind === "integer" ? Math.trunc(value) : value;
13108
+ }
13109
+ if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) {
13110
+ const parsed = Number(value);
13111
+ return spec.kind === "integer" ? Math.trunc(parsed) : parsed;
13112
+ }
13113
+ return void 0;
13114
+ }
13115
+ case "boolean":
13116
+ if (typeof value === "boolean") return value;
13117
+ if (value === "true") return true;
13118
+ if (value === "false") return false;
13119
+ return void 0;
13120
+ case "enum":
13121
+ if (typeof value !== "string") return void 0;
13122
+ return spec.values?.includes(value) ? value : void 0;
13123
+ case "array":
13124
+ return Array.isArray(value) ? value : void 0;
13125
+ case "object":
13126
+ return value && typeof value === "object" ? value : void 0;
13127
+ default:
13128
+ return value;
13129
+ }
13130
+ }
13131
+ function resolveNode(node, catalog, path) {
13132
+ const issues = [];
13133
+ const type = node.type;
13134
+ if (typeof type !== "string" || type === "") {
13135
+ issues.push(issue("JR021", "El nodo no declara `type`.", formatPath(path), { severity: "error" }));
13136
+ return { ok: false, issues };
13137
+ }
13138
+ if (isExcludedType(catalog, type)) {
13139
+ const reason = getExclusionReason(catalog, type);
13140
+ issues.push(
13141
+ issue("JR010", `El tipo \`${type}\` est\xE1 excluido del cat\xE1logo.`, formatPath(path), {
13142
+ severity: "error",
13143
+ hint: reason
13144
+ })
13145
+ );
13146
+ return { ok: false, issues };
13147
+ }
13148
+ const entry = catalog.entries[type];
13149
+ if (!entry) {
13150
+ const known = Object.keys(catalog.entries).slice(0, 8).join(", ");
13151
+ issues.push(
13152
+ issue("JR010", `El tipo \`${type}\` no est\xE1 en el cat\xE1logo.`, formatPath(path), {
13153
+ severity: "error",
13154
+ hint: `Tipos disponibles (primeros 8): ${known}\u2026`
13155
+ })
13156
+ );
13157
+ return { ok: false, issues };
13158
+ }
13159
+ const specs = entry.props ?? {};
13160
+ const props = {};
13161
+ const actions = {};
13162
+ const input = node.props ?? {};
13163
+ for (const [name, spec] of Object.entries(specs)) {
13164
+ if (spec.default !== void 0) props[name] = spec.default;
13165
+ }
13166
+ for (const [name, raw] of Object.entries(input)) {
13167
+ const forbiddenByEntry = entry.forbidden?.includes(name);
13168
+ const forbiddenGlobally = GLOBALLY_FORBIDDEN_PROPS.includes(name);
13169
+ if (forbiddenByEntry || forbiddenGlobally) {
13170
+ issues.push(
13171
+ issue("JR011", `La prop \`${name}\` est\xE1 prohibida en \`${type}\`.`, formatPath(propPath(path, name)), {
13172
+ severity: "warning",
13173
+ hint: "Los nodos React se declaran como hijos del esquema, no como props."
13174
+ })
13175
+ );
13176
+ continue;
13177
+ }
13178
+ const spec = specs[name];
13179
+ if (!spec) {
13180
+ issues.push(
13181
+ issue("JR011", `La prop \`${name}\` no est\xE1 declarada para \`${type}\`.`, formatPath(propPath(path, name)), {
13182
+ severity: "warning",
13183
+ hint: "Se ignora. Si es necesaria, a\xF1\xE1dela al cat\xE1logo con su tipo."
13184
+ })
13185
+ );
13186
+ continue;
13187
+ }
13188
+ if (spec.kind === "action") {
13189
+ actions[name] = raw;
13190
+ continue;
13191
+ }
13192
+ if (isSchemaReference(raw)) {
13193
+ props[name] = raw;
13194
+ continue;
13195
+ }
13196
+ const value = coerce(raw, spec);
13197
+ if (value === void 0) {
13198
+ issues.push(
13199
+ issue(
13200
+ "JR011",
13201
+ `Valor inv\xE1lido para \`${name}\` en \`${type}\`.`,
13202
+ formatPath(propPath(path, name)),
13203
+ { severity: "warning", hint: spec.values ? `Admitidos: ${spec.values.join(", ")}` : `Se esperaba ${spec.kind}.` }
13204
+ )
13205
+ );
13206
+ continue;
13207
+ }
13208
+ props[name] = value;
13209
+ }
13210
+ for (const [name, spec] of Object.entries(specs)) {
13211
+ if (spec.required && props[name] === void 0) {
13212
+ issues.push(
13213
+ issue("JR011", `Falta la prop obligatoria \`${name}\` en \`${type}\`.`, formatPath(propPath(path, name)), {
13214
+ severity: "error"
13215
+ })
13216
+ );
13217
+ }
13218
+ }
13219
+ if (node.children !== void 0 && !entry.children) {
13220
+ issues.push(
13221
+ issue("JR011", `\`${type}\` no acepta \`children\`.`, formatPath([...path, "children"]), {
13222
+ severity: "warning",
13223
+ hint: "Los hijos se ignoran."
13224
+ })
13225
+ );
13226
+ }
13227
+ return { ok: true, entry, props, actions, issues };
13228
+ }
13229
+
13230
+ // src/json-renderer/kernel/renderNode.tsx
13231
+ function childList(node) {
13232
+ if (!node || node.children === void 0 || node.children === null) return [];
13233
+ return Array.isArray(node.children) ? node.children : [node.children];
13234
+ }
13235
+ function renderNode(node, options) {
13236
+ const { catalog, path, issues, renderChildren } = options;
13237
+ if (!node || typeof node !== "object") {
13238
+ return null;
13239
+ }
13240
+ if (isNodePending(node)) {
13241
+ return options.pendingFallback ?? null;
13242
+ }
13243
+ const resolved = resolveNode(node, catalog, path);
13244
+ issues.push(...resolved.issues);
13245
+ if (!resolved.ok) {
13246
+ return null;
13247
+ }
13248
+ const { entry, props, actions } = resolved;
13249
+ const finalProps = {};
13250
+ for (const [name, value] of Object.entries(props)) {
13251
+ finalProps[name] = options.resolveValue ? options.resolveValue(value, path) : value;
13252
+ }
13253
+ for (const [name, action] of Object.entries(actions)) {
13254
+ const handler = options.resolveAction?.(node, name, action, path);
13255
+ if (typeof handler === "function") finalProps[name] = handler;
13256
+ }
13257
+ const content = renderChildren ? renderChildren(node, path) : null;
13258
+ const rawText = entry.text && node.text !== void 0 ? node.text : void 0;
13259
+ const text = rawText === void 0 ? void 0 : options.resolveValue ? options.resolveValue(rawText, path) : rawText;
13260
+ const children = content ?? text;
13261
+ const element = React17.createElement(
13262
+ entry.component,
13263
+ { ...finalProps, key: node.id ?? path.join("-"), id: node.id },
13264
+ children
13265
+ );
13266
+ return options.wrap ? options.wrap(node, path, element) : element;
13267
+ }
13268
+
13269
+ // src/json-renderer/kernel/partial.ts
13270
+ function auditTree(schema, limits) {
13271
+ const tracker = createLimitTracker(limits);
13272
+ const issues = [];
13273
+ let pending = 0;
13274
+ let depth = 0;
13275
+ const walk = (node, path, level) => {
13276
+ if (!node || typeof node !== "object") return;
13277
+ if (!tracker.visit(level)) return;
13278
+ if (level > depth) depth = level;
13279
+ if (isNodePending(node)) pending += 1;
13280
+ const children = childList(node);
13281
+ children.forEach((child, index) => {
13282
+ walk(child, `${path}[${index}]`, level + 1);
13283
+ });
13284
+ if (node.fallback) walk(node.fallback, `${path}.fallback`, level + 1);
13285
+ };
13286
+ const content = Array.isArray(schema.content) ? schema.content : [schema.content];
13287
+ content.forEach((node, index) => walk(node, `content[${index}]`, 0));
13288
+ if (tracker.exceeded) {
13289
+ issues.push(
13290
+ issue(
13291
+ "JR013",
13292
+ `El esquema supera el presupuesto (${tracker.nodes} nodos, profundidad ${tracker.deepest}).`,
13293
+ "content",
13294
+ {
13295
+ severity: "warning",
13296
+ hint: `M\xE1ximo configurado: ${limits.maxNodes} nodos y profundidad ${limits.maxDepth}. La parte que sobra no se pinta.`
13297
+ }
13298
+ )
13299
+ );
13300
+ }
13301
+ return { nodes: tracker.nodes, depth: tracker.deepest, pending, exceeded: tracker.exceeded, issues };
13302
+ }
13303
+ function countPendingNodes(schema) {
13304
+ if (!schema) return 0;
13305
+ let total = 0;
13306
+ const walk = (node) => {
13307
+ if (!node || typeof node !== "object") return;
13308
+ if (isNodePending(node)) total += 1;
13309
+ for (const child of childList(node)) walk(child);
13310
+ };
13311
+ const content = Array.isArray(schema.content) ? schema.content : [schema.content];
13312
+ for (const node of content) walk(node);
13313
+ return total;
13314
+ }
13315
+
13316
+ // src/json-renderer/kernel/SchemaRenderer.tsx
13317
+ import { Fragment as Fragment13, jsx as jsx75 } from "react/jsx-runtime";
13318
+ function renderTree(node, path, context, level) {
13319
+ if (!node || typeof node !== "object") return null;
13320
+ if (level > context.limits.maxDepth) return null;
13321
+ const issues = context.issues;
13322
+ if (node.id) context.nodeIds.add(node.id);
13323
+ const reportIssue = (issue2) => {
13324
+ issues.push(issue2);
13325
+ context.onIssue?.(issue2);
13326
+ };
13327
+ const issuesBefore = issues.length;
13328
+ const element = renderNode(node, {
13329
+ catalog: context.catalog,
13330
+ path,
13331
+ issues,
13332
+ resolveValue: context.resolveValue,
13333
+ resolveAction: context.resolveAction,
13334
+ pendingFallback: context.pendingFallback,
13335
+ renderChildren: (current, currentPath) => {
13336
+ const children = childList(current);
13337
+ if (children.length === 0) return void 0;
13338
+ return children.map(
13339
+ (child, index) => renderTree(child, [...currentPath, "children", index], context, level + 1)
13340
+ );
13341
+ }
13342
+ });
13343
+ for (let index = issuesBefore; index < issues.length; index += 1) {
13344
+ context.onIssue?.(issues[index]);
13345
+ }
13346
+ const fallback = node.fallback ? renderTree(node.fallback, [...path, "fallback"], context, level + 1) : context.pendingFallback ?? null;
13347
+ const wrapped = /* @__PURE__ */ jsx75(
13348
+ NodeBoundary,
13349
+ {
13350
+ path: path.join("."),
13351
+ fallback,
13352
+ onError: (error, errorPath) => reportIssue({
13353
+ code: "JR012",
13354
+ severity: "error",
13355
+ message: error.message,
13356
+ path: errorPath,
13357
+ hint: "El nodo se ha aislado; el resto de la pantalla sigue pint\xE1ndose."
13358
+ }),
13359
+ children: element
13360
+ },
13361
+ String(path.join("-"))
13362
+ );
13363
+ return wrapped;
13364
+ }
13365
+ function ITSchemaRenderer({
13366
+ schema,
13367
+ catalog = axzyCatalog,
13368
+ limits,
13369
+ resolveValue,
13370
+ resolveAction,
13371
+ pendingFallback,
13372
+ onIssue,
13373
+ className
13374
+ }) {
13375
+ const resolvedLimits = useMemo16(() => resolveLimits(limits), [limits]);
13376
+ const issues = [];
13377
+ const nodeIds = /* @__PURE__ */ new Set();
13378
+ const audit = useMemo16(
13379
+ () => schema ? auditTree(schema, resolvedLimits) : null,
13380
+ [schema, resolvedLimits]
13381
+ );
13382
+ const context = useMemo16(
13383
+ () => ({
13384
+ catalog,
13385
+ nodeIds,
13386
+ limits: resolvedLimits,
13387
+ issues,
13388
+ onIssue,
13389
+ resolveValue,
13390
+ resolveAction,
13391
+ pendingFallback
13392
+ }),
13393
+ // `issues` es un array nuevo en cada render a propósito: acumular avisos
13394
+ // entre renders duplicaría los avisos de esquemas que no han cambiado.
13395
+ // eslint-disable-next-line react-hooks/exhaustive-deps
13396
+ [catalog, resolvedLimits, onIssue, resolveValue, resolveAction, pendingFallback]
13397
+ );
13398
+ const content = schema ? (Array.isArray(schema.content) ? schema.content : [schema.content]).filter(
13399
+ (node) => Boolean(node) && typeof node === "object"
13400
+ ) : [];
13401
+ const children = content.slice(0, resolvedLimits.maxNodes).map((node, index) => renderTree(node, ["content", index], context, 0)).filter(Boolean);
13402
+ const collected = [...audit?.issues ?? [], ...issues];
13403
+ const signature = collected.map((issue2) => `${issue2.code}:${issue2.path}`).join("|");
13404
+ const reported = useRef23("");
13405
+ useEffect18(() => {
13406
+ const all = [...collected];
13407
+ for (const id of nodeIds) {
13408
+ if (!document.getElementById(id)) {
13409
+ all.push({
13410
+ code: "JR014",
13411
+ severity: "warning",
13412
+ message: `El \`id\` "${id}" no lleg\xF3 al DOM.`,
13413
+ path: id,
13414
+ 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."
13415
+ });
13416
+ }
13417
+ }
13418
+ const firma = all.map((issue2) => `${issue2.code}:${issue2.path}`).join("|");
13419
+ if (!onIssue || reported.current === firma) return;
13420
+ reported.current = firma;
13421
+ for (const issue2 of all) onIssue(issue2);
13422
+ }, [signature, onIssue]);
13423
+ if (!schema || children.length === 0) return null;
13424
+ return className ? /* @__PURE__ */ jsx75("div", { className, children }) : /* @__PURE__ */ jsx75(Fragment13, { children });
13425
+ }
13426
+
13427
+ // src/json-renderer/validation/validate.ts
13428
+ var CURRENT_SCHEMA_VERSION = 1;
13429
+ function validateNodes(node, path, catalog, errors, warnings) {
13430
+ if (!node || typeof node !== "object") {
13431
+ errors.push(issue("JR021", "El nodo no es un objeto.", formatPath(path), { severity: "error" }));
13432
+ return 0;
13433
+ }
13434
+ if (isNodePending(node)) return 1;
13435
+ const resolved = resolveNode(node, catalog, path);
13436
+ for (const item of resolved.issues) {
13437
+ (item.severity === "error" ? errors : warnings).push(item);
13438
+ }
13439
+ let pending = 0;
13440
+ const children = node.children === void 0 ? [] : Array.isArray(node.children) ? node.children : [node.children];
13441
+ children.forEach((child, index) => {
13442
+ pending += validateNodes(child, [...path, "children", index], catalog, errors, warnings);
13443
+ });
13444
+ return pending;
13445
+ }
13446
+ function validateSchema(schema, options = {}) {
13447
+ const catalog = options.catalog ?? axzyCatalog;
13448
+ const maxVersion = options.maxVersion ?? CURRENT_SCHEMA_VERSION;
13449
+ const errors = [];
13450
+ const warnings = [];
13451
+ if (schema === null || schema === void 0) {
13452
+ return { verdict: "invalid", errors: [issue("JR020", "No hay esquema que validar.", "")], warnings, pendingNodes: 0 };
13453
+ }
13454
+ if (typeof schema !== "object" || Array.isArray(schema)) {
13455
+ return {
13456
+ verdict: "invalid",
13457
+ errors: [issue("JR020", "El esquema debe ser un objeto.", "", { severity: "error" })],
13458
+ warnings,
13459
+ pendingNodes: 0
13460
+ };
13461
+ }
13462
+ const candidate = schema;
13463
+ if (candidate.$schema !== void 0 && candidate.$schema !== "axzy/screen") {
13464
+ errors.push(
13465
+ issue("JR020", `El formato declarado no es \`axzy/screen\`.`, "$schema", {
13466
+ severity: "error",
13467
+ hint: 'Usa `$schema: "axzy/screen"` o quita la propiedad.'
13468
+ })
13469
+ );
13470
+ }
13471
+ if (candidate.version === void 0) {
13472
+ errors.push(issue("JR020", "Falta `version` en el esquema.", "version", { severity: "error" }));
13473
+ } else if (typeof candidate.version !== "number" || !Number.isInteger(candidate.version)) {
13474
+ errors.push(issue("JR020", "`version` debe ser un entero.", "version", { severity: "error" }));
13475
+ } else if (candidate.version > maxVersion) {
13476
+ errors.push(
13477
+ issue("JR020", `La versi\xF3n ${candidate.version} es m\xE1s nueva que la soportada (${maxVersion}).`, "version", {
13478
+ severity: "error",
13479
+ hint: "Actualiza el motor o migra el esquema."
13480
+ })
13481
+ );
13482
+ }
13483
+ if (typeof candidate.id !== "string" || candidate.id.trim() === "") {
13484
+ errors.push(issue("JR020", "Falta `id` en el esquema.", "id", { severity: "error" }));
13485
+ }
13486
+ if (candidate.content === void 0) {
13487
+ errors.push(issue("JR020", "El esquema no declara `content`.", "content", { severity: "error" }));
13488
+ return { verdict: "invalid", errors, warnings, pendingNodes: 0, version: candidate.version };
13489
+ }
13490
+ const content = Array.isArray(candidate.content) ? candidate.content : [candidate.content];
13491
+ if (content.length === 0) {
13492
+ warnings.push(
13493
+ issue("JR021", "`content` est\xE1 vac\xEDo: la pantalla se pinta sin nodos.", "content", { severity: "warning" })
13494
+ );
13495
+ }
13496
+ let pendingNodes = 0;
13497
+ content.map((node, index) => ({ node, index })).filter(({ node }) => node !== void 0 && node !== null).forEach(({ node, index }) => {
13498
+ pendingNodes += validateNodes(node, ["content", index], catalog, errors, warnings);
13499
+ });
13500
+ const verdict = errors.length > 0 ? "invalid" : pendingNodes > 0 ? "partial" : "valid";
13501
+ return { verdict, errors, warnings, pendingNodes, version: candidate.version };
13502
+ }
13503
+
13504
+ // src/json-renderer/validation/migrate.ts
13505
+ var DEFAULT_MIGRATIONS = {};
13506
+ function migrateSchema(schema, targetVersion, migrations = DEFAULT_MIGRATIONS) {
13507
+ const from = typeof schema.version === "number" ? schema.version : 0;
13508
+ const issues = [];
13509
+ if (from === targetVersion) {
13510
+ return { schema, migrated: false, from, to: targetVersion, issues };
13511
+ }
13512
+ if (from > targetVersion) {
13513
+ issues.push(
13514
+ issue("JR020", `El esquema es de una versi\xF3n posterior (${from}) a la del motor (${targetVersion}).`, "version", {
13515
+ severity: "error",
13516
+ hint: "Actualiza el motor; no se puede degradar un esquema."
13517
+ })
13518
+ );
13519
+ return { schema, migrated: false, from, to: targetVersion, issues };
13520
+ }
13521
+ let current = schema;
13522
+ let version = from;
13523
+ while (version < targetVersion) {
13524
+ const migration = migrations[version];
13525
+ if (!migration) {
13526
+ issues.push(
13527
+ issue("JR070", `No hay migraci\xF3n registrada de la versi\xF3n ${version} a la ${version + 1}.`, "version", {
13528
+ severity: "error",
13529
+ hint: "Registra la migraci\xF3n en `migrations` o guarda el esquema en la versi\xF3n actual."
13530
+ })
13531
+ );
13532
+ return { schema: current, migrated: false, from, to: version, issues };
13533
+ }
13534
+ current = { ...migration(current), version: version + 1 };
13535
+ version += 1;
13536
+ }
13537
+ return { schema: current, migrated: version !== from, from, to: version, issues };
13538
+ }
13539
+
13540
+ // src/json-renderer/vocabulary/buildContract.ts
13541
+ var RULES = [
13542
+ 'Emite SOLO JSON v\xE1lido con la forma: { $schema: "axzy/screen", version, id, content }.',
13543
+ "`content` es un nodo o un array de nodos; cada nodo necesita `type` del cat\xE1logo.",
13544
+ "Usa solo props declaradas para ese `type`; el resto se ignora y se avisa.",
13545
+ "Los hijos se expresan con `children` (nodos) y los textos con `text`, nunca con props de nodo React.",
13546
+ 'Las acciones se declaran por nombre: `"onClick": { "action": "nombre.registrado" }`. No hay c\xF3digo en el JSON.',
13547
+ "Prohibido: HTML crudo, URLs, fetch, expresiones JS y props como icon/actions/render.",
13548
+ 'Los textos visibles deben ser claves de i18n: { "i18n": "namespace.clave" }.'
13549
+ ];
13550
+ function buildMinimal(entry) {
13551
+ const props = {};
13552
+ for (const [name, spec] of Object.entries(entry.props ?? {})) {
13553
+ if (!spec.required) continue;
13554
+ props[name] = sampleValue(name, spec);
13555
+ }
13556
+ const node = { type: entry.type };
13557
+ if (Object.keys(props).length > 0) node.props = props;
13558
+ if (entry.text) node.text = "Texto";
13559
+ return node;
13560
+ }
13561
+ function sampleValue(name, spec) {
13562
+ if (spec.values?.length) return spec.values[0];
13563
+ if (spec.kind === "number" || spec.kind === "integer") return 1;
13564
+ if (spec.kind === "boolean") return false;
13565
+ if (spec.kind === "i18n") return { i18n: `ejemplo.${name}` };
13566
+ return name === "src" ? "/imagen.png" : `${name}`;
13567
+ }
13568
+ function buildVocabularyContract(catalog = axzyCatalog, schemaVersion = CURRENT_SCHEMA_VERSION) {
13569
+ const components2 = Object.values(catalog.entries).map((entry) => ({
13570
+ type: entry.type,
13571
+ summary: entry.summary,
13572
+ children: Boolean(entry.children),
13573
+ text: Boolean(entry.text),
13574
+ props: Object.entries(entry.props ?? {}).map(([name, spec]) => ({
13575
+ name,
13576
+ kind: spec.kind,
13577
+ required: Boolean(spec.required),
13578
+ values: spec.values ? [...spec.values] : void 0,
13579
+ default: spec.default,
13580
+ doc: spec.doc
13581
+ })),
13582
+ forbidden: [...entry.forbidden ?? []],
13583
+ minimal: buildMinimal(entry)
13584
+ })).sort((a, b) => a.type.localeCompare(b.type));
13585
+ return {
13586
+ $schema: "axzy/vocabulary",
13587
+ schemaVersion,
13588
+ rules: RULES,
13589
+ components: components2,
13590
+ excluded: catalog.excluded ?? {}
13591
+ };
13592
+ }
13593
+ function formatVocabularyForPrompt(contract) {
13594
+ const lines = [
13595
+ `# Contrato de vocabulario AXZY (formato v${contract.schemaVersion})`,
13596
+ "",
13597
+ "Reglas:",
13598
+ ...contract.rules.map((rule) => `- ${rule}`),
13599
+ "",
13600
+ "Componentes:"
13601
+ ];
13602
+ for (const component of contract.components) {
13603
+ const props = component.props.map((prop) => {
13604
+ const parts = [`${prop.name}:${prop.kind}${prop.required ? "*" : ""}`];
13605
+ if (prop.values?.length) parts.push(`(${prop.values.join("|")})`);
13606
+ return parts.join(" ");
13607
+ }).join(", ");
13608
+ lines.push(`- ${component.type}${component.summary ? ` \u2014 ${component.summary}` : ""}`);
13609
+ if (props) lines.push(` props: ${props}`);
13610
+ if (component.children) lines.push(" children: s\xED");
13611
+ if (component.text) lines.push(" text: s\xED");
13612
+ lines.push(` m\xEDnimo: ${JSON.stringify(component.minimal)}`);
13613
+ }
13614
+ return lines.join("\n");
13615
+ }
13616
+
13617
+ // src/components/organisms/dropfile/dropfile.tsx
13618
+ import { useState as useState37, useEffect as useEffect19 } from "react";
13619
+ import { useDropzone } from "react-dropzone";
13620
+ import clsx54 from "clsx";
13621
+
13622
+ // src/components/organisms/dropfile/dropfile.props.ts
13623
+ var FileTypeEnum = /* @__PURE__ */ ((FileTypeEnum2) => {
13624
+ FileTypeEnum2["PDF"] = "application/pdf";
13625
+ FileTypeEnum2["XLS"] = "application/vnd.ms-excel";
13626
+ FileTypeEnum2["XLSX"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
13627
+ FileTypeEnum2["CSV"] = "text/csv";
13628
+ FileTypeEnum2["PNG"] = "image/png";
13629
+ FileTypeEnum2["JPG"] = "image/jpg";
13630
+ FileTypeEnum2["JPEG"] = "image/jpeg";
13631
+ FileTypeEnum2["MP4"] = "video/mp4";
13632
+ FileTypeEnum2["MOV"] = "video/quicktime";
13633
+ FileTypeEnum2["AVI"] = "video/x-msvideo";
13634
+ FileTypeEnum2["MKV"] = "video/x-matroska";
13635
+ FileTypeEnum2["VIDEO_3GPP"] = "video/3gpp";
13636
+ FileTypeEnum2["WEBM"] = "video/webm";
13637
+ return FileTypeEnum2;
13638
+ })(FileTypeEnum || {});
13639
+ var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
13640
+ UploadStatus2["PENDING"] = "pendiente";
13641
+ UploadStatus2["UPLOADING"] = "subiendo";
13642
+ UploadStatus2["UPLOADED"] = "subido";
13643
+ UploadStatus2["ERROR"] = "error";
13644
+ return UploadStatus2;
13645
+ })(UploadStatus || {});
13646
+
13647
+ // src/components/organisms/dropfile/dropfile.tsx
13648
+ import { Fragment as Fragment14, jsx as jsx76, jsxs as jsxs54 } from "react/jsx-runtime";
13649
+ var ITDropfile = ({
13650
+ onFileSelect,
13651
+ onCancel,
13652
+ onSubmit,
13653
+ contentClassName,
13654
+ containerClassName,
13655
+ acceptedFileTypes = ["application/pdf" /* PDF */, "application/vnd.ms-excel" /* XLS */, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* XLSX */, "image/jpg" /* JPG */, "image/png" /* PNG */, "image/jpeg" /* JPEG */],
13656
+ showStatusBadge = true,
13657
+ uploadStatus: externalStatus,
13658
+ onStatusChange,
13659
+ initialPreviewUrl,
13660
+ view = "drop",
13661
+ buttonLabel,
13662
+ modalTitle
13663
+ }) => {
13664
+ const { t } = useITTranslation();
13665
+ const [isModalOpen, setIsModalOpen] = useState37(false);
13666
+ const [selectedFile, setSelectedFile] = useState37(null);
13667
+ const [fileType, setFileType] = useState37(null);
13668
+ const [imagePreview, setImagePreview] = useState37(initialPreviewUrl || null);
13669
+ const [isConfirmed, setIsConfirmed] = useState37(false);
13670
+ const [internalUploadStatus, setInternalUploadStatus] = useState37(
13671
+ initialPreviewUrl ? "subido" /* UPLOADED */ : "pendiente" /* PENDING */
13672
+ );
13673
+ useEffect19(() => {
13674
+ if (initialPreviewUrl && !selectedFile) {
13675
+ setImagePreview(initialPreviewUrl);
13676
+ if (externalStatus === void 0) setInternalUploadStatus("subido" /* UPLOADED */);
13677
+ }
13678
+ }, [initialPreviewUrl, selectedFile, externalStatus]);
13679
+ const uploadStatus = externalStatus || internalUploadStatus;
13680
+ const setUploadStatus = (status) => {
13681
+ if (externalStatus === void 0) {
13682
+ setInternalUploadStatus(status);
13683
+ }
13684
+ onStatusChange?.(status);
13685
+ };
13686
+ const getAcceptedFileTypes = () => {
13687
+ const accept = {};
13688
+ acceptedFileTypes.forEach((type) => {
13689
+ switch (type) {
13690
+ case "application/pdf" /* PDF */:
13691
+ accept["application/pdf" /* PDF */] = [".pdf"];
13692
+ break;
13693
+ case "application/vnd.ms-excel" /* XLS */:
13694
+ accept["application/vnd.ms-excel" /* XLS */] = [".xls"];
13695
+ break;
13696
+ case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* XLSX */:
13697
+ accept["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* XLSX */] = [".xlsx"];
13698
+ break;
13699
+ case "text/csv" /* CSV */:
13700
+ accept["text/csv" /* CSV */] = [".csv"];
13701
+ break;
13702
+ case "image/png" /* PNG */:
13703
+ accept["image/png" /* PNG */] = [".png"];
13704
+ break;
13705
+ case "image/jpg" /* JPG */:
13706
+ accept["image/jpg" /* JPG */] = [".jpg", ".jpeg"];
13707
+ break;
13708
+ case "image/jpeg" /* JPEG */:
13709
+ accept["image/jpeg" /* JPEG */] = [".jpeg", ".jpg"];
13710
+ break;
13711
+ case "video/mp4" /* MP4 */:
13712
+ accept["video/mp4" /* MP4 */] = [".mp4"];
13713
+ break;
13714
+ case "video/quicktime" /* MOV */:
13715
+ accept["video/quicktime" /* MOV */] = [".mov"];
13716
+ break;
13717
+ case "video/x-msvideo" /* AVI */:
13718
+ accept["video/x-msvideo" /* AVI */] = [".avi"];
13719
+ break;
13720
+ case "video/x-matroska" /* MKV */:
13721
+ accept["video/x-matroska" /* MKV */] = [".mkv"];
13722
+ break;
13723
+ case "video/3gpp" /* VIDEO_3GPP */:
13724
+ accept["video/3gpp" /* VIDEO_3GPP */] = [".3gp"];
13725
+ break;
13726
+ case "video/webm" /* WEBM */:
13727
+ accept["video/webm" /* WEBM */] = [".webm"];
13728
+ break;
13729
+ }
13730
+ });
13731
+ return accept;
13732
+ };
13733
+ const getFileExtensions = () => {
13734
+ const extensions = [];
13735
+ acceptedFileTypes.forEach((type) => {
13736
+ switch (type) {
13737
+ case "application/pdf" /* PDF */:
13738
+ if (!extensions.includes("PDF")) extensions.push("PDF");
13739
+ break;
13740
+ case "application/vnd.ms-excel" /* XLS */:
13741
+ case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* XLSX */:
13742
+ if (!extensions.includes("EXCEL")) extensions.push("EXCEL");
13743
+ break;
13744
+ case "text/csv" /* CSV */:
13745
+ if (!extensions.includes("CSV")) extensions.push("CSV");
13746
+ break;
13747
+ case "image/png" /* PNG */:
13748
+ case "image/jpg" /* JPG */:
13749
+ case "image/jpeg" /* JPEG */:
13750
+ if (!extensions.includes("IMAGEN")) extensions.push("IMAGEN");
13751
+ break;
13752
+ case "video/mp4" /* MP4 */:
13753
+ case "video/quicktime" /* MOV */:
13754
+ case "video/x-msvideo" /* AVI */:
13755
+ case "video/x-matroska" /* MKV */:
13756
+ case "video/3gpp" /* VIDEO_3GPP */:
13757
+ case "video/webm" /* WEBM */:
13758
+ if (!extensions.includes("VIDEO")) extensions.push("VIDEO");
13759
+ break;
13760
+ }
13761
+ });
13762
+ return extensions.join(", ");
13763
+ };
13764
+ const StatusBadge = ({ status }) => {
13765
+ const config2 = {
13766
+ ["pendiente" /* PENDING */]: {
13767
+ label: t("dropfile.status.pending"),
13768
+ color: "bg-warning-100 text-warning-800 border-warning-200",
13769
+ dotColor: "bg-warning-400"
13770
+ },
13771
+ ["subiendo" /* UPLOADING */]: {
13772
+ label: t("dropfile.status.uploading"),
13773
+ color: "bg-primary-100 text-primary-800 border-primary-200",
13774
+ dotColor: "bg-primary-400 animate-pulse"
13775
+ },
13776
+ ["subido" /* UPLOADED */]: {
13777
+ label: t("dropfile.status.uploaded"),
13778
+ color: "bg-success-100 text-success-800 border-success-200",
13779
+ dotColor: "bg-success-400"
13780
+ },
13781
+ ["error" /* ERROR */]: {
13782
+ label: t("dropfile.status.error"),
13783
+ color: "bg-danger-100 text-danger-800 border-danger-200",
13784
+ dotColor: "bg-danger-400"
13785
+ }
13786
+ };
13787
+ const { label, color, dotColor } = config2[status];
13788
+ return /* @__PURE__ */ jsxs54("div", { className: `inline-flex items-center gap-2 px-2.5 py-1 rounded-full border ${color}`, children: [
13789
+ /* @__PURE__ */ jsx76("div", { className: `w-2 h-2 rounded-full ${dotColor}` }),
13790
+ /* @__PURE__ */ jsx76(ITText, { as: "span", className: "text-xs font-medium flex items-center gap-1.5", children: label })
13791
+ ] });
13792
+ };
13793
+ const onDrop = (acceptedFiles) => {
13794
+ const file = acceptedFiles[0];
13795
+ if (file) {
13796
+ if (acceptedFileTypes.includes(file.type)) {
13797
+ setSelectedFile(file);
13798
+ setFileType(file.type);
13799
+ setUploadStatus("pendiente" /* PENDING */);
13800
+ if (imagePreview) {
13801
+ URL.revokeObjectURL(imagePreview);
13802
+ setImagePreview(null);
13803
+ }
13804
+ if (file.type.startsWith("image/")) {
13805
+ const previewUrl = URL.createObjectURL(file);
13806
+ setImagePreview(previewUrl);
13807
+ }
13808
+ } else {
13809
+ alert(t("dropfile.fileTypeNotAllowed"));
13810
+ setSelectedFile(null);
13811
+ setFileType(null);
12347
13812
  setImagePreview(null);
12348
13813
  setUploadStatus("pendiente" /* PENDING */);
12349
13814
  }
@@ -12354,12 +13819,12 @@ var ITDropfile = ({
12354
13819
  accept: getAcceptedFileTypes(),
12355
13820
  maxFiles: 1
12356
13821
  });
12357
- useEffect18(() => {
13822
+ useEffect19(() => {
12358
13823
  const renderPDF = async () => {
12359
13824
  };
12360
13825
  renderPDF();
12361
13826
  }, [selectedFile, fileType]);
12362
- useEffect18(() => {
13827
+ useEffect19(() => {
12363
13828
  return () => {
12364
13829
  if (imagePreview) {
12365
13830
  URL.revokeObjectURL(imagePreview);
@@ -12396,7 +13861,7 @@ var ITDropfile = ({
12396
13861
  const handleDelete = () => {
12397
13862
  handleCancel();
12398
13863
  };
12399
- useEffect18(() => {
13864
+ useEffect19(() => {
12400
13865
  if (view === "button" && isConfirmed && uploadStatus === "subido" /* UPLOADED */) {
12401
13866
  const timeout = setTimeout(() => {
12402
13867
  setIsModalOpen(false);
@@ -12425,9 +13890,9 @@ var ITDropfile = ({
12425
13890
  ")"
12426
13891
  ] })
12427
13892
  ] }),
12428
- showStatusBadge && selectedFile && /* @__PURE__ */ jsx74(StatusBadge, { status: uploadStatus })
13893
+ showStatusBadge && selectedFile && /* @__PURE__ */ jsx76(StatusBadge, { status: uploadStatus })
12429
13894
  ] });
12430
- const dropZoneOrPreview = /* @__PURE__ */ jsx74(Fragment13, { children: !selectedFile && !imagePreview ? /* @__PURE__ */ jsxs54(
13895
+ const dropZoneOrPreview = /* @__PURE__ */ jsx76(Fragment14, { children: !selectedFile && !imagePreview ? /* @__PURE__ */ jsxs54(
12431
13896
  "div",
12432
13897
  {
12433
13898
  ...getRootProps(),
@@ -12437,29 +13902,29 @@ var ITDropfile = ({
12437
13902
  ${isDragActive ? "border-primary-500 bg-primary-50 scale-[1.01]" : "border-secondary-300 bg-white hover:border-primary-400 hover:bg-secondary-50"}
12438
13903
  `,
12439
13904
  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(
13905
+ /* @__PURE__ */ jsx76("input", { ...getInputProps() }),
13906
+ /* @__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
13907
  "svg",
12443
13908
  {
12444
13909
  className: `w-6 h-6 transition-colors duration-300 ${isDragActive ? "text-primary-600" : "text-secondary-400 group-hover:text-primary-500"}`,
12445
13910
  fill: "none",
12446
13911
  viewBox: "0 0 24 24",
12447
13912
  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" })
13913
+ 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
13914
  }
12450
13915
  ) }),
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") }) })
13916
+ /* @__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
13917
  ]
12453
13918
  }
12454
13919
  ) : /* @__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" }) }) }),
13920
+ /* @__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: [
13921
+ /* @__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
13922
  /* @__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" : "" })
13923
+ /* @__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") }),
13924
+ /* @__PURE__ */ jsx76(ITText, { as: "p", className: "text-[10px] text-secondary-500", children: selectedFile ? (selectedFile.size / 1024 / 1024).toFixed(2) + " MB" : "" })
12460
13925
  ] })
12461
13926
  ] }) }),
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(
13927
+ /* @__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
13928
  "img",
12464
13929
  {
12465
13930
  src: imagePreview,
@@ -12467,11 +13932,11 @@ var ITDropfile = ({
12467
13932
  className: "w-full h-full object-contain max-h-[200px]"
12468
13933
  }
12469
13934
  ) : /* @__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") })
13935
+ /* @__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" }) }),
13936
+ /* @__PURE__ */ jsx76(ITText, { as: "span", className: "text-xs", children: t("dropfile.noPreview") })
12472
13937
  ] }) }),
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(
13938
+ /* @__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: [
13939
+ /* @__PURE__ */ jsx76(
12475
13940
  ITButton,
12476
13941
  {
12477
13942
  type: "button",
@@ -12479,10 +13944,10 @@ var ITDropfile = ({
12479
13944
  color: "secondary",
12480
13945
  size: "sm",
12481
13946
  onClick: handleCancel,
12482
- children: /* @__PURE__ */ jsx74(ITText, { children: t("common.cancel") })
13947
+ children: /* @__PURE__ */ jsx76(ITText, { children: t("common.cancel") })
12483
13948
  }
12484
13949
  ),
12485
- /* @__PURE__ */ jsx74(
13950
+ /* @__PURE__ */ jsx76(
12486
13951
  ITButton,
12487
13952
  {
12488
13953
  type: "button",
@@ -12491,8 +13956,8 @@ var ITDropfile = ({
12491
13956
  size: "sm",
12492
13957
  onClick: handleConfirm,
12493
13958
  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" }) })
13959
+ /* @__PURE__ */ jsx76(ITText, { children: t("common.confirm") }),
13960
+ /* @__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
13961
  ] })
12497
13962
  }
12498
13963
  )
@@ -12505,12 +13970,12 @@ var ITDropfile = ({
12505
13970
  size: "sm",
12506
13971
  onClick: handleDelete,
12507
13972
  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") })
13973
+ /* @__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" }) }),
13974
+ /* @__PURE__ */ jsx76(ITText, { children: t("common.delete") })
12510
13975
  ]
12511
13976
  }
12512
13977
  ) }),
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(
13978
+ 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
13979
  "div",
12515
13980
  {
12516
13981
  className: "bg-primary-600 h-1.5 rounded-full transition-all duration-1000 ease-out",
@@ -12524,7 +13989,7 @@ var ITDropfile = ({
12524
13989
  if (view === "button") {
12525
13990
  const hasFile = Boolean(selectedFile || imagePreview);
12526
13991
  return /* @__PURE__ */ jsxs54("div", { className: clsx54("inline-block", containerClassName), children: [
12527
- /* @__PURE__ */ jsx74(
13992
+ /* @__PURE__ */ jsx76(
12528
13993
  ITButton,
12529
13994
  {
12530
13995
  type: "button",
@@ -12533,13 +13998,13 @@ var ITDropfile = ({
12533
13998
  size: "sm",
12534
13999
  onClick: () => setIsModalOpen(true),
12535
14000
  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 })
14001
+ /* @__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" }) }),
14002
+ /* @__PURE__ */ jsx76(ITText, { className: "truncate", children: selectedFile?.name || (hasFile ? t("dropfile.fileLoaded") : buttonLabel ?? t("dropfile.upload")) }),
14003
+ showStatusBadge && hasFile && /* @__PURE__ */ jsx76(StatusBadge, { status: uploadStatus })
12539
14004
  ] })
12540
14005
  }
12541
14006
  ),
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: [
14007
+ /* @__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
14008
  headerRow,
12544
14009
  dropZoneOrPreview
12545
14010
  ] }) })
@@ -12558,8 +14023,8 @@ import clsx55 from "clsx";
12558
14023
 
12559
14024
  // src/components/organisms/topbar/topbar.tsx
12560
14025
  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";
14026
+ import { useRef as useRef24, useState as useState38 } from "react";
14027
+ import { jsx as jsx77, jsxs as jsxs55 } from "react/jsx-runtime";
12563
14028
  function ITTopBar({
12564
14029
  logo,
12565
14030
  logoText,
@@ -12577,9 +14042,9 @@ function ITTopBar({
12577
14042
  const { t } = useITTranslation();
12578
14043
  const initials = (userMenu?.userName ?? "").trim().split(/\s+/).slice(0, 2).map((word) => word.charAt(0).toUpperCase()).join("");
12579
14044
  const [isUserMenuOpen, setIsUserMenuOpen] = useState38(false);
12580
- const userMenuRef = useRef23(null);
14045
+ const userMenuRef = useRef24(null);
12581
14046
  useClickOutside_default(userMenuRef, () => setIsUserMenuOpen(false));
12582
- return /* @__PURE__ */ jsx75(
14047
+ return /* @__PURE__ */ jsx77(
12583
14048
  "header",
12584
14049
  {
12585
14050
  className: `sticky top-0 z-40 transition-all duration-300 ${flat ? "" : "backdrop-blur-md"}`,
@@ -12590,7 +14055,7 @@ function ITTopBar({
12590
14055
  },
12591
14056
  children: /* @__PURE__ */ jsxs55("div", { className: `flex items-center justify-between px-6 lg:px-8 ${flat ? "h-[64px]" : "h-[72px]"}`, children: [
12592
14057
  /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-5", children: [
12593
- showMobileMenuButton && /* @__PURE__ */ jsx75(
14058
+ showMobileMenuButton && /* @__PURE__ */ jsx77(
12594
14059
  "button",
12595
14060
  {
12596
14061
  type: "button",
@@ -12602,12 +14067,12 @@ function ITTopBar({
12602
14067
  onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "var(--it-topbar-user-hover, #f1f5f9)",
12603
14068
  onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
12604
14069
  onClick: onToggleMobileMenu,
12605
- children: /* @__PURE__ */ jsx75(FaBars, { className: "w-[1.125rem] h-[1.125rem]" })
14070
+ children: /* @__PURE__ */ jsx77(FaBars, { className: "w-[1.125rem] h-[1.125rem]" })
12606
14071
  }
12607
14072
  ),
12608
14073
  /* @__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(
14074
+ logo && /* @__PURE__ */ jsx77("div", { className: "flex-shrink-0 drop-shadow-sm", children: logo }),
14075
+ logoText && /* @__PURE__ */ jsx77(
12611
14076
  ITText,
12612
14077
  {
12613
14078
  as: "span",
@@ -12617,7 +14082,7 @@ function ITTopBar({
12617
14082
  }
12618
14083
  )
12619
14084
  ] }),
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(
14085
+ 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
14086
  "button",
12622
14087
  {
12623
14088
  onClick: () => onNavItemClick?.(item.id),
@@ -12632,14 +14097,14 @@ function ITTopBar({
12632
14097
  e.currentTarget.style.backgroundColor = "transparent";
12633
14098
  },
12634
14099
  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 })
14100
+ item.icon && /* @__PURE__ */ jsx77("span", { className: "opacity-70", children: item.icon }),
14101
+ /* @__PURE__ */ jsx77(ITText, { as: "span", children: item.label })
12637
14102
  ] })
12638
14103
  },
12639
14104
  item.id
12640
14105
  )) })
12641
14106
  ] }),
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 }) }),
14107
+ 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
14108
  (children || userMenu) && /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-2", children: [
12644
14109
  children,
12645
14110
  userMenu && /* @__PURE__ */ jsxs55("div", { className: "relative", children: [
@@ -12660,14 +14125,14 @@ function ITTopBar({
12660
14125
  onClick: () => setIsUserMenuOpen(!isUserMenuOpen),
12661
14126
  children: [
12662
14127
  /* @__PURE__ */ jsxs55("div", { className: "relative", children: [
12663
- userMenu.userImage ? /* @__PURE__ */ jsx75(
14128
+ userMenu.userImage ? /* @__PURE__ */ jsx77(
12664
14129
  "img",
12665
14130
  {
12666
14131
  className: "w-9 h-9 rounded-full object-cover ring-2 ring-white shadow-sm",
12667
14132
  src: userMenu.userImage,
12668
14133
  alt: t("common.userAvatar")
12669
14134
  }
12670
- ) : flat && initials ? /* @__PURE__ */ jsx75(
14135
+ ) : flat && initials ? /* @__PURE__ */ jsx77(
12671
14136
  "div",
12672
14137
  {
12673
14138
  "aria-hidden": "true",
@@ -12678,11 +14143,11 @@ function ITTopBar({
12678
14143
  },
12679
14144
  children: initials
12680
14145
  }
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" })
14146
+ ) : /* @__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)" } }) }),
14147
+ !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
14148
  ] }),
12684
14149
  /* @__PURE__ */ jsxs55("div", { className: `hidden sm:flex flex-col py-0.5 ${flat ? "text-right" : "text-left"}`, children: [
12685
- /* @__PURE__ */ jsx75(
14150
+ /* @__PURE__ */ jsx77(
12686
14151
  ITText,
12687
14152
  {
12688
14153
  as: "span",
@@ -12691,7 +14156,7 @@ function ITTopBar({
12691
14156
  children: userMenu.userName
12692
14157
  }
12693
14158
  ),
12694
- /* @__PURE__ */ jsx75(
14159
+ /* @__PURE__ */ jsx77(
12695
14160
  ITText,
12696
14161
  {
12697
14162
  as: "span",
@@ -12718,14 +14183,14 @@ function ITTopBar({
12718
14183
  },
12719
14184
  children: [
12720
14185
  /* @__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 })
14186
+ /* @__PURE__ */ jsx77(ITText, { as: "span", className: "block font-bold text-[0.9rem]", style: { color: "var(--it-topbar-user-text, #0f172a)" }, children: userMenu.userName }),
14187
+ /* @__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
14188
  ] }),
12724
- /* @__PURE__ */ jsx75("ul", { className: "py-2", children: userMenu.menuItems.map((m, i) => {
14189
+ /* @__PURE__ */ jsx77("ul", { className: "py-2", children: userMenu.menuItems.map((m, i) => {
12725
14190
  const isDestructive = m.label.toLowerCase().includes("salir") || m.label.toLowerCase().includes("cerrar") || m.label.toLowerCase().includes("logout");
12726
14191
  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(
14192
+ i === userMenu.menuItems.length - 1 && isDestructive && i > 0 && /* @__PURE__ */ jsx77("div", { className: "h-px bg-slate-100 my-1 mx-2" }),
14193
+ /* @__PURE__ */ jsx77(
12729
14194
  "button",
12730
14195
  {
12731
14196
  onClick: () => {
@@ -12740,7 +14205,7 @@ function ITTopBar({
12740
14205
  onMouseLeave: (e) => {
12741
14206
  e.currentTarget.style.backgroundColor = "transparent";
12742
14207
  },
12743
- children: /* @__PURE__ */ jsx75(ITText, { as: "span", children: m.label })
14208
+ children: /* @__PURE__ */ jsx77(ITText, { as: "span", children: m.label })
12744
14209
  }
12745
14210
  )
12746
14211
  ] }, i);
@@ -12756,7 +14221,7 @@ function ITTopBar({
12756
14221
  }
12757
14222
 
12758
14223
  // src/components/templates/layout/layout.tsx
12759
- import { jsx as jsx76, jsxs as jsxs56 } from "react/jsx-runtime";
14224
+ import { jsx as jsx78, jsxs as jsxs56 } from "react/jsx-runtime";
12760
14225
  function ITLayout({
12761
14226
  topBar,
12762
14227
  sidebar,
@@ -12780,7 +14245,7 @@ function ITLayout({
12780
14245
  else setMobileSidebarOpen((v) => !v);
12781
14246
  };
12782
14247
  const brand = sidebarFullHeight ? sidebar.brand ?? { logo: topBar.logo, text: topBar.logoText } : sidebar.brand;
12783
- const topBarNode = /* @__PURE__ */ jsx76(
14248
+ const topBarNode = /* @__PURE__ */ jsx78(
12784
14249
  ITTopBar,
12785
14250
  {
12786
14251
  ...topBar,
@@ -12794,8 +14259,8 @@ function ITLayout({
12794
14259
  // Full-height: the sidebar sits beside the top bar, so it needs to win the
12795
14260
  // stacking order when the collapsed rail expands over the content on hover.
12796
14261
  /* @__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(
14262
+ /* @__PURE__ */ jsx78("div", { className: `${reservedWidth} h-full flex-shrink-0` }),
14263
+ /* @__PURE__ */ jsx78("div", { className: "absolute top-0 left-0 h-full", children: /* @__PURE__ */ jsx78(
12799
14264
  ITSidebar,
12800
14265
  {
12801
14266
  ...sidebar,
@@ -12808,17 +14273,17 @@ function ITLayout({
12808
14273
  ) })
12809
14274
  ] })
12810
14275
  );
12811
- const mobileSidebar = mobileSidebarOpen && /* @__PURE__ */ jsx76(
14276
+ const mobileSidebar = mobileSidebarOpen && /* @__PURE__ */ jsx78(
12812
14277
  "div",
12813
14278
  {
12814
14279
  className: "lg:hidden fixed inset-0 z-[40] transition-opacity duration-300 backdrop-blur-sm bg-black/40",
12815
14280
  onClick: () => setMobileSidebarOpen(false),
12816
- children: /* @__PURE__ */ jsx76(
14281
+ children: /* @__PURE__ */ jsx78(
12817
14282
  "div",
12818
14283
  {
12819
14284
  className: "h-full w-fit flex transform transition-transform duration-300 ease-[cubic-bezier(0.2,0,0,1)]",
12820
14285
  onClick: (e) => e.stopPropagation(),
12821
- children: /* @__PURE__ */ jsx76(
14286
+ children: /* @__PURE__ */ jsx78(
12822
14287
  ITSidebar,
12823
14288
  {
12824
14289
  ...sidebar,
@@ -12835,7 +14300,7 @@ function ITLayout({
12835
14300
  )
12836
14301
  }
12837
14302
  );
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 }) });
14303
+ 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
14304
  if (sidebarFullHeight) {
12840
14305
  return /* @__PURE__ */ jsxs56(
12841
14306
  "div",
@@ -12870,97 +14335,11 @@ function ITLayout({
12870
14335
  ] });
12871
14336
  }
12872
14337
 
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
14338
  // src/components/molecules/stepper/stepper.tsx
12960
14339
  import clsx56 from "clsx";
12961
- import { useEffect as useEffect19, useRef as useRef24, useState as useState40 } from "react";
14340
+ import { useEffect as useEffect20, useRef as useRef25, useState as useState40 } from "react";
12962
14341
  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";
14342
+ import { jsx as jsx79, jsxs as jsxs57 } from "react/jsx-runtime";
12964
14343
  function ITStepper({
12965
14344
  steps,
12966
14345
  currentStep,
@@ -12977,14 +14356,14 @@ function ITStepper({
12977
14356
  }) {
12978
14357
  const { t } = useITTranslation();
12979
14358
  const [direction, setDirection] = useState40("next");
12980
- const contentRef = useRef24(null);
12981
- const progressRef = useRef24(null);
14359
+ const contentRef = useRef25(null);
14360
+ const progressRef = useRef25(null);
12982
14361
  const isThemeColor = color in theme.colors;
12983
14362
  const resolvedColor = isThemeColor ? theme.colors[color][500] : color;
12984
- useEffect19(() => {
14363
+ useEffect20(() => {
12985
14364
  onStepChange?.(currentStep);
12986
14365
  }, [currentStep, onStepChange]);
12987
- useEffect19(() => {
14366
+ useEffect20(() => {
12988
14367
  const pct = currentStep / Math.max(1, steps.length - 1) * 100;
12989
14368
  if (progressRef.current) {
12990
14369
  progressRef.current.style.width = `${pct}%`;
@@ -13028,23 +14407,23 @@ function ITStepper({
13028
14407
  const renderStepContent = (index, isCompleted) => {
13029
14408
  const step = steps[index];
13030
14409
  if (isCompleted) {
13031
- return /* @__PURE__ */ jsx78(FaCheck6, { className: "w-4 h-4" });
14410
+ return /* @__PURE__ */ jsx79(FaCheck6, { className: "w-4 h-4" });
13032
14411
  }
13033
14412
  if (step.icon && useIcons) {
13034
- return /* @__PURE__ */ jsx78("div", { className: "flex items-center justify-center w-5 h-5", children: step.icon });
14413
+ return /* @__PURE__ */ jsx79("div", { className: "flex items-center justify-center w-5 h-5", children: step.icon });
13035
14414
  }
13036
- return /* @__PURE__ */ jsx78(ITText, { as: "span", className: "text-sm font-semibold", children: index + 1 });
14415
+ return /* @__PURE__ */ jsx79(ITText, { as: "span", className: "text-sm font-semibold", children: index + 1 });
13037
14416
  };
13038
14417
  return /* @__PURE__ */ jsxs57("div", { className: clsx56("w-full max-w-5xl mx-auto px-4", containerClassName), children: [
13039
14418
  /* @__PURE__ */ jsxs57("div", { className: "relative mb-8", children: [
13040
- /* @__PURE__ */ jsx78(
14419
+ /* @__PURE__ */ jsx79(
13041
14420
  "div",
13042
14421
  {
13043
14422
  className: "absolute left-6 right-6 top-5 h-1 bg-secondary-200 rounded-full z-0",
13044
14423
  "aria-hidden": true
13045
14424
  }
13046
14425
  ),
13047
- /* @__PURE__ */ jsx78(
14426
+ /* @__PURE__ */ jsx79(
13048
14427
  "div",
13049
14428
  {
13050
14429
  ref: progressRef,
@@ -13052,11 +14431,11 @@ function ITStepper({
13052
14431
  "aria-hidden": true
13053
14432
  }
13054
14433
  ),
13055
- /* @__PURE__ */ jsx78("div", { className: "flex items-start justify-between space-x-2 relative z-20", children: steps.map((step, idx) => {
14434
+ /* @__PURE__ */ jsx79("div", { className: "flex items-start justify-between space-x-2 relative z-20", children: steps.map((step, idx) => {
13056
14435
  const isActive = idx === currentStep;
13057
14436
  const isCompleted = idx < currentStep;
13058
14437
  const hasIcon = step.icon && useIcons;
13059
- return /* @__PURE__ */ jsx78(
14438
+ return /* @__PURE__ */ jsx79(
13060
14439
  "button",
13061
14440
  {
13062
14441
  type: "button",
@@ -13067,7 +14446,7 @@ function ITStepper({
13067
14446
  className: "flex-1 group",
13068
14447
  title: step.label,
13069
14448
  children: /* @__PURE__ */ jsxs57("div", { className: "flex flex-col items-center", children: [
13070
- /* @__PURE__ */ jsx78(
14449
+ /* @__PURE__ */ jsx79(
13071
14450
  "div",
13072
14451
  {
13073
14452
  className: clsx56(
@@ -13081,7 +14460,7 @@ function ITStepper({
13081
14460
  children: renderStepContent(idx, isCompleted)
13082
14461
  }
13083
14462
  ),
13084
- /* @__PURE__ */ jsx78(
14463
+ /* @__PURE__ */ jsx79(
13085
14464
  ITText,
13086
14465
  {
13087
14466
  as: "span",
@@ -13099,7 +14478,7 @@ function ITStepper({
13099
14478
  );
13100
14479
  }) })
13101
14480
  ] }),
13102
- /* @__PURE__ */ jsx78(
14481
+ /* @__PURE__ */ jsx79(
13103
14482
  "div",
13104
14483
  {
13105
14484
  ref: contentRef,
@@ -13116,7 +14495,7 @@ function ITStepper({
13116
14495
  }
13117
14496
  ),
13118
14497
  /* @__PURE__ */ jsxs57("div", { className: "flex justify-between items-center mt-6", children: [
13119
- /* @__PURE__ */ jsx78(
14498
+ /* @__PURE__ */ jsx79(
13120
14499
  ITButton,
13121
14500
  {
13122
14501
  variant: "outlined",
@@ -13124,14 +14503,14 @@ function ITStepper({
13124
14503
  disabled: currentStep === 0,
13125
14504
  onClick: prevStep,
13126
14505
  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") })
14506
+ /* @__PURE__ */ jsx79(FaChevronLeft4, {}),
14507
+ /* @__PURE__ */ jsx79(ITText, { as: "span", children: t("common.back") })
13129
14508
  ] })
13130
14509
  }
13131
14510
  ),
13132
14511
  /* @__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(
14512
+ /* @__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 }) }),
14513
+ /* @__PURE__ */ jsx79(
13135
14514
  ITButton,
13136
14515
  {
13137
14516
  variant: "solid",
@@ -13139,8 +14518,8 @@ function ITStepper({
13139
14518
  disabled: disableNext,
13140
14519
  onClick: nextStep,
13141
14520
  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, {})
14521
+ /* @__PURE__ */ jsx79(ITText, { as: "span", children: currentStep === steps.length - 1 ? t("common.finish") : t("common.next") }),
14522
+ currentStep === steps.length - 1 ? /* @__PURE__ */ jsx79(FaCheck6, {}) : /* @__PURE__ */ jsx79(FaChevronRight7, {})
13144
14523
  ] })
13145
14524
  }
13146
14525
  )
@@ -13150,7 +14529,7 @@ function ITStepper({
13150
14529
  }
13151
14530
 
13152
14531
  // src/components/theme-provider/themeProvider.tsx
13153
- import { useState as useState41, useEffect as useEffect20, useLayoutEffect as useLayoutEffect5 } from "react";
14532
+ import { useState as useState41, useEffect as useEffect21, useLayoutEffect as useLayoutEffect5 } from "react";
13154
14533
  import { MdPalette, MdClose, MdRefresh } from "react-icons/md";
13155
14534
 
13156
14535
  // src/components/theme-provider/themePresets.ts
@@ -13328,7 +14707,7 @@ var PRESETS = [
13328
14707
  ];
13329
14708
 
13330
14709
  // src/components/theme-provider/themeProvider.tsx
13331
- import { jsx as jsx79, jsxs as jsxs58 } from "react/jsx-runtime";
14710
+ import { jsx as jsx80, jsxs as jsxs58 } from "react/jsx-runtime";
13332
14711
  var STORAGE_KEY = "it-theme-palette";
13333
14712
  var SHADOW_LEVELS = {
13334
14713
  0: {
@@ -13497,7 +14876,7 @@ function ITThemeProvider({
13497
14876
  return "system";
13498
14877
  }
13499
14878
  );
13500
- useEffect20(() => {
14879
+ useEffect21(() => {
13501
14880
  localStorage.setItem("it-theme-dark-mode", darkModeMode);
13502
14881
  const applyDarkMode = (isDark) => {
13503
14882
  if (isDark) {
@@ -13522,7 +14901,7 @@ function ITThemeProvider({
13522
14901
  applyDarkMode(darkModeMode === "dark");
13523
14902
  }
13524
14903
  }, [darkModeMode]);
13525
- useEffect20(() => {
14904
+ useEffect21(() => {
13526
14905
  if (!showFab) {
13527
14906
  setPaletteState({
13528
14907
  ...DEFAULT_PALETTE,
@@ -13579,7 +14958,7 @@ function ITThemeProvider({
13579
14958
  surfaceStyle?.remove();
13580
14959
  };
13581
14960
  }, [radius, shadow]);
13582
- useEffect20(() => {
14961
+ useEffect21(() => {
13583
14962
  const injectStyles = (obj, prefix = "") => {
13584
14963
  Object.entries(obj).forEach(([key, val]) => {
13585
14964
  if (typeof val === "object" && val !== null) {
@@ -14740,7 +16119,7 @@ function ITThemeProvider({
14740
16119
  children: [
14741
16120
  /* @__PURE__ */ jsxs58("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [
14742
16121
  /* @__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(
16122
+ /* @__PURE__ */ jsx80(
14744
16123
  "input",
14745
16124
  {
14746
16125
  type: "color",
@@ -14749,23 +16128,23 @@ function ITThemeProvider({
14749
16128
  className: "absolute inset-0 opacity-0 cursor-pointer w-full h-full"
14750
16129
  }
14751
16130
  ),
14752
- /* @__PURE__ */ jsx79("div", { className: "w-full h-full", style: { backgroundColor: value } })
16131
+ /* @__PURE__ */ jsx80("div", { className: "w-full h-full", style: { backgroundColor: value } })
14753
16132
  ] }),
14754
16133
  /* @__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() }),
16134
+ /* @__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
16135
  /* @__PURE__ */ jsxs58("div", { className: "flex items-center gap-2 mt-0.5", children: [
14757
- /* @__PURE__ */ jsx79(
16136
+ /* @__PURE__ */ jsx80(
14758
16137
  "span",
14759
16138
  {
14760
16139
  className: "w-3 h-3 rounded-full border border-slate-200 dark:border-slate-600",
14761
16140
  style: { backgroundColor: value }
14762
16141
  }
14763
16142
  ),
14764
- /* @__PURE__ */ jsx79(ITText, { as: "span", className: "font-mono text-[11px] text-slate-400", children: value })
16143
+ /* @__PURE__ */ jsx80(ITText, { as: "span", className: "font-mono text-[11px] text-slate-400", children: value })
14765
16144
  ] })
14766
16145
  ] })
14767
16146
  ] }),
14768
- /* @__PURE__ */ jsx79(
16147
+ /* @__PURE__ */ jsx80(
14769
16148
  "input",
14770
16149
  {
14771
16150
  type: "text",
@@ -14791,7 +16170,7 @@ function ITThemeProvider({
14791
16170
  onClick: () => applyPreset(preset.colors),
14792
16171
  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
16172
  children: [
14794
- isCustom && /* @__PURE__ */ jsx79(
16173
+ isCustom && /* @__PURE__ */ jsx80(
14795
16174
  "span",
14796
16175
  {
14797
16176
  onClick: (e) => {
@@ -14800,11 +16179,11 @@ function ITThemeProvider({
14800
16179
  },
14801
16180
  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
16181
  title: t("themeProvider.designer.deletePreset"),
14803
- children: /* @__PURE__ */ jsx79(MdClose, { size: 12 })
16182
+ children: /* @__PURE__ */ jsx80(MdClose, { size: 12 })
14804
16183
  }
14805
16184
  ),
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(
16185
+ /* @__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 }),
16186
+ /* @__PURE__ */ jsx80("div", { className: "flex gap-1", children: ["primary", "secondary", "ternary", "success"].map((c) => /* @__PURE__ */ jsx80(
14808
16187
  "span",
14809
16188
  {
14810
16189
  className: "w-3 h-3 rounded-full border border-black/10",
@@ -14833,17 +16212,17 @@ function ITThemeProvider({
14833
16212
  },
14834
16213
  children: [
14835
16214
  children,
14836
- showFab && /* @__PURE__ */ jsx79(
16215
+ showFab && /* @__PURE__ */ jsx80(
14837
16216
  "button",
14838
16217
  {
14839
16218
  onClick: () => setIsOpen((prev) => !prev),
14840
16219
  className: "it-theme-fab it-theme-bounce",
14841
16220
  style: { backgroundColor: "var(--color-primary)" },
14842
16221
  "aria-label": t("themeProvider.fab.ariaLabel"),
14843
- children: /* @__PURE__ */ jsx79(MdPalette, { size: 28 })
16222
+ children: /* @__PURE__ */ jsx80(MdPalette, { size: 28 })
14844
16223
  }
14845
16224
  ),
14846
- showFab && /* @__PURE__ */ jsx79(
16225
+ showFab && /* @__PURE__ */ jsx80(
14847
16226
  ITDialog,
14848
16227
  {
14849
16228
  isOpen,
@@ -14853,8 +16232,8 @@ function ITThemeProvider({
14853
16232
  children: /* @__PURE__ */ jsxs58("div", { className: "flex gap-6 h-[580px]", children: [
14854
16233
  /* @__PURE__ */ jsxs58("div", { className: "w-64 flex-shrink-0 flex flex-col gap-5 overflow-y-auto pr-1", children: [
14855
16234
  /* @__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(
16235
+ /* @__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") }),
16236
+ /* @__PURE__ */ jsx80(
14858
16237
  ITSegmentedControl,
14859
16238
  {
14860
16239
  options: [
@@ -14869,15 +16248,15 @@ function ITThemeProvider({
14869
16248
  )
14870
16249
  ] }),
14871
16250
  /* @__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)) })
16251
+ /* @__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") }) }),
16252
+ /* @__PURE__ */ jsx80("div", { className: "grid grid-cols-2 gap-2", children: PRESETS.map((preset) => /* @__PURE__ */ jsx80(PresetCard, { preset }, preset.name)) })
14874
16253
  ] }),
14875
16254
  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)) })
16255
+ /* @__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") }),
16256
+ /* @__PURE__ */ jsx80("div", { className: "flex flex-col gap-1.5", children: customPresets.map((preset) => /* @__PURE__ */ jsx80(PresetCard, { preset, isCustom: true }, preset.name)) })
14878
16257
  ] }),
14879
16258
  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(
16259
+ /* @__PURE__ */ jsx80(
14881
16260
  ITInput,
14882
16261
  {
14883
16262
  name: "presetName",
@@ -14896,7 +16275,7 @@ function ITThemeProvider({
14896
16275
  }
14897
16276
  ),
14898
16277
  /* @__PURE__ */ jsxs58("div", { className: "flex gap-2", children: [
14899
- /* @__PURE__ */ jsx79(
16278
+ /* @__PURE__ */ jsx80(
14900
16279
  ITButton,
14901
16280
  {
14902
16281
  label: t("themeProvider.designer.save"),
@@ -14907,7 +16286,7 @@ function ITThemeProvider({
14907
16286
  className: "flex-1"
14908
16287
  }
14909
16288
  ),
14910
- /* @__PURE__ */ jsx79(
16289
+ /* @__PURE__ */ jsx80(
14911
16290
  ITButton,
14912
16291
  {
14913
16292
  label: t("themeProvider.designer.cancelSave"),
@@ -14921,31 +16300,31 @@ function ITThemeProvider({
14921
16300
  )
14922
16301
  ] })
14923
16302
  ] }),
14924
- !isSavingPreset && /* @__PURE__ */ jsx79(
16303
+ !isSavingPreset && /* @__PURE__ */ jsx80(
14925
16304
  ITButton,
14926
16305
  {
14927
16306
  variant: "outlined",
14928
- icon: /* @__PURE__ */ jsx79(MdPalette, { size: 14 }),
16307
+ icon: /* @__PURE__ */ jsx80(MdPalette, { size: 14 }),
14929
16308
  label: t("themeProvider.designer.saveCurrent"),
14930
16309
  onClick: () => setIsSavingPreset(true),
14931
16310
  size: "sm"
14932
16311
  }
14933
16312
  ),
14934
- /* @__PURE__ */ jsx79(
16313
+ /* @__PURE__ */ jsx80(
14935
16314
  ITButton,
14936
16315
  {
14937
16316
  variant: "outlined",
14938
16317
  color: "danger",
14939
- icon: /* @__PURE__ */ jsx79(MdRefresh, { size: 14 }),
16318
+ icon: /* @__PURE__ */ jsx80(MdRefresh, { size: 14 }),
14940
16319
  label: t("themeProvider.designer.reset"),
14941
16320
  onClick: resetTheme,
14942
16321
  size: "sm"
14943
16322
  }
14944
16323
  )
14945
16324
  ] }),
14946
- /* @__PURE__ */ jsx79(ITDivider, { orientation: "vertical" }),
16325
+ /* @__PURE__ */ jsx80(ITDivider, { orientation: "vertical" }),
14947
16326
  /* @__PURE__ */ jsxs58("div", { className: "flex-1 flex flex-col min-w-0", children: [
14948
- /* @__PURE__ */ jsx79(
16327
+ /* @__PURE__ */ jsx80(
14949
16328
  tabs_default,
14950
16329
  {
14951
16330
  variant: "pill",
@@ -14953,7 +16332,7 @@ function ITThemeProvider({
14953
16332
  {
14954
16333
  id: "brand",
14955
16334
  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: [
16335
+ 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
16336
  "primary",
14958
16337
  "secondary",
14959
16338
  "ternary",
@@ -14962,35 +16341,35 @@ function ITThemeProvider({
14962
16341
  "info",
14963
16342
  "alert",
14964
16343
  "warning"
14965
- ].map((key) => /* @__PURE__ */ jsx79(ColorRow, { colorKey: key }, key)) })
16344
+ ].map((key) => /* @__PURE__ */ jsx80(ColorRow, { colorKey: key }, key)) })
14966
16345
  },
14967
16346
  {
14968
16347
  id: "layout",
14969
16348
  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: [
16349
+ 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
16350
  "layout.sidebarBg",
14972
16351
  "layout.sidebarText",
14973
16352
  "layout.navbarBg",
14974
16353
  "layout.navbarText"
14975
- ].map((key) => /* @__PURE__ */ jsx79(ColorRow, { colorKey: key }, key)) })
16354
+ ].map((key) => /* @__PURE__ */ jsx80(ColorRow, { colorKey: key }, key)) })
14976
16355
  },
14977
16356
  {
14978
16357
  id: "tables",
14979
16358
  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: [
16359
+ 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
16360
  "table.headerBg",
14982
16361
  "table.headerText",
14983
16362
  "table.rowBg",
14984
16363
  "table.rowText",
14985
16364
  "table.rowHover"
14986
- ].map((key) => /* @__PURE__ */ jsx79(ColorRow, { colorKey: key }, key)) })
16365
+ ].map((key) => /* @__PURE__ */ jsx80(ColorRow, { colorKey: key }, key)) })
14987
16366
  }
14988
16367
  ]
14989
16368
  }
14990
16369
  ),
14991
16370
  /* @__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(
16371
+ /* @__PURE__ */ jsx80(ITText, { as: "p", className: "text-[11px] text-slate-400 mr-auto", children: t("themeProvider.designer.autosave") }),
16372
+ /* @__PURE__ */ jsx80(
14994
16373
  ITButton,
14995
16374
  {
14996
16375
  label: t("themeProvider.designer.close"),
@@ -15020,7 +16399,13 @@ var createValidationSchema = (fields) => Yup.object().shape(
15020
16399
  }, {})
15021
16400
  );
15022
16401
  export {
16402
+ AXZY_CATALOG_ENTRIES,
16403
+ AXZY_EXCLUDED_TYPES,
16404
+ CURRENT_SCHEMA_VERSION,
16405
+ DEFAULT_LIMITS,
16406
+ DEFAULT_MIGRATIONS,
15023
16407
  FileTypeEnum,
16408
+ GLOBALLY_FORBIDDEN_PROPS,
15024
16409
  ITAccordion,
15025
16410
  ITAlert,
15026
16411
  ITAvatar,
@@ -15064,6 +16449,7 @@ export {
15064
16449
  ITPopover,
15065
16450
  ITProgress,
15066
16451
  ITRadioGroup,
16452
+ ITSchemaRenderer,
15067
16453
  ITSearchSelect,
15068
16454
  ITSearchTable,
15069
16455
  ITSegmentedControl,
@@ -15084,13 +16470,39 @@ export {
15084
16470
  ITToast,
15085
16471
  tripleFilter_default as ITTripleFilter,
15086
16472
  ITWysiwyg,
16473
+ JsonEngineError,
16474
+ NodeBoundary,
15087
16475
  UploadStatus,
16476
+ auditTree,
16477
+ axzyCatalog,
16478
+ axzyCatalogTypes,
16479
+ buildVocabularyContract,
16480
+ countPendingNodes,
16481
+ createCatalog,
16482
+ createLimitTracker,
15088
16483
  createValidationSchema,
15089
16484
  en_default as enMessages,
15090
16485
  es_default as esMessages,
16486
+ formatPath,
16487
+ formatVocabularyForPrompt,
16488
+ getCatalogEntry,
15091
16489
  getContrastTextColor,
16490
+ getExclusionReason,
16491
+ hasPath,
16492
+ isExcludedType,
15092
16493
  isLightColor,
16494
+ isNodePending,
16495
+ issue,
16496
+ migrateSchema,
16497
+ parsePartialSchema,
16498
+ parsePath,
16499
+ propPath,
16500
+ pushPath,
16501
+ readPath,
16502
+ renderNode,
15093
16503
  resolveCssColor,
16504
+ resolveLimits,
16505
+ resolveNode,
15094
16506
  useClickOutside_default as useClickOutside,
15095
16507
  useDebouncedSearch,
15096
16508
  useEditableRow,
@@ -15100,6 +16512,7 @@ export {
15100
16512
  useITThemeSafe,
15101
16513
  useITTranslation,
15102
16514
  useJsonRender_default as useJsonRender,
15103
- useTableState
16515
+ useTableState,
16516
+ validateSchema
15104
16517
  };
15105
16518
  //# sourceMappingURL=index.js.map