hs-uix 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +3 -1
  2. package/common-components.d.ts +319 -68
  3. package/dist/calendar.js +355 -57
  4. package/dist/calendar.mjs +356 -57
  5. package/dist/common-components.js +3546 -88
  6. package/dist/common-components.mjs +3530 -84
  7. package/dist/datatable.js +108 -18
  8. package/dist/datatable.mjs +108 -18
  9. package/dist/experimental.js +2876 -0
  10. package/dist/experimental.mjs +2883 -0
  11. package/dist/feed.js +267 -38
  12. package/dist/feed.mjs +260 -37
  13. package/dist/filter.js +1379 -0
  14. package/dist/filter.mjs +1334 -0
  15. package/dist/form.js +222 -26
  16. package/dist/form.mjs +227 -27
  17. package/dist/index.js +3208 -287
  18. package/dist/index.mjs +3156 -283
  19. package/dist/kanban.js +282 -62
  20. package/dist/kanban.mjs +273 -61
  21. package/dist/safe.js +9207 -0
  22. package/dist/safe.mjs +9298 -0
  23. package/dist/utils.js +491 -75
  24. package/dist/utils.mjs +491 -75
  25. package/experimental.d.ts +1 -0
  26. package/filter.d.ts +1 -0
  27. package/index.d.ts +45 -3
  28. package/package.json +19 -1
  29. package/safe.d.ts +1 -0
  30. package/src/calendar/README.md +74 -5
  31. package/src/calendar/index.d.ts +95 -1
  32. package/src/common-components/README.md +140 -1
  33. package/src/datatable/README.md +0 -2
  34. package/src/experimental/README.md +126 -0
  35. package/src/experimental/index.d.ts +346 -0
  36. package/src/feed/README.md +69 -0
  37. package/src/feed/index.d.ts +103 -0
  38. package/src/filter/README.md +148 -0
  39. package/src/filter/index.d.ts +221 -0
  40. package/src/form/README.md +132 -4
  41. package/src/form/index.d.ts +82 -1
  42. package/src/kanban/README.md +119 -6
  43. package/src/kanban/index.d.ts +153 -2
  44. package/src/safe/README.md +108 -0
  45. package/src/safe/index.d.ts +158 -0
  46. package/src/utils/README.md +39 -0
  47. package/src/wizard/README.md +158 -0
  48. package/src/wizard/index.d.ts +138 -0
  49. package/utils.d.ts +17 -0
package/dist/form.js CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var form_exports = {};
31
31
  __export(form_exports, {
32
32
  FormBuilder: () => FormBuilder,
33
+ fieldsFromHubSpotProperties: () => fieldsFromHubSpotProperties,
33
34
  useFormPrefill: () => useFormPrefill
34
35
  });
35
36
  module.exports = __toCommonJS(form_exports);
@@ -297,7 +298,7 @@ var GENERATED_ICONS = {
297
298
  "ZoomOut": { "viewBox": "0 0 32 32", "paths": ["M14.42 26.75c2.85 0 5.47-.97 7.56-2.6l-.03.02 5.28 5.34a1.619 1.619 0 0 0 2.76-1.15c0-.45-.18-.85-.47-1.14l-5.33-5.33c1.59-2.06 2.55-4.68 2.55-7.52C26.74 7.54 21.2 2 14.37 2S2 7.55 2 14.38s5.54 12.37 12.37 12.37h.05m0-21.55c5.06 0 9.16 4.1 9.16 9.16s-4.1 9.16-9.16 9.16-9.16-4.1-9.16-9.16c.01-5.05 4.11-9.14 9.16-9.15Zm-4.31 10.78h8.62c.89 0 1.62-.72 1.62-1.62s-.72-1.62-1.62-1.62h-8.62c-.89 0-1.62.72-1.62 1.62s.72 1.62 1.62 1.62"] }
298
299
  };
299
300
 
