@character-foundry/character-foundry 0.1.8-dev.1765911776 → 0.1.8-dev.1765913496

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.
@@ -102,7 +102,7 @@ export interface ExtensionState<TConfig = unknown> {
102
102
  /**
103
103
  * Built-in widget types that AutoForm understands
104
104
  */
105
- export type BuiltinWidget = "text" | "number" | "password" | "textarea" | "switch" | "checkbox" | "select" | "searchable-select" | "radio" | "slider" | "color-picker" | "tag-input" | "file-upload";
105
+ export type BuiltinWidget = "text" | "number" | "password" | "textarea" | "switch" | "checkbox" | "select" | "searchable-select" | "radio" | "radio-group" | "slider" | "range" | "color-picker" | "color" | "tag-input" | "file-upload";
106
106
  /**
107
107
  * Props passed to custom widget components.
108
108
  *
@@ -102,7 +102,7 @@ export interface ExtensionState<TConfig = unknown> {
102
102
  /**
103
103
  * Built-in widget types that AutoForm understands
104
104
  */
105
- export type BuiltinWidget = "text" | "number" | "password" | "textarea" | "switch" | "checkbox" | "select" | "searchable-select" | "radio" | "slider" | "color-picker" | "tag-input" | "file-upload";
105
+ export type BuiltinWidget = "text" | "number" | "password" | "textarea" | "switch" | "checkbox" | "select" | "searchable-select" | "radio" | "radio-group" | "slider" | "range" | "color-picker" | "color" | "tag-input" | "file-upload";
106
106
  /**
107
107
  * Props passed to custom widget components.
108
108
  *
@@ -12,16 +12,19 @@ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
12
12
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
13
13
  import { useState, useCallback, useRef, useEffect, useMemo } from "react";
14
14
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
15
- import { useState as useState2, useCallback as useCallback2 } from "react";
16
15
  import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
17
- import { useState as useState3, useCallback as useCallback3 } from "react";
18
16
  import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
19
- import { useState as useState4, useCallback as useCallback4, useRef as useRef2 } from "react";
20
17
  import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
18
+ import { useState as useState2, useCallback as useCallback2 } from "react";
21
19
  import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
22
- import { Fragment, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
23
- import { useState as useState6, useCallback as useCallback6 } from "react";
20
+ import { useState as useState3, useCallback as useCallback3 } from "react";
21
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
22
+ import { useState as useState4, useCallback as useCallback4, useRef as useRef2 } from "react";
24
23
  import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
24
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
25
+ import { Fragment, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
26
+ import { useState as useState6, useCallback as useCallback6 } from "react";
27
+ import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
25
28
  var noopServices = {
26
29
  toast: {
27
30
  success: () => {
@@ -296,20 +299,25 @@ function analyzeField(name, zodType) {
296
299
  let isNullable = false;
297
300
  let defaultValue;
298
301
  const description = getDescription(zodType);
299
- if (currentType instanceof z.ZodOptional) {
300
- isOptional = true;
301
- currentType = currentType.unwrap();
302
- }
303
- if (currentType instanceof z.ZodNullable) {
304
- isNullable = true;
305
- currentType = currentType.unwrap();
306
- }
307
- if (currentType instanceof z.ZodDefault) {
308
- defaultValue = currentType._def.defaultValue();
309
- currentType = currentType._def.innerType;
310
- }
311
- if (currentType instanceof z.ZodEffects) {
312
- currentType = currentType._def.schema;
302
+ let unwrapping = true;
303
+ while (unwrapping) {
304
+ unwrapping = false;
305
+ if (currentType instanceof z.ZodOptional) {
306
+ isOptional = true;
307
+ currentType = currentType.unwrap();
308
+ unwrapping = true;
309
+ } else if (currentType instanceof z.ZodNullable) {
310
+ isNullable = true;
311
+ currentType = currentType.unwrap();
312
+ unwrapping = true;
313
+ } else if (currentType instanceof z.ZodDefault) {
314
+ defaultValue = currentType._def.defaultValue();
315
+ currentType = currentType._def.innerType;
316
+ unwrapping = true;
317
+ } else if (currentType instanceof z.ZodEffects) {
318
+ currentType = currentType._def.schema;
319
+ unwrapping = true;
320
+ }
313
321
  }
314
322
  if (currentType instanceof z.ZodUnion) {
315
323
  const options = currentType._def.options;
@@ -914,7 +922,7 @@ function SearchableSelect({
914
922
  type: "button",
915
923
  id,
916
924
  onClick: handleOpen,
917
- disabled,
925
+ disabled: disabled || hint?.readOnly,
918
926
  "aria-haspopup": "listbox",
919
927
  "aria-expanded": isOpen,
920
928
  "aria-labelledby": `${id}-label`,
@@ -972,6 +980,191 @@ function SearchableSelect({
972
980
  }
973
981
  );
974
982
  }
983
+ function RadioGroup({
984
+ value,
985
+ onChange,
986
+ name,
987
+ label,
988
+ error,
989
+ disabled,
990
+ required,
991
+ hint
992
+ }) {
993
+ const id = `field-${name}`;
994
+ const errorId = `${id}-error`;
995
+ const helperId = `${id}-helper`;
996
+ const hasError = Boolean(error);
997
+ const hasHelper = Boolean(hint?.helperText);
998
+ const options = hint?.options ?? [];
999
+ return /* @__PURE__ */ jsxs7("div", { className: hint?.className, "data-field": name, "data-error": hasError, children: [
1000
+ /* @__PURE__ */ jsxs7("fieldset", { "data-radio-group": true, children: [
1001
+ label && /* @__PURE__ */ jsxs7("legend", { "data-radio-legend": true, children: [
1002
+ label,
1003
+ required && /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1004
+ ] }),
1005
+ hasHelper && /* @__PURE__ */ jsx7("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1006
+ /* @__PURE__ */ jsx7("div", { "data-radio-options": true, role: "radiogroup", "aria-required": required, children: options.map((opt, index) => {
1007
+ const optionId = `${id}-${index}`;
1008
+ const isChecked = value === opt.value;
1009
+ return /* @__PURE__ */ jsxs7(
1010
+ "label",
1011
+ {
1012
+ htmlFor: optionId,
1013
+ "data-radio-option": true,
1014
+ "data-checked": isChecked,
1015
+ children: [
1016
+ /* @__PURE__ */ jsx7(
1017
+ "input",
1018
+ {
1019
+ id: optionId,
1020
+ type: "radio",
1021
+ name,
1022
+ value: opt.value,
1023
+ checked: isChecked,
1024
+ onChange: (e) => onChange(e.target.value),
1025
+ disabled: disabled || hint?.readOnly,
1026
+ "aria-invalid": hasError,
1027
+ "aria-describedby": [hasError && errorId, hasHelper && helperId].filter(Boolean).join(" ") || void 0
1028
+ }
1029
+ ),
1030
+ /* @__PURE__ */ jsx7("span", { "data-radio-label": true, children: opt.label })
1031
+ ]
1032
+ },
1033
+ opt.value
1034
+ );
1035
+ }) })
1036
+ ] }),
1037
+ hasError && /* @__PURE__ */ jsx7("p", { id: errorId, role: "alert", "data-error-message": true, children: error })
1038
+ ] });
1039
+ }
1040
+ function Slider({
1041
+ value,
1042
+ onChange,
1043
+ name,
1044
+ label,
1045
+ error,
1046
+ disabled,
1047
+ required,
1048
+ hint
1049
+ }) {
1050
+ const id = `field-${name}`;
1051
+ const errorId = `${id}-error`;
1052
+ const helperId = `${id}-helper`;
1053
+ const valueId = `${id}-value`;
1054
+ const hasError = Boolean(error);
1055
+ const hasHelper = Boolean(hint?.helperText);
1056
+ const min = hint?.min ?? 0;
1057
+ const max = hint?.max ?? 100;
1058
+ const step = hint?.step ?? 1;
1059
+ const currentValue = value ?? min;
1060
+ return /* @__PURE__ */ jsxs8("div", { className: hint?.className, "data-field": name, "data-error": hasError, children: [
1061
+ label && /* @__PURE__ */ jsxs8("label", { htmlFor: id, "data-slider-label": true, children: [
1062
+ label,
1063
+ required && /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1064
+ ] }),
1065
+ /* @__PURE__ */ jsxs8("div", { "data-slider-container": true, children: [
1066
+ /* @__PURE__ */ jsx8(
1067
+ "input",
1068
+ {
1069
+ id,
1070
+ type: "range",
1071
+ name,
1072
+ value: currentValue,
1073
+ min,
1074
+ max,
1075
+ step,
1076
+ onChange: (e) => onChange(Number(e.target.value)),
1077
+ disabled: disabled || hint?.readOnly,
1078
+ "aria-invalid": hasError,
1079
+ "aria-valuemin": min,
1080
+ "aria-valuemax": max,
1081
+ "aria-valuenow": currentValue,
1082
+ "aria-describedby": [valueId, hasError && errorId, hasHelper && helperId].filter(Boolean).join(" ") || void 0,
1083
+ "aria-required": required
1084
+ }
1085
+ ),
1086
+ /* @__PURE__ */ jsx8("output", { id: valueId, htmlFor: id, "data-slider-value": true, children: currentValue })
1087
+ ] }),
1088
+ hasHelper && /* @__PURE__ */ jsx8("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1089
+ hasError && /* @__PURE__ */ jsx8("p", { id: errorId, role: "alert", "data-error-message": true, children: error })
1090
+ ] });
1091
+ }
1092
+ function ColorPicker({
1093
+ value,
1094
+ onChange,
1095
+ name,
1096
+ label,
1097
+ error,
1098
+ disabled,
1099
+ required,
1100
+ hint
1101
+ }) {
1102
+ const id = `field-${name}`;
1103
+ const textId = `${id}-text`;
1104
+ const errorId = `${id}-error`;
1105
+ const helperId = `${id}-helper`;
1106
+ const hasError = Boolean(error);
1107
+ const hasHelper = Boolean(hint?.helperText);
1108
+ const currentValue = value || "#000000";
1109
+ const normalizeHex = (hex) => {
1110
+ let clean = hex.replace(/^#/, "");
1111
+ if (clean.length === 3) {
1112
+ clean = clean.split("").map((c) => c + c).join("");
1113
+ }
1114
+ if (/^[0-9a-fA-F]{6}$/.test(clean)) {
1115
+ return `#${clean.toLowerCase()}`;
1116
+ }
1117
+ return currentValue;
1118
+ };
1119
+ return /* @__PURE__ */ jsxs9("div", { className: hint?.className, "data-field": name, "data-error": hasError, children: [
1120
+ label && /* @__PURE__ */ jsxs9("label", { htmlFor: id, "data-color-label": true, children: [
1121
+ label,
1122
+ required && /* @__PURE__ */ jsx9("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1123
+ ] }),
1124
+ /* @__PURE__ */ jsxs9("div", { "data-color-container": true, children: [
1125
+ /* @__PURE__ */ jsx9(
1126
+ "input",
1127
+ {
1128
+ id,
1129
+ type: "color",
1130
+ name,
1131
+ value: currentValue,
1132
+ onChange: (e) => onChange(e.target.value),
1133
+ disabled: disabled || hint?.readOnly,
1134
+ "aria-invalid": hasError,
1135
+ "aria-describedby": [hasError && errorId, hasHelper && helperId].filter(Boolean).join(" ") || void 0,
1136
+ "aria-required": required
1137
+ }
1138
+ ),
1139
+ /* @__PURE__ */ jsx9(
1140
+ "input",
1141
+ {
1142
+ id: textId,
1143
+ type: "text",
1144
+ value: currentValue,
1145
+ onChange: (e) => {
1146
+ const normalized = normalizeHex(e.target.value);
1147
+ onChange(normalized);
1148
+ },
1149
+ onBlur: (e) => {
1150
+ const normalized = normalizeHex(e.target.value);
1151
+ if (normalized !== e.target.value) {
1152
+ onChange(normalized);
1153
+ }
1154
+ },
1155
+ disabled: disabled || hint?.readOnly,
1156
+ placeholder: "#000000",
1157
+ pattern: "^#[0-9a-fA-F]{6}$",
1158
+ maxLength: 7,
1159
+ "data-color-text": true,
1160
+ "aria-label": `${label} hex value`
1161
+ }
1162
+ )
1163
+ ] }),
1164
+ hasHelper && /* @__PURE__ */ jsx9("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1165
+ hasError && /* @__PURE__ */ jsx9("p", { id: errorId, role: "alert", "data-error-message": true, children: error })
1166
+ ] });
1167
+ }
975
1168
  function TagInput({
976
1169
  value,
977
1170
  onChange,
@@ -1021,15 +1214,15 @@ function TagInput({
1021
1214
  addTag(inputValue);
1022
1215
  }
1023
1216
  }, [inputValue, addTag]);
1024
- return /* @__PURE__ */ jsxs7("div", { className: hint?.className, "data-field": name, "data-error": hasError, children: [
1025
- label && /* @__PURE__ */ jsxs7("label", { htmlFor: id, children: [
1217
+ return /* @__PURE__ */ jsxs10("div", { className: hint?.className, "data-field": name, "data-error": hasError, children: [
1218
+ label && /* @__PURE__ */ jsxs10("label", { htmlFor: id, children: [
1026
1219
  label,
1027
- required && /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1220
+ required && /* @__PURE__ */ jsx10("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1028
1221
  ] }),
1029
- /* @__PURE__ */ jsxs7("div", { "data-tag-container": true, children: [
1030
- tags.map((tag, index) => /* @__PURE__ */ jsxs7("span", { "data-tag": true, children: [
1222
+ /* @__PURE__ */ jsxs10("div", { "data-tag-container": true, children: [
1223
+ tags.map((tag, index) => /* @__PURE__ */ jsxs10("span", { "data-tag": true, children: [
1031
1224
  tag,
1032
- !disabled && !hint?.readOnly && /* @__PURE__ */ jsx7(
1225
+ !disabled && !hint?.readOnly && /* @__PURE__ */ jsx10(
1033
1226
  "button",
1034
1227
  {
1035
1228
  type: "button",
@@ -1040,7 +1233,7 @@ function TagInput({
1040
1233
  }
1041
1234
  )
1042
1235
  ] }, `${tag}-${index}`)),
1043
- /* @__PURE__ */ jsx7(
1236
+ /* @__PURE__ */ jsx10(
1044
1237
  "input",
1045
1238
  {
1046
1239
  id,
@@ -1058,8 +1251,8 @@ function TagInput({
1058
1251
  }
1059
1252
  )
1060
1253
  ] }),
1061
- hasHelper && /* @__PURE__ */ jsx7("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1062
- hasError && /* @__PURE__ */ jsx7("p", { id: errorId, role: "alert", "data-error-message": true, children: error })
1254
+ hasHelper && /* @__PURE__ */ jsx10("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1255
+ hasError && /* @__PURE__ */ jsx10("p", { id: errorId, role: "alert", "data-error-message": true, children: error })
1063
1256
  ] });
1064
1257
  }
1065
1258
  function SecretInput({
@@ -1081,13 +1274,13 @@ function SecretInput({
1081
1274
  const toggleVisibility = useCallback3(() => {
1082
1275
  setShowValue((prev) => !prev);
1083
1276
  }, []);
1084
- return /* @__PURE__ */ jsxs8("div", { className: hint?.className, "data-field": name, "data-error": hasError, children: [
1085
- label && /* @__PURE__ */ jsxs8("label", { htmlFor: id, children: [
1277
+ return /* @__PURE__ */ jsxs11("div", { className: hint?.className, "data-field": name, "data-error": hasError, children: [
1278
+ label && /* @__PURE__ */ jsxs11("label", { htmlFor: id, children: [
1086
1279
  label,
1087
- required && /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1280
+ required && /* @__PURE__ */ jsx11("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1088
1281
  ] }),
1089
- /* @__PURE__ */ jsxs8("div", { "data-secret-container": true, children: [
1090
- /* @__PURE__ */ jsx8(
1282
+ /* @__PURE__ */ jsxs11("div", { "data-secret-container": true, children: [
1283
+ /* @__PURE__ */ jsx11(
1091
1284
  "input",
1092
1285
  {
1093
1286
  id,
@@ -1105,7 +1298,7 @@ function SecretInput({
1105
1298
  "data-secret-input": true
1106
1299
  }
1107
1300
  ),
1108
- /* @__PURE__ */ jsx8(
1301
+ /* @__PURE__ */ jsx11(
1109
1302
  "button",
1110
1303
  {
1111
1304
  type: "button",
@@ -1117,8 +1310,8 @@ function SecretInput({
1117
1310
  }
1118
1311
  )
1119
1312
  ] }),
1120
- hasHelper && /* @__PURE__ */ jsx8("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1121
- hasError && /* @__PURE__ */ jsx8("p", { id: errorId, role: "alert", "data-error-message": true, children: error })
1313
+ hasHelper && /* @__PURE__ */ jsx11("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1314
+ hasError && /* @__PURE__ */ jsx11("p", { id: errorId, role: "alert", "data-error-message": true, children: error })
1122
1315
  ] });
1123
1316
  }
1124
1317
  function FileUpload({
@@ -1255,12 +1448,12 @@ function FileUpload({
1255
1448
  );
1256
1449
  const displayError = error ?? localError;
1257
1450
  const files = multiple ? Array.isArray(value) ? value : [] : value instanceof File ? [value] : [];
1258
- return /* @__PURE__ */ jsxs9("div", { className: hint?.className, "data-field": name, "data-error": Boolean(displayError), children: [
1259
- label && /* @__PURE__ */ jsxs9("label", { htmlFor: id, children: [
1451
+ return /* @__PURE__ */ jsxs12("div", { className: hint?.className, "data-field": name, "data-error": Boolean(displayError), children: [
1452
+ label && /* @__PURE__ */ jsxs12("label", { htmlFor: id, children: [
1260
1453
  label,
1261
- required && /* @__PURE__ */ jsx9("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1454
+ required && /* @__PURE__ */ jsx12("span", { "aria-hidden": "true", "data-required": true, children: "*" })
1262
1455
  ] }),
1263
- /* @__PURE__ */ jsxs9(
1456
+ /* @__PURE__ */ jsxs12(
1264
1457
  "div",
1265
1458
  {
1266
1459
  "data-file-dropzone": true,
@@ -1271,10 +1464,10 @@ function FileUpload({
1271
1464
  onDrop: handleDrop,
1272
1465
  onClick: handleClick,
1273
1466
  role: "button",
1274
- tabIndex: disabled ? -1 : 0,
1467
+ tabIndex: disabled || hint?.readOnly ? -1 : 0,
1275
1468
  "aria-describedby": [Boolean(displayError) && errorId, hasHelper && helperId].filter(Boolean).join(" ") || void 0,
1276
1469
  children: [
1277
- /* @__PURE__ */ jsx9(
1470
+ /* @__PURE__ */ jsx12(
1278
1471
  "input",
1279
1472
  {
1280
1473
  ref: inputRef,
@@ -1283,21 +1476,21 @@ function FileUpload({
1283
1476
  name,
1284
1477
  accept,
1285
1478
  multiple,
1286
- disabled,
1479
+ disabled: disabled || hint?.readOnly,
1287
1480
  onChange: handleChange,
1288
1481
  "aria-invalid": Boolean(displayError),
1289
1482
  "aria-required": required,
1290
1483
  "data-file-input": true
1291
1484
  }
1292
1485
  ),
1293
- files.length === 0 ? /* @__PURE__ */ jsx9("p", { "data-file-placeholder": true, children: hint?.placeholder ?? (isDragging ? "Drop files here..." : "Click or drag files to upload") }) : /* @__PURE__ */ jsx9("ul", { "data-file-list": true, children: files.map((file, index) => /* @__PURE__ */ jsxs9("li", { "data-file-item": true, children: [
1294
- /* @__PURE__ */ jsx9("span", { "data-file-name": true, children: file.name }),
1295
- /* @__PURE__ */ jsxs9("span", { "data-file-size": true, children: [
1486
+ files.length === 0 ? /* @__PURE__ */ jsx12("p", { "data-file-placeholder": true, children: hint?.placeholder ?? (isDragging ? "Drop files here..." : "Click or drag files to upload") }) : /* @__PURE__ */ jsx12("ul", { "data-file-list": true, children: files.map((file, index) => /* @__PURE__ */ jsxs12("li", { "data-file-item": true, children: [
1487
+ /* @__PURE__ */ jsx12("span", { "data-file-name": true, children: file.name }),
1488
+ /* @__PURE__ */ jsxs12("span", { "data-file-size": true, children: [
1296
1489
  "(",
1297
1490
  formatFileSize(file.size),
1298
1491
  ")"
1299
1492
  ] }),
1300
- !disabled && !hint?.readOnly && /* @__PURE__ */ jsx9(
1493
+ !disabled && !hint?.readOnly && /* @__PURE__ */ jsx12(
1301
1494
  "button",
1302
1495
  {
1303
1496
  type: "button",
@@ -1314,8 +1507,8 @@ function FileUpload({
1314
1507
  ]
1315
1508
  }
1316
1509
  ),
1317
- hasHelper && /* @__PURE__ */ jsx9("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1318
- displayError && /* @__PURE__ */ jsx9("p", { id: errorId, role: "alert", "data-error-message": true, children: displayError })
1510
+ hasHelper && /* @__PURE__ */ jsx12("p", { id: helperId, "data-helper": true, children: hint?.helperText }),
1511
+ displayError && /* @__PURE__ */ jsx12("p", { id: errorId, role: "alert", "data-error-message": true, children: displayError })
1319
1512
  ] });
1320
1513
  }
1321
1514
  function formatFileSize(bytes) {
@@ -1331,15 +1524,15 @@ var BUILTIN_WIDGETS = {
1331
1524
  checkbox: Switch,
1332
1525
  select: Select,
1333
1526
  "searchable-select": SearchableSelect,
1334
- radio: Select,
1335
- // Could be RadioGroup
1527
+ radio: RadioGroup,
1528
+ "radio-group": RadioGroup,
1336
1529
  password: SecretInput,
1337
1530
  "tag-input": TagInput,
1338
1531
  "file-upload": FileUpload,
1339
- slider: NumberInput,
1340
- // Could be Slider widget
1341
- "color-picker": TextInput
1342
- // Could be ColorPicker widget
1532
+ slider: Slider,
1533
+ range: Slider,
1534
+ "color-picker": ColorPicker,
1535
+ color: ColorPicker
1343
1536
  };
1344
1537
  var TYPE_TO_WIDGET = {
1345
1538
  ZodString: TextInput,
@@ -1362,10 +1555,10 @@ function FieldRenderer({
1362
1555
  if (fieldInfo.typeName === "ZodObject" && fieldInfo.nestedFields && renderNestedField) {
1363
1556
  const nestedFields = Array.from(fieldInfo.nestedFields.values());
1364
1557
  const fieldBaseName2 = fieldInfo.name.split(".").pop() ?? fieldInfo.name;
1365
- return /* @__PURE__ */ jsx10("div", { "data-nested-object": true, "data-field": fieldInfo.name, children: /* @__PURE__ */ jsxs10("fieldset", { "data-nested-fieldset": true, children: [
1366
- /* @__PURE__ */ jsx10("legend", { "data-nested-legend": true, children: hint?.label ?? fieldInfo.description ?? formatLabel(fieldBaseName2) }),
1367
- hint?.helperText && /* @__PURE__ */ jsx10("p", { "data-helper": true, children: hint.helperText }),
1368
- /* @__PURE__ */ jsx10("div", { "data-nested-fields": true, children: nestedFields.map((nestedInfo) => renderNestedField(nestedInfo)) })
1558
+ return /* @__PURE__ */ jsx13("div", { "data-nested-object": true, "data-field": fieldInfo.name, children: /* @__PURE__ */ jsxs13("fieldset", { "data-nested-fieldset": true, children: [
1559
+ /* @__PURE__ */ jsx13("legend", { "data-nested-legend": true, children: hint?.label ?? fieldInfo.description ?? formatLabel(fieldBaseName2) }),
1560
+ hint?.helperText && /* @__PURE__ */ jsx13("p", { "data-helper": true, children: hint.helperText }),
1561
+ /* @__PURE__ */ jsx13("div", { "data-nested-fields": true, children: nestedFields.map((nestedInfo) => renderNestedField(nestedInfo)) })
1369
1562
  ] }) });
1370
1563
  }
1371
1564
  let Widget;
@@ -1406,11 +1599,30 @@ function FieldRenderer({
1406
1599
  max: hint?.max ?? fieldInfo.constraints?.max ?? fieldInfo.constraints?.maxLength
1407
1600
  }
1408
1601
  };
1409
- return /* @__PURE__ */ jsx10(Widget, { ...props });
1602
+ return /* @__PURE__ */ jsx13(Widget, { ...props });
1410
1603
  }
1411
1604
  function formatLabel(name) {
1412
1605
  return name.replace(/([A-Z])/g, " $1").replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase()).trim();
1413
1606
  }
1607
+ var HINT_KEYS = /* @__PURE__ */ new Set([
1608
+ "widget",
1609
+ "label",
1610
+ "placeholder",
1611
+ "helperText",
1612
+ "hidden",
1613
+ "readOnly",
1614
+ "className",
1615
+ "condition",
1616
+ "group",
1617
+ "rows",
1618
+ "accept",
1619
+ "multiple",
1620
+ "maxSize",
1621
+ "options",
1622
+ "searchable",
1623
+ "searchPlaceholder",
1624
+ "noResultsText"
1625
+ ]);
1414
1626
  function AutoForm({
1415
1627
  schema,
1416
1628
  values,
@@ -1470,7 +1682,9 @@ function AutoForm({
1470
1682
  fields.add(condition.field);
1471
1683
  }
1472
1684
  }
1473
- if (!("widget" in hint) && !("label" in hint) && !("condition" in hint)) {
1685
+ const hintKeys = Object.keys(hint);
1686
+ const isHintObject = hintKeys.length > 0 && hintKeys.every((k) => HINT_KEYS.has(k));
1687
+ if (!isHintObject) {
1474
1688
  extractConditionFields(hint, prefix ? `${prefix}.${key}` : key);
1475
1689
  }
1476
1690
  }
@@ -1522,28 +1736,10 @@ function AutoForm({
1522
1736
  });
1523
1737
  return () => subscription.unsubscribe();
1524
1738
  }, [watch]);
1525
- const HINT_KEYS = /* @__PURE__ */ new Set([
1526
- "widget",
1527
- "label",
1528
- "placeholder",
1529
- "helperText",
1530
- "hidden",
1531
- "readOnly",
1532
- "className",
1533
- "condition",
1534
- "group",
1535
- "rows",
1536
- "accept",
1537
- "multiple",
1538
- "maxSize",
1539
- "options",
1540
- "searchable",
1541
- "searchPlaceholder",
1542
- "noResultsText"
1543
- ]);
1544
1739
  const isFieldUIHint = useCallback5((obj) => {
1545
1740
  if (!obj || typeof obj !== "object") return false;
1546
- return Object.keys(obj).some((key) => HINT_KEYS.has(key));
1741
+ const keys = Object.keys(obj);
1742
+ return keys.length > 0 && keys.every((key) => HINT_KEYS.has(key));
1547
1743
  }, []);
1548
1744
  const getHint = useCallback5(
1549
1745
  (fieldName) => {
@@ -1601,12 +1797,12 @@ function AutoForm({
1601
1797
  const hint = getHint(fieldInfo.name);
1602
1798
  if (hint?.hidden) return null;
1603
1799
  if (!isConditionMet(hint?.condition)) return null;
1604
- return /* @__PURE__ */ jsx11(
1800
+ return /* @__PURE__ */ jsx14(
1605
1801
  Controller,
1606
1802
  {
1607
1803
  name: fieldInfo.name,
1608
1804
  control,
1609
- render: ({ field, fieldState }) => /* @__PURE__ */ jsx11(
1805
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsx14(
1610
1806
  FieldRenderer,
1611
1807
  {
1612
1808
  fieldInfo,
@@ -1651,7 +1847,7 @@ function AutoForm({
1651
1847
  },
1652
1848
  [flatFieldInfoMap, getField, getHint]
1653
1849
  );
1654
- const submitButton = withSubmit ? /* @__PURE__ */ jsx11(
1850
+ const submitButton = withSubmit ? /* @__PURE__ */ jsx14(
1655
1851
  "button",
1656
1852
  {
1657
1853
  type: "submit",
@@ -1660,7 +1856,7 @@ function AutoForm({
1660
1856
  children: formState.isSubmitting ? "Submitting..." : submitText
1661
1857
  }
1662
1858
  ) : null;
1663
- const formContent = /* @__PURE__ */ jsx11(FormProvider, { ...methods, children: /* @__PURE__ */ jsx11("form", { onSubmit: onFormSubmit, className, "data-autoform": true, children: children ? children({
1859
+ const formContent = /* @__PURE__ */ jsx14(FormProvider, { ...methods, children: /* @__PURE__ */ jsx14("form", { onSubmit: onFormSubmit, className, "data-autoform": true, children: children ? children({
1664
1860
  fields: renderedFields,
1665
1861
  submit: submitButton,
1666
1862
  formState: {
@@ -1670,12 +1866,12 @@ function AutoForm({
1670
1866
  },
1671
1867
  getField,
1672
1868
  getFieldsByGroup
1673
- }) : /* @__PURE__ */ jsxs11(Fragment, { children: [
1869
+ }) : /* @__PURE__ */ jsxs14(Fragment, { children: [
1674
1870
  renderedFields,
1675
1871
  submitButton
1676
1872
  ] }) }) });
1677
1873
  if (widgetRegistry2) {
1678
- return /* @__PURE__ */ jsx11(WidgetRegistryContext.Provider, { value: widgetRegistry2, children: formContent });
1874
+ return /* @__PURE__ */ jsx14(WidgetRegistryContext.Provider, { value: widgetRegistry2, children: formContent });
1679
1875
  }
1680
1876
  return formContent;
1681
1877
  }
@@ -1761,7 +1957,7 @@ function FieldGroup({
1761
1957
  }, [collapsible]);
1762
1958
  const headerId = `fieldgroup-${title.toLowerCase().replace(/\s+/g, "-")}`;
1763
1959
  const contentId = `${headerId}-content`;
1764
- return /* @__PURE__ */ jsxs12(
1960
+ return /* @__PURE__ */ jsxs15(
1765
1961
  "fieldset",
1766
1962
  {
1767
1963
  className,
@@ -1769,7 +1965,7 @@ function FieldGroup({
1769
1965
  "data-collapsible": collapsible,
1770
1966
  "data-collapsed": isCollapsed,
1771
1967
  children: [
1772
- collapsible ? /* @__PURE__ */ jsx12("legend", { children: /* @__PURE__ */ jsxs12(
1968
+ collapsible ? /* @__PURE__ */ jsx15("legend", { children: /* @__PURE__ */ jsxs15(
1773
1969
  "button",
1774
1970
  {
1775
1971
  type: "button",
@@ -1778,13 +1974,13 @@ function FieldGroup({
1778
1974
  "aria-controls": contentId,
1779
1975
  "data-fieldgroup-toggle": true,
1780
1976
  children: [
1781
- /* @__PURE__ */ jsx12("span", { "data-fieldgroup-arrow": true, "aria-hidden": "true", children: isCollapsed ? "\u25B6" : "\u25BC" }),
1782
- /* @__PURE__ */ jsx12("span", { id: headerId, "data-fieldgroup-title": true, children: title })
1977
+ /* @__PURE__ */ jsx15("span", { "data-fieldgroup-arrow": true, "aria-hidden": "true", children: isCollapsed ? "\u25B6" : "\u25BC" }),
1978
+ /* @__PURE__ */ jsx15("span", { id: headerId, "data-fieldgroup-title": true, children: title })
1783
1979
  ]
1784
1980
  }
1785
- ) }) : /* @__PURE__ */ jsx12("legend", { id: headerId, "data-fieldgroup-title": true, children: title }),
1786
- description && /* @__PURE__ */ jsx12("p", { "data-fieldgroup-description": true, children: description }),
1787
- /* @__PURE__ */ jsx12(
1981
+ ) }) : /* @__PURE__ */ jsx15("legend", { id: headerId, "data-fieldgroup-title": true, children: title }),
1982
+ description && /* @__PURE__ */ jsx15("p", { "data-fieldgroup-description": true, children: description }),
1983
+ /* @__PURE__ */ jsx15(
1788
1984
  "div",
1789
1985
  {
1790
1986
  id: contentId,