hs-uix 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/datatable.d.ts CHANGED
@@ -3,6 +3,7 @@ export {
3
3
  DataTableProps,
4
4
  DataTableColumn,
5
5
  DataTableFilterConfig,
6
+ DataTableFilterType,
6
7
  DataTableGroupBy,
7
8
  DataTableSortDirection,
8
9
  DataTableSortObject,
@@ -18,4 +19,9 @@ export {
18
19
  DataTableSelectionAction,
19
20
  DataTableRowAction,
20
21
  DataTableSelectAllRequestPayload,
22
+ DataTableLabels,
23
+ DataTableSelectionBarRenderContext,
24
+ DataTableEmptyStateRenderContext,
25
+ DataTableLoadingStateRenderContext,
26
+ DataTableErrorStateRenderContext,
21
27
  } from "./packages/datatable/index";
package/dist/form.js CHANGED
@@ -262,6 +262,10 @@ var resolveRequired = (field, allValues) => {
262
262
  if (typeof field.required === "function") return field.required(allValues);
263
263
  return !!field.required;
264
264
  };
265
+ var resolveDisabled = (field, allValues) => {
266
+ if (typeof field.disabled === "function") return field.disabled(allValues);
267
+ return !!field.disabled;
268
+ };
265
269
  var resolveOptions = (field, allValues) => {
266
270
  if (typeof field.options === "function") return field.options(allValues);
267
271
  return field.options || [];
@@ -593,7 +597,8 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
593
597
  "defaultOpen",
594
598
  "info",
595
599
  "renderBefore",
596
- "renderAfter"
600
+ "renderAfter",
601
+ "columns"
597
602
  ]);
598
603
  const SECTION_SUGGESTIONS = {
599
604
  title: "Use label instead",
@@ -1306,7 +1311,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
1306
1311
  const hasError = !!fieldError;
1307
1312
  const isRequired = showRequiredIndicator && resolveRequired(field, formValues);
1308
1313
  const isReadOnly = field.readOnly || formReadOnly;
1309
- const isDisabled = disabled || field.disabled || formReadOnly;
1314
+ const isDisabled = disabled || resolveDisabled(field, formValues) || formReadOnly;
1310
1315
  const fieldOnChange = field.debounce ? (v) => handleDebouncedFieldChange(field.name, v) : (v) => handleFieldChange(field.name, v);
1311
1316
  if (field.type === "display") {
1312
1317
  if (field.render) {
@@ -1350,7 +1355,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
1350
1355
  const sfError = formErrors[sf.name] || null;
1351
1356
  const sfLabel = itemIdx === 0 ? sf.label : void 0;
1352
1357
  const sfReadOnly = sf.readOnly || formReadOnly;
1353
- const sfDisabled = disabled || sf.disabled || formReadOnly;
1358
+ const sfDisabled = disabled || resolveDisabled(sf, formValues) || formReadOnly;
1354
1359
  const sfOnChange = sf.debounce ? (v) => handleDebouncedFieldChange(sf.name, v) : (v) => handleFieldChange(sf.name, v);
1355
1360
  const sfProps = {
1356
1361
  name: sf.name,
@@ -1800,7 +1805,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
1800
1805
  label: sfLabel,
1801
1806
  placeholder: sf.placeholder,
1802
1807
  readOnly: sf.readOnly || isReadOnly,
1803
- disabled: sf.disabled || isDisabled,
1808
+ disabled: resolveDisabled(sf, formValues) || isDisabled,
1804
1809
  error: !!sfError,
1805
1810
  validationMessage: sfError || void 0,
1806
1811
  ...sf.fieldProps || {}
@@ -1880,6 +1885,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
1880
1885
  const getFieldColSpan = (field) => {
1881
1886
  if (field.colSpan != null) return Math.min(field.colSpan, columns);
1882
1887
  if (field.width === "full" && columns > 1) return columns;
1888
+ if (columns > 1 && (field.type === "display" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return columns;
1883
1889
  return 1;
1884
1890
  };
1885
1891
  const getDependents = (parentField) => visibleFields.filter(
@@ -1894,24 +1900,31 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
1894
1900
  const tooltipMessage = typeof rawMessage === "function" ? rawMessage(parentField.label) : rawMessage || "";
1895
1901
  return /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Tile, { key: `dep-${parentField.name}`, compact: true }, /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Flex, { direction: "column", gap }, /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Flex, { direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Text, { format: { fontWeight: "demibold" } }, groupLabel, " ", tooltipMessage && /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Link, { inline: true, variant: "dark", overlay: /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Tooltip, null, tooltipMessage) }, /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Icon, { name: "info" })))), renderFieldSubset(dependents)));
1896
1902
  };