300
- // src/common-components/Icon.js
301
+ // src/common-components/nativeIconNames.js
301
302
  var NATIVE_ICON_NAMES = /* @__PURE__ */ new Set([
302
303
  "add",
303
304
  "appointment",
@@ -309,12 +310,12 @@ var NATIVE_ICON_NAMES = /* @__PURE__ */ new Set([
309
310
  "block",
310
311
  "book",
311
312
  "bulb",
313
+ "callTranscript",
312
314
  "calling",
313
315
  "callingHangup",
314
316
  "callingMade",
315
317
  "callingMissed",
316
318
  "callingVoicemail",
317
- "callTranscript",
318
319
  "campaigns",
319
320
  "cap",
320
321
  "checkCircle",
@@ -343,13 +344,13 @@ var NATIVE_ICON_NAMES = /* @__PURE__ */ new Set([
343
344
  "enroll",
344
345
  "exclamation",
345
346
  "exclamationCircle",
346
- "facebook",
347
347
  "faceHappy",
348
348
  "faceHappyFilled",
349
349
  "faceNeutral",
350
350
  "faceNeutralFilled",
351
351
  "faceSad",
352
352
  "faceSadFilled",
353
+ "facebook",
353
354
  "favoriteHollow",
354
355
  "file",
355
356
  "filledXCircleIcon",
@@ -490,6 +491,8 @@ var NATIVE_ICON_NAMES = /* @__PURE__ */ new Set([
490
491
  "zoomIn",
491
492
  "zoomOut"
492
493
  ]);
494
+
495
+ // src/common-components/Icon.js
493
496
  var NATIVE_COLORS = /* @__PURE__ */ new Set(["inherit", "alert", "warning", "success"]);
494
497
  var NATIVE_SIZE_TOKENS = {
495
498
  sm: "sm",
@@ -985,8 +988,25 @@ var resolveDependentCascade = ({ name, value, fields, values, getEmptyValueForFi
985
988
  return { newValues, changedDependents };
986
989
  };
987
990
 
991
+ // src/form/formDirty.js
992
+ var isFormDirty = (values, initialValues) => !deepEqual(values || {}, initialValues || {});
993
+ var getDirtyFields = (values, initialValues) => {
994
+ const current = values || {};
995
+ const baseline = initialValues || {};
996
+ const names = [...Object.keys(current)];
997
+ for (const name of Object.keys(baseline)) {
998
+ if (!Object.prototype.hasOwnProperty.call(current, name)) names.push(name);
999
+ }
1000
+ return names.filter((name) => !deepEqual(current[name], baseline[name]));
1001
+ };
1002
+
988
1003
  // src/form/FormBuilder.jsx
989
1004
  var getRepeaterErrorKey = (fieldName, rowIdx, subFieldName) => `${fieldName}[${rowIdx}].${subFieldName}`;
1005
+ var withFieldLoadingSpinner = (element, loading) => {
1006
+ if (!loading) return element;
1007
+ return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", gap: "xs", align: "end" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { flex: 1 }, element), /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.LoadingSpinner, { size: "xs", layout: "inline" }));
1008
+ };
1009
+ var formBuilderInstanceCounter = 0;
990
1010
  var fieldSetHasErrors = (errors, fields) => {
991
1011
  if (!errors || !fields || fields.length === 0) return false;
992
1012
  const names = new Set(fields.map((field) => field.name));
@@ -1086,8 +1106,10 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
1086
1106
  // controlled loading state
1087
1107
  disabled = false,
1088
1108
  // disable entire form
1089
- renderButtons: renderButtonsProp
1109
+ renderButtons: renderButtonsProp,
1090
1110
  // custom action row renderer
1111
+ confirmDiscard
1112
+ // true | { title, message, confirmLabel, cancelLabel } — confirm before the built-in Cancel discards dirty changes
1091
1113
  } = props;
1092
1114
  const {
1093
1115
  columns = 1,
@@ -1206,6 +1228,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
1206
1228
  "readOnly",
1207
1229
  "alwaysEditable",
1208
1230
  "disabled",
1231
+ "loading",
1209
1232
  "defaultValue",
1210
1233
  "fieldProps",
1211
1234
  "colSpan",
@@ -1462,7 +1485,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
1462
1485
  syncDirtyBaseline(values);
1463
1486
  }, [values, syncDirtyBaseline]);
1464
1487
  const isDirty = (0, import_react2.useMemo)(() => {
1465
- return !deepEqual(formValues, initialSnapshot.current);
1488
+ return isFormDirty(formValues, initialSnapshot.current);
1466
1489
  }, [formValues]);
1467
1490
  const prevDirtyRef = (0, import_react2.useRef)(false);
1468
1491
  (0, import_react2.useEffect)(() => {
@@ -1471,6 +1494,27 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
1471
1494
  if (onDirtyChange) onDirtyChange(isDirty);
1472
1495
  }
1473
1496
  }, [isDirty, onDirtyChange]);
1497
+ let hostActions = null;
1498
+ try {
1499
+ hostActions = (0, import_ui_extensions2.useExtensionActions)();
1500
+ } catch (err) {
1501
+ hostActions = null;
1502
+ }
1503
+ const discardModalIdRef = (0, import_react2.useRef)(null);
1504
+ if (discardModalIdRef.current === null) {
1505
+ formBuilderInstanceCounter += 1;
1506
+ discardModalIdRef.current = `hs-uix-form-discard-${formBuilderInstanceCounter}`;
1507
+ }
1508
+ const discardConfig = confirmDiscard ? confirmDiscard === true ? {} : confirmDiscard : null;
1509
+ const discardTitle = discardConfig && discardConfig.title || "Discard changes?";
1510
+ const discardMessage = discardConfig && discardConfig.message || "You have unsaved changes. If you discard now, they will be lost.";
1511
+ const discardConfirmLabel = discardConfig && discardConfig.confirmLabel || "Discard changes";
1512
+ const discardCancelLabel = discardConfig && discardConfig.cancelLabel || "Keep editing";
1513
+ const closeDiscardModal = (0, import_react2.useCallback)(() => {
1514
+ if (hostActions && typeof hostActions.closeOverlay === "function") {
1515
+ hostActions.closeOverlay(discardModalIdRef.current);
1516
+ }
1517
+ }, [hostActions]);
1474
1518
  const autoSaveTimerRef = (0, import_react2.useRef)(null);
1475
1519
  const autoSaveRef = (0, import_react2.useRef)(autoSave);
1476
1520
  autoSaveRef.current = autoSave;
@@ -2109,6 +2153,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2109
2153
  },
2110
2154
  getValues: () => formValues,
2111
2155
  isDirty: () => isDirty,
2156
+ getDirtyFields: () => getDirtyFields(formValuesRef.current, initialSnapshot.current),
2112
2157
  setFieldValue: (name, value) => handleFieldChange(name, value),
2113
2158
  setFieldError: (name, message) => updateErrors({ [name]: message }),
2114
2159
  setErrors: (errors) => {
@@ -2128,7 +2173,8 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2128
2173
  const isRequired = showRequiredIndicator && resolveRequired(field, formValues);
2129
2174
  const fieldFormReadOnly = field.alwaysEditable ? false : formReadOnly;
2130
2175
  const isReadOnly = field.readOnly || fieldFormReadOnly;
2131
- const isDisabled = disabled || resolveDisabled(field, formValues) || fieldFormReadOnly;
2176
+ const isFieldLoading = !!field.loading;
2177
+ const isDisabled = disabled || resolveDisabled(field, formValues) || fieldFormReadOnly || isFieldLoading;
2132
2178
  const fieldOnChange = field.debounce ? (v) => handleDebouncedFieldChange(field.name, v) : (v) => handleFieldChange(field.name, v);
2133
2179
  if (field.type === "display" || field.type === "slot") {
2134
2180
  if (field.render) {
@@ -2312,7 +2358,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2312
2358
  disabled: isDisabled,
2313
2359
  error: hasError,
2314
2360
  validationMessage: renderFieldError ? void 0 : fieldError || void 0,
2315
- ...field.loading || validatingFields[field.name] ? { loading: true } : {},
2361
+ ...validatingFields[field.name] ? { loading: true } : {},
2316
2362
  ...field.fieldProps || {}
2317
2363
  };
2318
2364
  const options = resolveOptions(field, formValues);
@@ -2470,25 +2516,31 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2470
2516
  )));
2471
2517
  }
2472
2518
  case "select":
2473
- return /* @__PURE__ */ import_react2.default.createElement(
2474
- import_ui_extensions2.Select,
2475
- {
2476
- ...commonProps,
2477
- value: fieldValue,
2478
- options,
2479
- variant: field.variant,
2480
- onChange: fieldOnChange
2481
- }
2519
+ return withFieldLoadingSpinner(
2520
+ /* @__PURE__ */ import_react2.default.createElement(
2521
+ import_ui_extensions2.Select,
2522
+ {
2523
+ ...commonProps,
2524
+ value: fieldValue,
2525
+ options,
2526
+ variant: field.variant,
2527
+ onChange: fieldOnChange
2528
+ }
2529
+ ),
2530
+ isFieldLoading
2482
2531
  );
2483
2532
  case "multiselect":
2484
- return /* @__PURE__ */ import_react2.default.createElement(
2485
- import_ui_extensions2.MultiSelect,
2486
- {
2487
- ...commonProps,
2488
- value: fieldValue || [],
2489
- options,
2490
- onChange: fieldOnChange
2491
- }
2533
+ return withFieldLoadingSpinner(
2534
+ /* @__PURE__ */ import_react2.default.createElement(
2535
+ import_ui_extensions2.MultiSelect,
2536
+ {
2537
+ ...commonProps,
2538
+ value: fieldValue || [],
2539
+ options,
2540
+ onChange: fieldOnChange
2541
+ }
2542
+ ),
2543
+ isFieldLoading
2492
2544
  );
2493
2545
  case "toggle":
2494
2546
  return /* @__PURE__ */ import_react2.default.createElement(
@@ -3009,6 +3061,30 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
3009
3061
  if (layout) return renderExplicitLayout();
3010
3062
  return renderFieldSubset(visibleFields);
3011
3063
  };
3064
+ const renderCancelButton = () => {
3065
+ if (discardConfig && isDirty) {
3066
+ return /* @__PURE__ */ import_react2.default.createElement(
3067
+ import_ui_extensions2.Button,
3068
+ {
3069
+ variant: "secondary",
3070
+ disabled,
3071
+ overlay: /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Modal, { id: discardModalIdRef.current, title: discardTitle, width: "small" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.ModalBody, null, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, null, discardMessage)), /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.ModalFooter, null, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "secondary", onClick: closeDiscardModal }, discardCancelLabel), /* @__PURE__ */ import_react2.default.createElement(
3072
+ import_ui_extensions2.Button,
3073
+ {
3074
+ variant: "destructive",
3075
+ onClick: () => {
3076
+ closeDiscardModal();
3077
+ if (onCancel) onCancel();
3078
+ }
3079
+ },
3080
+ discardConfirmLabel
3081
+ )))
3082
+ },
3083
+ cancelButtonLabel
3084
+ );
3085
+ }
3086
+ return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "secondary", onClick: onCancel, disabled }, cancelButtonLabel);
3087
+ };
3012
3088
  const renderButtons = () => {
3013
3089
  if (submitPosition === "none" || formReadOnly) return null;
3014
3090
  const isLastStep = !isMultiStep || currentStep === steps.length - 1;
@@ -3022,6 +3098,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
3022
3098
  totalSteps: isMultiStep ? steps.length : 1,
3023
3099
  disabled,
3024
3100
  loading: isLoading,
3101
+ isDirty,
3025
3102
  labels: {
3026
3103
  submit: submitButtonLabel,
3027
3104
  cancel: cancelButtonLabel,
@@ -3037,7 +3114,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
3037
3114
  return renderButtonsProp(buttonContext);
3038
3115
  }
3039
3116
  if (isMultiStep) {
3040
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: "between", align: "center" }, !isFirstStep ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "secondary", onClick: handleBack, disabled }, backButtonLabel) : showCancel ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "secondary", onClick: onCancel, disabled }, cancelButtonLabel) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, null, " "), /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Inline, { gap: "small" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { variant: "microcopy" }, "Step ", currentStep + 1, " of ", steps.length), isLastStep ? /* @__PURE__ */ import_react2.default.createElement(
3117
+ return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: "between", align: "center" }, !isFirstStep ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "secondary", onClick: handleBack, disabled }, backButtonLabel) : showCancel ? renderCancelButton() : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, null, " "), /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Inline, { gap: "small" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { variant: "microcopy" }, "Step ", currentStep + 1, " of ", steps.length), isLastStep ? /* @__PURE__ */ import_react2.default.createElement(
3041
3118
  import_ui_extensions2.LoadingButton,
3042
3119
  {
3043
3120
  variant: submitVariant,
@@ -3048,7 +3125,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
3048
3125
  submitButtonLabel
3049
3126
  ) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "primary", onClick: handleNext, disabled }, nextButtonLabel)));
3050
3127
  }
3051
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: singleStepJustify, gap: "sm" }, showCancel && /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "secondary", onClick: onCancel, disabled }, cancelButtonLabel), /* @__PURE__ */ import_react2.default.createElement(
3128
+ return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: singleStepJustify, gap: "sm" }, showCancel && renderCancelButton(), /* @__PURE__ */ import_react2.default.createElement(
3052
3129
  import_ui_extensions2.LoadingButton,
3053
3130
  {
3054
3131
  variant: submitVariant,
@@ -3088,8 +3165,127 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
3088
3165
  formContent
3089
3166
  );
3090
3167
  });
3168
+ FormBuilder.displayName = "FormBuilder";
3169
+
3170
+ // src/form/hubspotSchema.js
3171
+ var coerceBool = (value) => value === true || value === "true" || value === "Yes" || value === "yes" || value === "1";
3172
+ var coerceNumber = (value) => {
3173
+ if (value === null || value === void 0 || value === "") return void 0;
3174
+ if (typeof value === "number") return value;
3175
+ const parsed = Number(value);
3176
+ return Number.isNaN(parsed) ? void 0 : parsed;
3177
+ };
3178
+ var mapPropertyOptions = (options) => {
3179
+ if (!Array.isArray(options)) return void 0;
3180
+ const mapped = options.filter((opt) => opt && opt.hidden !== true).map((opt) => {
3181
+ const result = { label: opt.label != null ? opt.label : String(opt.value), value: opt.value };
3182
+ if (opt.description != null && opt.description !== "") result.description = opt.description;
3183
+ return result;
3184
+ });
3185
+ return mapped;
3186
+ };
3187
+ var resolveFieldType = (property) => {
3188
+ const { type, fieldType } = property;
3189
+ if (type === "datetime") return "datetime";
3190
+ if (type === "date" || fieldType === "date") return "date";
3191
+ switch (fieldType) {
3192
+ case "select":
3193
+ return "select";
3194
+ // FormBuilder's radio rendering is the "radioGroup" type (native
3195
+ // ToggleGroup with toggleType="radioButtonList").
3196
+ case "radio":
3197
+ return "radioGroup";
3198
+ // HubSpot "checkbox" = multiple checkboxes over an enumeration → multiselect.
3199
+ case "checkbox":
3200
+ return "multiselect";
3201
+ case "booleancheckbox":
3202
+ return "toggle";
3203
+ case "number":
3204
+ return "number";
3205
+ case "textarea":
3206
+ return "textarea";
3207
+ case "text":
3208
+ case "phonenumber":
3209
+ return "text";
3210
+ default:
3211
+ break;
3212
+ }
3213
+ switch (type) {
3214
+ case "enumeration":
3215
+ return "select";
3216
+ case "number":
3217
+ return "number";
3218
+ case "bool":
3219
+ return "toggle";
3220
+ default:
3221
+ return "text";
3222
+ }
3223
+ };
3224
+ var isPropertyReadOnly = (property) => property.calculated === true || property.modificationMetadata && property.modificationMetadata.readOnlyValue === true;
3225
+ var resolveRequiredOverride = (requiredOverrides, name) => {
3226
+ if (!requiredOverrides) return void 0;
3227
+ if (Array.isArray(requiredOverrides)) {
3228
+ return requiredOverrides.includes(name) ? true : void 0;
3229
+ }
3230
+ if (Object.prototype.hasOwnProperty.call(requiredOverrides, name)) {
3231
+ return !!requiredOverrides[name];
3232
+ }
3233
+ return void 0;
3234
+ };
3235
+ var fieldsFromHubSpotProperties = (properties, options = {}) => {
3236
+ if (!Array.isArray(properties)) return [];
3237
+ const {
3238
+ include,
3239
+ exclude,
3240
+ overrides,
3241
+ requiredOverrides,
3242
+ includeDescriptions = false
3243
+ } = options;
3244
+ const includeSet = Array.isArray(include) ? new Set(include) : null;
3245
+ const excludeSet = Array.isArray(exclude) ? new Set(exclude) : null;
3246
+ let selected = properties.filter((property) => {
3247
+ if (!property || !property.name) return false;
3248
+ if (includeSet && !includeSet.has(property.name)) return false;
3249
+ if (excludeSet && excludeSet.has(property.name)) return false;
3250
+ if (property.hidden === true && !includeSet) return false;
3251
+ return true;
3252
+ });
3253
+ if (includeSet) {
3254
+ const order = new Map(include.map((name, idx) => [name, idx]));
3255
+ selected = [...selected].sort((a, b) => order.get(a.name) - order.get(b.name));
3256
+ }
3257
+ return selected.map((property) => {
3258
+ const type = resolveFieldType(property);
3259
+ const field = {
3260
+ name: property.name,
3261
+ type,
3262
+ label: property.label || property.name
3263
+ };
3264
+ if (includeDescriptions && property.description) {
3265
+ field.description = property.description;
3266
+ }
3267
+ if (type === "select" || type === "multiselect" || type === "radioGroup") {
3268
+ field.options = mapPropertyOptions(property.options) || [];
3269
+ }
3270
+ if (type === "toggle") {
3271
+ field.transformIn = coerceBool;
3272
+ field.transformOut = (value) => !!value;
3273
+ }
3274
+ if (type === "number") {
3275
+ field.transformIn = coerceNumber;
3276
+ }
3277
+ if (isPropertyReadOnly(property)) {
3278
+ field.readOnly = true;
3279
+ }
3280
+ const required = resolveRequiredOverride(requiredOverrides, property.name);
3281
+ if (required !== void 0) field.required = required;
3282
+ const override = overrides && overrides[property.name];
3283
+ return override ? { ...field, ...override } : field;
3284
+ });
3285
+ };
3091
3286
  // Annotate the CommonJS export names for ESM import in node:
3092
3287
  0 && (module.exports = {
3093
3288
  FormBuilder,
3289
+ fieldsFromHubSpotProperties,
3094
3290
  useFormPrefill
3095
3291
  });