1897
- const renderGridLayout = (fieldSubset) => {
1903
+ const renderGridLayout = (fieldSubset, effectiveCols) => {
1904
+ const cols = effectiveCols || columns;
1898
1905
  const fieldList = fieldSubset || visibleFields;
1899
1906
  const elements = [];
1900
1907
  let currentRow = [];
1901
1908
  let currentRowSpan = 0;
1902
- const gridColumnWidth = Math.floor(100 / columns);
1909
+ const gridColumnWidth = 200;
1910
+ const colSpan = (field) => {
1911
+ if (field.colSpan != null) return Math.min(field.colSpan, cols);
1912
+ if (field.width === "full" && cols > 1) return cols;
1913
+ if (cols > 1 && (field.type === "display" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return cols;
1914
+ return 1;
1915
+ };
1903
1916
  const flushRow = () => {
1904
1917
  if (currentRow.length === 0) return;
1905
- const allUniform = currentRow.every((f) => getFieldColSpan(f) === 1);
1906
- const totalSpan = currentRow.reduce((s, f) => s + getFieldColSpan(f), 0);
1907
- const remainder = columns - totalSpan;
1918
+ const allUniform = currentRow.every((f) => colSpan(f) === 1);
1919
+ const totalSpan = currentRow.reduce((s, f) => s + colSpan(f), 0);
1920
+ const remainder = cols - totalSpan;
1908
1921
  if (allUniform) {
1909
1922
  elements.push(
1910
1923
  /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.AutoGrid, { key: `row-${currentRow[0].name}`, columnWidth: gridColumnWidth, flexible: true, gap }, currentRow.map((f) => /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, { key: f.name }, renderField(f))), remainder > 0 && Array.from({ length: remainder }, (_, i) => /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Box, { key: `spacer-${i}` })))
1911
1924
  );
1912
1925
  } else {
1913
1926
  elements.push(
1914
- /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Flex, { key: `row-${currentRow[0].name}`, direction: "row", gap }, currentRow.map((f) => /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Box, { key: f.name, flex: getFieldColSpan(f) }, renderField(f))), remainder > 0 && /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Box, { flex: remainder }))
1927
+ /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Flex, { key: `row-${currentRow[0].name}`, direction: "row", gap }, currentRow.map((f) => /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Box, { key: f.name, flex: colSpan(f) }, renderField(f))), remainder > 0 && /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Box, { flex: remainder }))
1915
1928
  );
1916
1929
  }
1917
1930
  currentRow = [];
@@ -1919,17 +1932,17 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
1919
1932
  };
1920
1933
  for (const field of fieldList) {
1921
1934
  if (isDependent(field)) continue;
1922
- const span = getFieldColSpan(field);
1923
- if (span >= columns) {
1935
+ const span = colSpan(field);
1936
+ if (span >= cols) {
1924
1937
  flushRow();
1925
1938
  elements.push(
1926
1939
  /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, { key: field.name }, renderField(field))
1927
1940
  );
1928
1941
  } else {
1929
- if (currentRowSpan + span > columns) flushRow();
1942
+ if (currentRowSpan + span > cols) flushRow();
1930
1943
  currentRow.push(field);
1931
1944
  currentRowSpan += span;
1932
- if (currentRowSpan >= columns) flushRow();
1945
+ if (currentRowSpan >= cols) flushRow();
1933
1946
  }
1934
1947
  const dependents = getDependents(field);
1935
1948
  if (dependents.length > 0) {
@@ -2078,10 +2091,11 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
2078
2091
  }
2079
2092
  return elements;
2080
2093
  };
2081
- const renderFieldSubset = (fieldSubset) => {
2094
+ const renderFieldSubset = (fieldSubset, overrides) => {
2095
+ const effectiveColumns = overrides && overrides.columns || columns;
2082
2096
  if (layout && fieldSubset === visibleFields) return renderExplicitLayout();
2083
2097
  if (columnWidth) return renderAutoGridLayout(fieldSubset);
2084
- if (columns > 1) return renderGridLayout(fieldSubset);
2098
+ if (effectiveColumns > 1) return renderGridLayout(fieldSubset, effectiveColumns);
2085
2099
  return renderSingleColumnLayout(fieldSubset);
2086
2100
  };
2087
2101
  const renderSections = () => {
@@ -2096,7 +2110,8 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
2096
2110
  const sectionFields = sec.fields ? visibleFields.filter((f) => sec.fields.includes(f.name)) : [];
2097
2111
  if (sectionFields.length === 0) continue;
2098
2112
  const sectionContext = { values: formValues, errors: formErrors };
2099
- const accordionContent = /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Flex, { direction: "column", gap }, sec.renderBefore && sec.renderBefore(sectionContext), renderFieldSubset(sectionFields), sec.renderAfter && sec.renderAfter(sectionContext));
2113
+ const sectionOverrides = sec.columns ? { columns: sec.columns } : void 0;
2114
+ const accordionContent = /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Flex, { direction: "column", gap }, sec.renderBefore && sec.renderBefore(sectionContext), renderFieldSubset(sectionFields, sectionOverrides), sec.renderAfter && sec.renderAfter(sectionContext));
2100
2115
  const accordion = /* @__PURE__ */ import_react.default.createElement(
2101
2116
  import_ui_extensions.Accordion,
2102
2117
  {
package/dist/form.mjs CHANGED
@@ -266,6 +266,10 @@ var resolveRequired = (field, allValues) => {
266
266
  if (typeof field.required === "function") return field.required(allValues);
267
267
  return !!field.required;
268
268
  };
269
+ var resolveDisabled = (field, allValues) => {
270
+ if (typeof field.disabled === "function") return field.disabled(allValues);
271
+ return !!field.disabled;
272
+ };
269
273
  var resolveOptions = (field, allValues) => {
270
274
  if (typeof field.options === "function") return field.options(allValues);
271
275
  return field.options || [];
@@ -597,7 +601,8 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
597
601
  "defaultOpen",
598
602
  "info",
599
603
  "renderBefore",
600
- "renderAfter"
604
+ "renderAfter",
605
+ "columns"
601
606
  ]);
602
607
  const SECTION_SUGGESTIONS = {
603
608
  title: "Use label instead",
@@ -1310,7 +1315,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
1310
1315
  const hasError = !!fieldError;
1311
1316
  const isRequired = showRequiredIndicator && resolveRequired(field, formValues);
1312
1317
  const isReadOnly = field.readOnly || formReadOnly;
1313
- const isDisabled = disabled || field.disabled || formReadOnly;
1318
+ const isDisabled = disabled || resolveDisabled(field, formValues) || formReadOnly;
1314
1319
  const fieldOnChange = field.debounce ? (v) => handleDebouncedFieldChange(field.name, v) : (v) => handleFieldChange(field.name, v);
1315
1320
  if (field.type === "display") {
1316
1321
  if (field.render) {
@@ -1354,7 +1359,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
1354
1359
  const sfError = formErrors[sf.name] || null;
1355
1360
  const sfLabel = itemIdx === 0 ? sf.label : void 0;
1356
1361
  const sfReadOnly = sf.readOnly || formReadOnly;
1357
- const sfDisabled = disabled || sf.disabled || formReadOnly;
1362
+ const sfDisabled = disabled || resolveDisabled(sf, formValues) || formReadOnly;
1358
1363
  const sfOnChange = sf.debounce ? (v) => handleDebouncedFieldChange(sf.name, v) : (v) => handleFieldChange(sf.name, v);
1359
1364
  const sfProps = {
1360
1365
  name: sf.name,
@@ -1804,7 +1809,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
1804
1809
  label: sfLabel,
1805
1810
  placeholder: sf.placeholder,
1806
1811
  readOnly: sf.readOnly || isReadOnly,
1807
- disabled: sf.disabled || isDisabled,
1812
+ disabled: resolveDisabled(sf, formValues) || isDisabled,
1808
1813
  error: !!sfError,
1809
1814
  validationMessage: sfError || void 0,
1810
1815
  ...sf.fieldProps || {}
@@ -1884,6 +1889,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
1884
1889
  const getFieldColSpan = (field) => {
1885
1890
  if (field.colSpan != null) return Math.min(field.colSpan, columns);
1886
1891
  if (field.width === "full" && columns > 1) return columns;
1892
+ if (columns > 1 && (field.type === "display" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return columns;
1887
1893
  return 1;
1888
1894
  };
1889
1895
  const getDependents = (parentField) => visibleFields.filter(
@@ -1898,24 +1904,31 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
1898
1904
  const tooltipMessage = typeof rawMessage === "function" ? rawMessage(parentField.label) : rawMessage || "";
1899
1905
  return /* @__PURE__ */ React.createElement(Tile, { key: `dep-${parentField.name}`, compact: true }, /* @__PURE__ */ React.createElement(Flex, { direction: "column", gap }, /* @__PURE__ */ React.createElement(Flex, { direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ React.createElement(Text, { format: { fontWeight: "demibold" } }, groupLabel, " ", tooltipMessage && /* @__PURE__ */ React.createElement(Link, { inline: true, variant: "dark", overlay: /* @__PURE__ */ React.createElement(Tooltip, null, tooltipMessage) }, /* @__PURE__ */ React.createElement(Icon, { name: "info" })))), renderFieldSubset(dependents)));
1900
1906
  };
1901
- const renderGridLayout = (fieldSubset) => {
1907
+ const renderGridLayout = (fieldSubset, effectiveCols) => {
1908
+ const cols = effectiveCols || columns;
1902
1909
  const fieldList = fieldSubset || visibleFields;
1903
1910
  const elements = [];
1904
1911
  let currentRow = [];
1905
1912
  let currentRowSpan = 0;
1906
- const gridColumnWidth = Math.floor(100 / columns);
1913
+ const gridColumnWidth = 200;
1914
+ const colSpan = (field) => {
1915
+ if (field.colSpan != null) return Math.min(field.colSpan, cols);
1916
+ if (field.width === "full" && cols > 1) return cols;
1917
+ if (cols > 1 && (field.type === "display" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return cols;
1918
+ return 1;
1919
+ };
1907
1920
  const flushRow = () => {
1908
1921
  if (currentRow.length === 0) return;
1909
- const allUniform = currentRow.every((f) => getFieldColSpan(f) === 1);
1910
- const totalSpan = currentRow.reduce((s, f) => s + getFieldColSpan(f), 0);
1911
- const remainder = columns - totalSpan;
1922
+ const allUniform = currentRow.every((f) => colSpan(f) === 1);
1923
+ const totalSpan = currentRow.reduce((s, f) => s + colSpan(f), 0);
1924
+ const remainder = cols - totalSpan;
1912
1925
  if (allUniform) {
1913
1926
  elements.push(
1914
1927
  /* @__PURE__ */ React.createElement(AutoGrid, { key: `row-${currentRow[0].name}`, columnWidth: gridColumnWidth, flexible: true, gap }, currentRow.map((f) => /* @__PURE__ */ React.createElement(React.Fragment, { key: f.name }, renderField(f))), remainder > 0 && Array.from({ length: remainder }, (_, i) => /* @__PURE__ */ React.createElement(Box, { key: `spacer-${i}` })))
1915
1928
  );
1916
1929
  } else {
1917
1930
  elements.push(
1918
- /* @__PURE__ */ React.createElement(Flex, { key: `row-${currentRow[0].name}`, direction: "row", gap }, currentRow.map((f) => /* @__PURE__ */ React.createElement(Box, { key: f.name, flex: getFieldColSpan(f) }, renderField(f))), remainder > 0 && /* @__PURE__ */ React.createElement(Box, { flex: remainder }))
1931
+ /* @__PURE__ */ React.createElement(Flex, { key: `row-${currentRow[0].name}`, direction: "row", gap }, currentRow.map((f) => /* @__PURE__ */ React.createElement(Box, { key: f.name, flex: colSpan(f) }, renderField(f))), remainder > 0 && /* @__PURE__ */ React.createElement(Box, { flex: remainder }))
1919
1932
  );
1920
1933
  }
1921
1934
  currentRow = [];
@@ -1923,17 +1936,17 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
1923
1936
  };
1924
1937
  for (const field of fieldList) {
1925
1938
  if (isDependent(field)) continue;
1926
- const span = getFieldColSpan(field);
1927
- if (span >= columns) {
1939
+ const span = colSpan(field);
1940
+ if (span >= cols) {
1928
1941
  flushRow();
1929
1942
  elements.push(
1930
1943
  /* @__PURE__ */ React.createElement(React.Fragment, { key: field.name }, renderField(field))
1931
1944
  );
1932
1945
  } else {
1933
- if (currentRowSpan + span > columns) flushRow();
1946
+ if (currentRowSpan + span > cols) flushRow();
1934
1947
  currentRow.push(field);
1935
1948
  currentRowSpan += span;
1936
- if (currentRowSpan >= columns) flushRow();
1949
+ if (currentRowSpan >= cols) flushRow();
1937
1950
  }
1938
1951
  const dependents = getDependents(field);
1939
1952
  if (dependents.length > 0) {
@@ -2082,10 +2095,11 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
2082
2095
  }
2083
2096
  return elements;
2084
2097
  };
2085
- const renderFieldSubset = (fieldSubset) => {
2098
+ const renderFieldSubset = (fieldSubset, overrides) => {
2099
+ const effectiveColumns = overrides && overrides.columns || columns;
2086
2100
  if (layout && fieldSubset === visibleFields) return renderExplicitLayout();
2087
2101
  if (columnWidth) return renderAutoGridLayout(fieldSubset);
2088
- if (columns > 1) return renderGridLayout(fieldSubset);
2102
+ if (effectiveColumns > 1) return renderGridLayout(fieldSubset, effectiveColumns);
2089
2103
  return renderSingleColumnLayout(fieldSubset);
2090
2104
  };
2091
2105
  const renderSections = () => {
@@ -2100,7 +2114,8 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
2100
2114
  const sectionFields = sec.fields ? visibleFields.filter((f) => sec.fields.includes(f.name)) : [];
2101
2115
  if (sectionFields.length === 0) continue;
2102
2116
  const sectionContext = { values: formValues, errors: formErrors };
2103
- const accordionContent = /* @__PURE__ */ React.createElement(Flex, { direction: "column", gap }, sec.renderBefore && sec.renderBefore(sectionContext), renderFieldSubset(sectionFields), sec.renderAfter && sec.renderAfter(sectionContext));
2117
+ const sectionOverrides = sec.columns ? { columns: sec.columns } : void 0;
2118
+ const accordionContent = /* @__PURE__ */ React.createElement(Flex, { direction: "column", gap }, sec.renderBefore && sec.renderBefore(sectionContext), renderFieldSubset(sectionFields, sectionOverrides), sec.renderAfter && sec.renderAfter(sectionContext));
2104
2119
  const accordion = /* @__PURE__ */ React.createElement(
2105
2120
  Accordion,
2106
2121
  {
package/dist/index.js CHANGED
@@ -1333,6 +1333,10 @@ var resolveRequired = (field, allValues) => {
1333
1333
  if (typeof field.required === "function") return field.required(allValues);
1334
1334
  return !!field.required;
1335
1335
  };
1336
+ var resolveDisabled = (field, allValues) => {
1337
+ if (typeof field.disabled === "function") return field.disabled(allValues);
1338
+ return !!field.disabled;
1339
+ };
1336
1340
  var resolveOptions = (field, allValues) => {
1337
1341
  if (typeof field.options === "function") return field.options(allValues);
1338
1342
  return field.options || [];
@@ -1664,7 +1668,8 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
1664
1668
  "defaultOpen",
1665
1669
  "info",
1666
1670
  "renderBefore",
1667
- "renderAfter"
1671
+ "renderAfter",
1672
+ "columns"
1668
1673
  ]);
1669
1674
  const SECTION_SUGGESTIONS = {
1670
1675
  title: "Use label instead",
@@ -2377,7 +2382,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2377
2382
  const hasError = !!fieldError;
2378
2383
  const isRequired = showRequiredIndicator && resolveRequired(field, formValues);
2379
2384
  const isReadOnly = field.readOnly || formReadOnly;
2380
- const isDisabled = disabled || field.disabled || formReadOnly;
2385
+ const isDisabled = disabled || resolveDisabled(field, formValues) || formReadOnly;
2381
2386
  const fieldOnChange = field.debounce ? (v) => handleDebouncedFieldChange(field.name, v) : (v) => handleFieldChange(field.name, v);
2382
2387
  if (field.type === "display") {
2383
2388
  if (field.render) {
@@ -2421,7 +2426,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2421
2426
  const sfError = formErrors[sf.name] || null;
2422
2427
  const sfLabel = itemIdx === 0 ? sf.label : void 0;
2423
2428
  const sfReadOnly = sf.readOnly || formReadOnly;
2424
- const sfDisabled = disabled || sf.disabled || formReadOnly;
2429
+ const sfDisabled = disabled || resolveDisabled(sf, formValues) || formReadOnly;
2425
2430
  const sfOnChange = sf.debounce ? (v) => handleDebouncedFieldChange(sf.name, v) : (v) => handleFieldChange(sf.name, v);
2426
2431
  const sfProps = {
2427
2432
  name: sf.name,
@@ -2871,7 +2876,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2871
2876
  label: sfLabel,
2872
2877
  placeholder: sf.placeholder,
2873
2878
  readOnly: sf.readOnly || isReadOnly,
2874
- disabled: sf.disabled || isDisabled,
2879
+ disabled: resolveDisabled(sf, formValues) || isDisabled,
2875
2880
  error: !!sfError,
2876
2881
  validationMessage: sfError || void 0,
2877
2882
  ...sf.fieldProps || {}
@@ -2951,6 +2956,7 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2951
2956
  const getFieldColSpan = (field) => {
2952
2957
  if (field.colSpan != null) return Math.min(field.colSpan, columns);
2953
2958
  if (field.width === "full" && columns > 1) return columns;
2959
+ if (columns > 1 && (field.type === "display" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return columns;
2954
2960
  return 1;
2955
2961
  };
2956
2962
  const getDependents = (parentField) => visibleFields.filter(
@@ -2965,24 +2971,31 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2965
2971
  const tooltipMessage = typeof rawMessage === "function" ? rawMessage(parentField.label) : rawMessage || "";
2966
2972
  return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tile, { key: `dep-${parentField.name}`, compact: true }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { format: { fontWeight: "demibold" } }, groupLabel, " ", tooltipMessage && /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Link, { inline: true, variant: "dark", overlay: /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tooltip, null, tooltipMessage) }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: "info" })))), renderFieldSubset(dependents)));
2967
2973
  };
2968
- const renderGridLayout = (fieldSubset) => {
2974
+ const renderGridLayout = (fieldSubset, effectiveCols) => {
2975
+ const cols = effectiveCols || columns;
2969
2976
  const fieldList = fieldSubset || visibleFields;
2970
2977
  const elements = [];
2971
2978
  let currentRow = [];
2972
2979
  let currentRowSpan = 0;
2973
- const gridColumnWidth = Math.floor(100 / columns);
2980
+ const gridColumnWidth = 200;
2981
+ const colSpan = (field) => {
2982
+ if (field.colSpan != null) return Math.min(field.colSpan, cols);
2983
+ if (field.width === "full" && cols > 1) return cols;
2984
+ if (cols > 1 && (field.type === "display" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return cols;
2985
+ return 1;
2986
+ };
2974
2987
  const flushRow = () => {
2975
2988
  if (currentRow.length === 0) return;
2976
- const allUniform = currentRow.every((f) => getFieldColSpan(f) === 1);
2977
- const totalSpan = currentRow.reduce((s, f) => s + getFieldColSpan(f), 0);
2978
- const remainder = columns - totalSpan;
2989
+ const allUniform = currentRow.every((f) => colSpan(f) === 1);
2990
+ const totalSpan = currentRow.reduce((s, f) => s + colSpan(f), 0);
2991
+ const remainder = cols - totalSpan;
2979
2992
  if (allUniform) {
2980
2993
  elements.push(
2981
2994
  /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.AutoGrid, { key: `row-${currentRow[0].name}`, columnWidth: gridColumnWidth, flexible: true, gap }, currentRow.map((f) => /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, { key: f.name }, renderField(f))), remainder > 0 && Array.from({ length: remainder }, (_, i) => /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { key: `spacer-${i}` })))
2982
2995
  );
2983
2996
  } else {
2984
2997
  elements.push(
2985
- /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { key: `row-${currentRow[0].name}`, direction: "row", gap }, currentRow.map((f) => /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { key: f.name, flex: getFieldColSpan(f) }, renderField(f))), remainder > 0 && /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { flex: remainder }))
2998
+ /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { key: `row-${currentRow[0].name}`, direction: "row", gap }, currentRow.map((f) => /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { key: f.name, flex: colSpan(f) }, renderField(f))), remainder > 0 && /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { flex: remainder }))
2986
2999
  );
2987
3000
  }
2988
3001
  currentRow = [];
@@ -2990,17 +3003,17 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
2990
3003
  };
2991
3004
  for (const field of fieldList) {
2992
3005
  if (isDependent(field)) continue;
2993
- const span = getFieldColSpan(field);
2994
- if (span >= columns) {
3006
+ const span = colSpan(field);
3007
+ if (span >= cols) {
2995
3008
  flushRow();
2996
3009
  elements.push(
2997
3010
  /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, { key: field.name }, renderField(field))
2998
3011
  );
2999
3012
  } else {
3000
- if (currentRowSpan + span > columns) flushRow();
3013
+ if (currentRowSpan + span > cols) flushRow();
3001
3014
  currentRow.push(field);
3002
3015
  currentRowSpan += span;
3003
- if (currentRowSpan >= columns) flushRow();
3016
+ if (currentRowSpan >= cols) flushRow();
3004
3017
  }
3005
3018
  const dependents = getDependents(field);
3006
3019
  if (dependents.length > 0) {
@@ -3149,10 +3162,11 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
3149
3162
  }
3150
3163
  return elements;
3151
3164
  };
3152
- const renderFieldSubset = (fieldSubset) => {
3165
+ const renderFieldSubset = (fieldSubset, overrides) => {
3166
+ const effectiveColumns = overrides && overrides.columns || columns;
3153
3167
  if (layout && fieldSubset === visibleFields) return renderExplicitLayout();
3154
3168
  if (columnWidth) return renderAutoGridLayout(fieldSubset);
3155
- if (columns > 1) return renderGridLayout(fieldSubset);
3169
+ if (effectiveColumns > 1) return renderGridLayout(fieldSubset, effectiveColumns);
3156
3170
  return renderSingleColumnLayout(fieldSubset);
3157
3171
  };
3158
3172
  const renderSections = () => {
@@ -3167,7 +3181,8 @@ var FormBuilder = (0, import_react2.forwardRef)(function FormBuilder2(props, ref
3167
3181
  const sectionFields = sec.fields ? visibleFields.filter((f) => sec.fields.includes(f.name)) : [];
3168
3182
  if (sectionFields.length === 0) continue;
3169
3183
  const sectionContext = { values: formValues, errors: formErrors };
3170
- const accordionContent = /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap }, sec.renderBefore && sec.renderBefore(sectionContext), renderFieldSubset(sectionFields), sec.renderAfter && sec.renderAfter(sectionContext));
3184
+ const sectionOverrides = sec.columns ? { columns: sec.columns } : void 0;
3185
+ const accordionContent = /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap }, sec.renderBefore && sec.renderBefore(sectionContext), renderFieldSubset(sectionFields, sectionOverrides), sec.renderAfter && sec.renderAfter(sectionContext));
3171
3186
  const accordion = /* @__PURE__ */ import_react2.default.createElement(
3172
3187
  import_ui_extensions2.Accordion,
3173
3188
  {
package/dist/index.mjs CHANGED
@@ -1366,6 +1366,10 @@ var resolveRequired = (field, allValues) => {
1366
1366
  if (typeof field.required === "function") return field.required(allValues);
1367
1367
  return !!field.required;
1368
1368
  };
1369
+ var resolveDisabled = (field, allValues) => {
1370
+ if (typeof field.disabled === "function") return field.disabled(allValues);
1371
+ return !!field.disabled;
1372
+ };
1369
1373
  var resolveOptions = (field, allValues) => {
1370
1374
  if (typeof field.options === "function") return field.options(allValues);
1371
1375
  return field.options || [];
@@ -1697,7 +1701,8 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
1697
1701
  "defaultOpen",
1698
1702
  "info",
1699
1703
  "renderBefore",
1700
- "renderAfter"
1704
+ "renderAfter",
1705
+ "columns"
1701
1706
  ]);
1702
1707
  const SECTION_SUGGESTIONS = {
1703
1708
  title: "Use label instead",
@@ -2410,7 +2415,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
2410
2415
  const hasError = !!fieldError;
2411
2416
  const isRequired = showRequiredIndicator && resolveRequired(field, formValues);
2412
2417
  const isReadOnly = field.readOnly || formReadOnly;
2413
- const isDisabled = disabled || field.disabled || formReadOnly;
2418
+ const isDisabled = disabled || resolveDisabled(field, formValues) || formReadOnly;
2414
2419
  const fieldOnChange = field.debounce ? (v) => handleDebouncedFieldChange(field.name, v) : (v) => handleFieldChange(field.name, v);
2415
2420
  if (field.type === "display") {
2416
2421
  if (field.render) {
@@ -2454,7 +2459,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
2454
2459
  const sfError = formErrors[sf.name] || null;
2455
2460
  const sfLabel = itemIdx === 0 ? sf.label : void 0;
2456
2461
  const sfReadOnly = sf.readOnly || formReadOnly;
2457
- const sfDisabled = disabled || sf.disabled || formReadOnly;
2462
+ const sfDisabled = disabled || resolveDisabled(sf, formValues) || formReadOnly;
2458
2463
  const sfOnChange = sf.debounce ? (v) => handleDebouncedFieldChange(sf.name, v) : (v) => handleFieldChange(sf.name, v);
2459
2464
  const sfProps = {
2460
2465
  name: sf.name,
@@ -2904,7 +2909,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
2904
2909
  label: sfLabel,
2905
2910
  placeholder: sf.placeholder,
2906
2911
  readOnly: sf.readOnly || isReadOnly,
2907
- disabled: sf.disabled || isDisabled,
2912
+ disabled: resolveDisabled(sf, formValues) || isDisabled,
2908
2913
  error: !!sfError,
2909
2914
  validationMessage: sfError || void 0,
2910
2915
  ...sf.fieldProps || {}
@@ -2984,6 +2989,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
2984
2989
  const getFieldColSpan = (field) => {
2985
2990
  if (field.colSpan != null) return Math.min(field.colSpan, columns);
2986
2991
  if (field.width === "full" && columns > 1) return columns;
2992
+ if (columns > 1 && (field.type === "display" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return columns;
2987
2993
  return 1;
2988
2994
  };
2989
2995
  const getDependents = (parentField) => visibleFields.filter(
@@ -2998,24 +3004,31 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
2998
3004
  const tooltipMessage = typeof rawMessage === "function" ? rawMessage(parentField.label) : rawMessage || "";
2999
3005
  return /* @__PURE__ */ React2.createElement(Tile, { key: `dep-${parentField.name}`, compact: true }, /* @__PURE__ */ React2.createElement(Flex2, { direction: "column", gap }, /* @__PURE__ */ React2.createElement(Flex2, { direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ React2.createElement(Text2, { format: { fontWeight: "demibold" } }, groupLabel, " ", tooltipMessage && /* @__PURE__ */ React2.createElement(Link2, { inline: true, variant: "dark", overlay: /* @__PURE__ */ React2.createElement(Tooltip, null, tooltipMessage) }, /* @__PURE__ */ React2.createElement(Icon2, { name: "info" })))), renderFieldSubset(dependents)));
3000
3006
  };
3001
- const renderGridLayout = (fieldSubset) => {
3007
+ const renderGridLayout = (fieldSubset, effectiveCols) => {
3008
+ const cols = effectiveCols || columns;
3002
3009
  const fieldList = fieldSubset || visibleFields;
3003
3010
  const elements = [];
3004
3011
  let currentRow = [];
3005
3012
  let currentRowSpan = 0;
3006
- const gridColumnWidth = Math.floor(100 / columns);
3013
+ const gridColumnWidth = 200;
3014
+ const colSpan = (field) => {
3015
+ if (field.colSpan != null) return Math.min(field.colSpan, cols);
3016
+ if (field.width === "full" && cols > 1) return cols;
3017
+ if (cols > 1 && (field.type === "display" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return cols;
3018
+ return 1;
3019
+ };
3007
3020
  const flushRow = () => {
3008
3021
  if (currentRow.length === 0) return;
3009
- const allUniform = currentRow.every((f) => getFieldColSpan(f) === 1);
3010
- const totalSpan = currentRow.reduce((s, f) => s + getFieldColSpan(f), 0);
3011
- const remainder = columns - totalSpan;
3022
+ const allUniform = currentRow.every((f) => colSpan(f) === 1);
3023
+ const totalSpan = currentRow.reduce((s, f) => s + colSpan(f), 0);
3024
+ const remainder = cols - totalSpan;
3012
3025
  if (allUniform) {
3013
3026
  elements.push(
3014
3027
  /* @__PURE__ */ React2.createElement(AutoGrid, { key: `row-${currentRow[0].name}`, columnWidth: gridColumnWidth, flexible: true, gap }, currentRow.map((f) => /* @__PURE__ */ React2.createElement(React2.Fragment, { key: f.name }, renderField(f))), remainder > 0 && Array.from({ length: remainder }, (_, i) => /* @__PURE__ */ React2.createElement(Box2, { key: `spacer-${i}` })))
3015
3028
  );
3016
3029
  } else {
3017
3030
  elements.push(
3018
- /* @__PURE__ */ React2.createElement(Flex2, { key: `row-${currentRow[0].name}`, direction: "row", gap }, currentRow.map((f) => /* @__PURE__ */ React2.createElement(Box2, { key: f.name, flex: getFieldColSpan(f) }, renderField(f))), remainder > 0 && /* @__PURE__ */ React2.createElement(Box2, { flex: remainder }))
3031
+ /* @__PURE__ */ React2.createElement(Flex2, { key: `row-${currentRow[0].name}`, direction: "row", gap }, currentRow.map((f) => /* @__PURE__ */ React2.createElement(Box2, { key: f.name, flex: colSpan(f) }, renderField(f))), remainder > 0 && /* @__PURE__ */ React2.createElement(Box2, { flex: remainder }))
3019
3032
  );
3020
3033
  }
3021
3034
  currentRow = [];
@@ -3023,17 +3036,17 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
3023
3036
  };
3024
3037
  for (const field of fieldList) {
3025
3038
  if (isDependent(field)) continue;
3026
- const span = getFieldColSpan(field);
3027
- if (span >= columns) {
3039
+ const span = colSpan(field);
3040
+ if (span >= cols) {
3028
3041
  flushRow();
3029
3042
  elements.push(
3030
3043
  /* @__PURE__ */ React2.createElement(React2.Fragment, { key: field.name }, renderField(field))
3031
3044
  );
3032
3045
  } else {
3033
- if (currentRowSpan + span > columns) flushRow();
3046
+ if (currentRowSpan + span > cols) flushRow();
3034
3047
  currentRow.push(field);
3035
3048
  currentRowSpan += span;
3036
- if (currentRowSpan >= columns) flushRow();
3049
+ if (currentRowSpan >= cols) flushRow();
3037
3050
  }
3038
3051
  const dependents = getDependents(field);
3039
3052
  if (dependents.length > 0) {
@@ -3182,10 +3195,11 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
3182
3195
  }
3183
3196
  return elements;
3184
3197
  };
3185
- const renderFieldSubset = (fieldSubset) => {
3198
+ const renderFieldSubset = (fieldSubset, overrides) => {
3199
+ const effectiveColumns = overrides && overrides.columns || columns;
3186
3200
  if (layout && fieldSubset === visibleFields) return renderExplicitLayout();
3187
3201
  if (columnWidth) return renderAutoGridLayout(fieldSubset);
3188
- if (columns > 1) return renderGridLayout(fieldSubset);
3202
+ if (effectiveColumns > 1) return renderGridLayout(fieldSubset, effectiveColumns);
3189
3203
  return renderSingleColumnLayout(fieldSubset);
3190
3204
  };
3191
3205
  const renderSections = () => {
@@ -3200,7 +3214,8 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
3200
3214
  const sectionFields = sec.fields ? visibleFields.filter((f) => sec.fields.includes(f.name)) : [];
3201
3215
  if (sectionFields.length === 0) continue;
3202
3216
  const sectionContext = { values: formValues, errors: formErrors };
3203
- const accordionContent = /* @__PURE__ */ React2.createElement(Flex2, { direction: "column", gap }, sec.renderBefore && sec.renderBefore(sectionContext), renderFieldSubset(sectionFields), sec.renderAfter && sec.renderAfter(sectionContext));
3217
+ const sectionOverrides = sec.columns ? { columns: sec.columns } : void 0;
3218
+ const accordionContent = /* @__PURE__ */ React2.createElement(Flex2, { direction: "column", gap }, sec.renderBefore && sec.renderBefore(sectionContext), renderFieldSubset(sectionFields, sectionOverrides), sec.renderAfter && sec.renderAfter(sectionContext));
3204
3219
  const accordion = /* @__PURE__ */ React2.createElement(
3205
3220
  Accordion,
3206
3221
  {
package/form.d.ts CHANGED
@@ -8,6 +8,14 @@ export {
8
8
  FormBuilderDateValue,
9
9
  FormBuilderTimeValue,
10
10
  FormBuilderDateTimeValue,
11
+ FormBuilderValidationContext,
12
+ FormBuilderValidatorResult,
13
+ FormBuilderValidator,
14
+ FormBuilderDependsOnConfig,
15
+ FormBuilderRepeaterProps,
16
+ FormBuilderLabels,
17
+ FormBuilderAlertConfig,
18
+ FormBuilderButtonsRenderContext,
11
19
  FormBuilderLayout,
12
20
  FormBuilderLayoutEntry,
13
21
  FormBuilderSection,
package/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export type {
3
3
  DataTableProps,
4
4
  DataTableColumn,
5
5
  DataTableFilterConfig,
6
+ DataTableFilterType,
6
7
  DataTableGroupBy,
7
8
  DataTableSortDirection,
8
9
  DataTableSortObject,
@@ -18,6 +19,11 @@ export type {
18
19
  DataTableSelectionAction,
19
20
  DataTableRowAction,
20
21
  DataTableSelectAllRequestPayload,
22
+ DataTableLabels,
23
+ DataTableSelectionBarRenderContext,
24
+ DataTableEmptyStateRenderContext,
25
+ DataTableLoadingStateRenderContext,
26
+ DataTableErrorStateRenderContext,
21
27
  } from "./packages/datatable/index";
22
28
 
23
29
  export { FormBuilder, useFormPrefill } from "./packages/form/index";
@@ -29,6 +35,14 @@ export type {
29
35
  FormBuilderDateValue,
30
36
  FormBuilderTimeValue,
31
37
  FormBuilderDateTimeValue,
38
+ FormBuilderValidationContext,
39
+ FormBuilderValidatorResult,
40
+ FormBuilderValidator,
41
+ FormBuilderDependsOnConfig,
42
+ FormBuilderRepeaterProps,
43
+ FormBuilderLabels,
44
+ FormBuilderAlertConfig,
45
+ FormBuilderButtonsRenderContext,
32
46
  FormBuilderLayout,
33
47
  FormBuilderLayoutEntry,
34
48
  FormBuilderSection,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hs-uix",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "Production-ready UI components for HubSpot UI Extensions — DataTable, FormBuilder, and more",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",