@bsol-oss/react-datatable5 12.0.0-beta.41 → 12.0.0-beta.43

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/dist/index.d.ts CHANGED
@@ -471,7 +471,9 @@ interface CustomJSONSchema7 extends JSONSchema7 {
471
471
  }) => ReactNode;
472
472
  dateFormat?: string;
473
473
  displayDateFormat?: string;
474
- format?: string;
474
+ timeFormat?: string;
475
+ displayTimeFormat?: string;
476
+ showTitle?: boolean;
475
477
  }
476
478
 
477
479
  interface FormRootProps<TData extends FieldValues> {
package/dist/index.js CHANGED
@@ -3651,13 +3651,17 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
3651
3651
  const isRequired = required?.some((columnId) => columnId === column);
3652
3652
  const { formState: { errors }, setValue, watch, } = reactHookForm.useFormContext();
3653
3653
  const fields = (watch(colLabel) ?? []);
3654
- return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] }), fields.map((field, index) => (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", children: [jsxRuntime.jsx(react.Box, { children: index + 1 }), jsxRuntime.jsx(react.Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaRenderer, { column: `${index}`,
3655
- prefix: `${colLabel}.`,
3656
- schema: items }) }), jsxRuntime.jsx(react.Flex, { justifyContent: "end", children: jsxRuntime.jsx(react.Button, { variant: "ghost", onClick: () => {
3657
- setValue(colLabel, fields.filter((_, curIndex) => {
3658
- return curIndex !== index;
3659
- }));
3660
- }, children: translate.t(removeIndex(`${colLabel}.remove`)) }) })] }, `${colLabel}.${index}`))), jsxRuntime.jsx(react.Flex, { children: jsxRuntime.jsx(react.Button, { onClick: () => {
3654
+ return (jsxRuntime.jsxs(react.Flex, { gridRow, gridColumn, flexFlow: "column", gap: 2, children: [jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 2, children: fields.map((field, index) => (jsxRuntime.jsxs(react.Flex, { flexFlow: "row", gap: 2, bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
3655
+ base: "colorPalette.200",
3656
+ _dark: "colorPalette.800",
3657
+ }, children: [jsxRuntime.jsx(react.Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaRenderer, { column: `${index}`,
3658
+ prefix: `${colLabel}.`,
3659
+ // @ts-expect-error find suitable types
3660
+ schema: { showTitle: false, ...(items ?? {}) } }) }), jsxRuntime.jsx(react.Flex, { justifyContent: "end", children: jsxRuntime.jsx(react.Button, { variant: "ghost", onClick: () => {
3661
+ setValue(colLabel, fields.filter((_, curIndex) => {
3662
+ return curIndex !== index;
3663
+ }));
3664
+ }, children: jsxRuntime.jsx(react.Icon, { children: jsxRuntime.jsx(cg.CgTrash, {}) }) }) })] }, `${colLabel}.${index}`))) }), jsxRuntime.jsx(react.Flex, { children: jsxRuntime.jsx(react.Button, { onClick: () => {
3661
3665
  if (type === "number") {
3662
3666
  setValue(colLabel, [...fields, 0]);
3663
3667
  return;
@@ -4496,7 +4500,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4496
4500
  borderRadius: "4px",
4497
4501
  border: "1px solid #ccc",
4498
4502
  fontSize: "14px",
4499
- }, children: [jsxRuntime.jsx("option", { value: "5", children: "5" }), jsxRuntime.jsx("option", { value: "10", children: "10" }), jsxRuntime.jsx("option", { value: "20", children: "20" }), jsxRuntime.jsx("option", { value: "50", children: "50" })] }) })] }), jsxRuntime.jsx(react.Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: dataList.length > 0 ? (jsxRuntime.jsx(react.Flex, { flexFlow: "column wrap", children: dataList.map((item) => {
4503
+ }, children: [jsxRuntime.jsx("option", { value: "5", children: "5" }), jsxRuntime.jsx("option", { value: "10", children: "10" }), jsxRuntime.jsx("option", { value: "20", children: "20" }), jsxRuntime.jsx("option", { value: "30", children: "30" })] }) })] }), jsxRuntime.jsx(react.Grid, { overflowY: "auto", children: dataList.length > 0 ? (jsxRuntime.jsx(react.Flex, { flexFlow: "column wrap", gap: 1, children: dataList.map((item) => {
4500
4504
  const selected = isMultiple
4501
4505
  ? watchIds.some((id) => item[column_ref] === id)
4502
4506
  : watchId === item[column_ref];
@@ -4545,7 +4549,7 @@ const NumberInputField = ({ schema, column, prefix, }) => {
4545
4549
  };
4546
4550
 
4547
4551
  const ObjectInput = ({ schema, column, prefix }) => {
4548
- const { properties, gridColumn = "span 12", gridRow = "span 1", required, } = schema;
4552
+ const { properties, gridColumn = "span 12", gridRow = "span 1", required, showTitle = true, } = schema;
4549
4553
  const { translate } = useSchemaContext();
4550
4554
  const colLabel = `${prefix}${column}`;
4551
4555
  const isRequired = required?.some((columnId) => columnId === column);
@@ -4553,7 +4557,10 @@ const ObjectInput = ({ schema, column, prefix }) => {
4553
4557
  if (properties === undefined) {
4554
4558
  throw new Error(`properties is undefined when using ObjectInput`);
4555
4559
  }
4556
- return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] }), jsxRuntime.jsx(react.Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
4560
+ return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [showTitle && (jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] })), jsxRuntime.jsx(react.Grid, { bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
4561
+ base: "colorPalette.200",
4562
+ _dark: "colorPalette.800",
4563
+ }, gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
4557
4564
  return (
4558
4565
  // @ts-expect-error find suitable types
4559
4566
  jsxRuntime.jsx(ColumnRenderer, { column: `${key}`,
@@ -4734,7 +4741,7 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
4734
4741
  // Refs for focus management
4735
4742
  const hourInputRef = React.useRef(null);
4736
4743
  const minuteInputRef = React.useRef(null);
4737
- const meridiemInputRef = React.useRef(null);
4744
+ React.useRef(null);
4738
4745
  // Centralized handler for key events, value changes, and focus management
4739
4746
  const handleKeyDown = (e, field) => {
4740
4747
  const input = e.target;
@@ -4786,9 +4793,10 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
4786
4793
  if (e.key.match(/^[0-9]$/)) {
4787
4794
  const newValue = value + e.key;
4788
4795
  const numValue = parseInt(newValue, 10);
4796
+ console.log("newValue minute", newValue, numValue, numValue > 60, numValue >= 0 && numValue <= 59, e.key);
4789
4797
  if (numValue > 60) {
4790
4798
  const digitValue = parseInt(e.key, 10);
4791
- setHour(digitValue);
4799
+ setMinute(digitValue);
4792
4800
  onChange({ hour, minute: digitValue, meridiem });
4793
4801
  return;
4794
4802
  }
@@ -4797,94 +4805,8 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
4797
4805
  // Set the minute value
4798
4806
  setMinute(numValue);
4799
4807
  onChange({ hour, minute: numValue, meridiem });
4800
- // Move to meridiem input
4801
- e.preventDefault();
4802
- meridiemInputRef.current?.focus();
4803
- }
4804
- }
4805
- }
4806
- else if (field === "meridiem") {
4807
- const key = e.key.toLowerCase();
4808
- if (key === "a") {
4809
- e.preventDefault();
4810
- setMeridiem("am");
4811
- onChange({ hour, minute, meridiem: "am" });
4812
- input.value = "am";
4813
- }
4814
- else if (key === "p") {
4815
- e.preventDefault();
4816
- setMeridiem("pm");
4817
- onChange({ hour, minute, meridiem: "pm" });
4818
- input.value = "pm";
4819
- }
4820
- }
4821
- };
4822
- // Handle input blur events to validate and format values
4823
- const handleBlur = (e, field) => {
4824
- const value = e.target.value;
4825
- if (field === "hour") {
4826
- if (value === "") {
4827
- if (hour !== null) {
4828
- setHour(null);
4829
- onChange({ hour: null, minute, meridiem });
4830
- }
4831
- return;
4832
- }
4833
- const numValue = parseInt(value, 10);
4834
- if (isNaN(numValue) || numValue < 1 || numValue > 12) {
4835
- setHour(null);
4836
- onChange({ hour: null, minute, meridiem });
4837
- }
4838
- else if (hour !== numValue) {
4839
- setHour(numValue);
4840
- onChange({ hour: numValue, minute, meridiem });
4841
- }
4842
- }
4843
- else if (field === "minute") {
4844
- if (value === "") {
4845
- if (minute !== null) {
4846
- setMinute(null);
4847
- onChange({ hour, minute: null, meridiem });
4848
- }
4849
- return;
4850
- }
4851
- const numValue = parseInt(value, 10);
4852
- if (isNaN(numValue) || numValue < 0 || numValue > 59) {
4853
- setMinute(null);
4854
- onChange({ hour, minute: null, meridiem });
4855
- }
4856
- else if (minute !== numValue) {
4857
- setMinute(numValue);
4858
- onChange({ hour, minute: numValue, meridiem });
4859
- }
4860
- }
4861
- else if (field === "meridiem") {
4862
- if (value === "") {
4863
- if (meridiem !== null) {
4864
- setMeridiem(null);
4865
- onChange({ hour, minute, meridiem: null });
4866
- }
4867
- return;
4868
- }
4869
- const lowerValue = value.toLowerCase();
4870
- if (lowerValue !== "am" && lowerValue !== "pm") {
4871
- if (lowerValue === "a") {
4872
- setMeridiem("am");
4873
- onChange({ hour, minute, meridiem: "am" });
4874
- }
4875
- else if (lowerValue === "p") {
4876
- setMeridiem("pm");
4877
- onChange({ hour, minute, meridiem: "pm" });
4878
- }
4879
- else {
4880
- setMeridiem(null);
4881
- onChange({ hour, minute, meridiem: null });
4882
4808
  }
4883
4809
  }
4884
- else if (meridiem !== lowerValue) {
4885
- setMeridiem(lowerValue);
4886
- onChange({ hour, minute, meridiem: lowerValue });
4887
- }
4888
4810
  }
4889
4811
  };
4890
4812
  // Handle meridiem button click
@@ -4900,26 +4822,25 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
4900
4822
  // Focus the hour field after clearing
4901
4823
  hourInputRef.current?.focus();
4902
4824
  };
4903
- function handleFocus(event) {
4904
- event.target.select();
4905
- }
4906
- return (jsxRuntime.jsx(react.Flex, { direction: "column", gap: 3, children: jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsxRuntime.jsx(react.Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), onBlur: (e) => handleBlur(e, "hour"), onFocus: handleFocus, placeholder: "HH", maxLength: 2, textAlign: "center" }), jsxRuntime.jsx(react.Text, { children: ":" }), jsxRuntime.jsx(react.Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), onBlur: (e) => handleBlur(e, "minute"), onFocus: handleFocus, placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxRuntime.jsxs(react.Flex, { gap: "1", children: [jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }) }));
4825
+ return (jsxRuntime.jsx(react.Flex, { direction: "column", gap: 3, children: jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsxRuntime.jsx(react.Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), placeholder: "HH", maxLength: 2, textAlign: "center" }), jsxRuntime.jsx(react.Text, { children: ":" }), jsxRuntime.jsx(react.Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxRuntime.jsxs(react.Flex, { gap: "1", children: [jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }) }));
4907
4826
  }
4908
4827
 
4909
4828
  const TimePicker = ({ column, schema, prefix }) => {
4910
4829
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
4911
4830
  const { translate } = useSchemaContext();
4912
- const { required, gridColumn = "span 4", gridRow = "span 1", format = "HH:mm:ss" } = schema;
4831
+ const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ss", displayTimeFormat = "hh:mm A", } = schema;
4913
4832
  const isRequired = required?.some((columnId) => columnId === column);
4914
4833
  const colLabel = `${prefix}${column}`;
4915
4834
  const [open, setOpen] = React.useState(false);
4916
4835
  const value = watch(colLabel);
4917
- const formatedTime = value ? dayjs(value).format("hh:mm A") : "";
4836
+ const displayedTime = dayjs(`1970-01-01T${value}Z`).isValid()
4837
+ ? dayjs(`1970-01-01T${value}Z`).utc().format(displayTimeFormat)
4838
+ : "";
4918
4839
  // Parse the initial time parts from the ISO time string (HH:mm:ss)
4919
4840
  const parseTime = (isoTime) => {
4920
4841
  if (!isoTime)
4921
4842
  return { hour: 12, minute: 0, meridiem: "am" };
4922
- const parsed = dayjs(isoTime);
4843
+ const parsed = dayjs(`1970-01-01T${isoTime}Z`).utc();
4923
4844
  if (!parsed.isValid())
4924
4845
  return { hour: 12, minute: 0, meridiem: "am" };
4925
4846
  let hour = parsed.hour();
@@ -4950,7 +4871,9 @@ const TimePicker = ({ column, schema, prefix }) => {
4950
4871
  h = 0;
4951
4872
  else if (meridiem === "pm" && hour < 12)
4952
4873
  h = hour + 12;
4953
- return dayjs().hour(h).minute(minute).second(0).format(format);
4874
+ return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00Z`)
4875
+ .utc()
4876
+ .format(timeFormat);
4954
4877
  };
4955
4878
  // Handle changes to time parts
4956
4879
  const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
@@ -4964,7 +4887,7 @@ const TimePicker = ({ column, schema, prefix }) => {
4964
4887
  return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4965
4888
  gridRow, children: [jsxRuntime.jsxs(react.Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(react.Popover.Trigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
4966
4889
  setOpen(true);
4967
- }, justifyContent: "start", children: [jsxRuntime.jsx(io.IoMdClock, {}), value !== undefined ? `${formatedTime}` : ""] }) }), jsxRuntime.jsx(react.Portal, { children: jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { ref: containerRef, children: jsxRuntime.jsx(react.Popover.Body, { children: jsxRuntime.jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
4890
+ }, justifyContent: "start", children: [jsxRuntime.jsx(io.IoMdClock, {}), !!value ? `${displayedTime}` : ""] }) }), jsxRuntime.jsx(react.Portal, { children: jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { ref: containerRef, children: jsxRuntime.jsx(react.Popover.Body, { children: jsxRuntime.jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
4968
4891
  am: translate.t(removeIndex(`common.am`)),
4969
4892
  pm: translate.t(removeIndex(`common.pm`)),
4970
4893
  } }) }) }) }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
@@ -5039,15 +4962,19 @@ const ColumnRenderer = ({ column, properties, prefix, }) => {
5039
4962
  };
5040
4963
 
5041
4964
  const ArrayViewer = ({ schema, column, prefix }) => {
5042
- const { gridColumn = "span 4", gridRow = "span 1", required, items } = schema;
4965
+ const { gridColumn = "span 12", gridRow = "span 1", required, items, } = schema;
5043
4966
  const { translate } = useSchemaContext();
5044
4967
  const colLabel = `${prefix}${column}`;
5045
4968
  const isRequired = required?.some((columnId) => columnId === column);
5046
4969
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5047
4970
  const values = watch(colLabel) ?? [];
5048
- return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] }), values.map((field, index) => (jsxRuntime.jsx(react.Flex, { flexFlow: "column", children: jsxRuntime.jsx(react.Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaViewer, { column: `${index}`,
5049
- prefix: `${colLabel}.`,
5050
- schema: items }) }) }, `form-${prefix}${column}.${index}`))), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4971
+ return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: values.map((field, index) => (jsxRuntime.jsx(react.Flex, { flexFlow: "column", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "2", borderRadius: "md", borderWidth: "thin", borderColor: {
4972
+ base: "colorPalette.200",
4973
+ _dark: "colorPalette.800",
4974
+ }, children: jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaViewer, { column: `${index}`,
4975
+ prefix: `${colLabel}.`,
4976
+ // @ts-expect-error find suitable types
4977
+ schema: { showTitle: false, ...(items ?? {}) } }) }) }, `form-${prefix}${column}.${index}`))) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5051
4978
  };
5052
4979
 
5053
4980
  const BooleanViewer = ({ schema, column, prefix, }) => {
@@ -5162,7 +5089,7 @@ const NumberViewer = ({ schema, column, prefix, }) => {
5162
5089
  };
5163
5090
 
5164
5091
  const ObjectViewer = ({ schema, column, prefix }) => {
5165
- const { properties, gridColumn = "span 12", gridRow = "span 1", required, } = schema;
5092
+ const { properties, gridColumn = "span 12", gridRow = "span 1", required, showTitle = true, } = schema;
5166
5093
  const { translate } = useSchemaContext();
5167
5094
  const colLabel = `${prefix}${column}`;
5168
5095
  const isRequired = required?.some((columnId) => columnId === column);
@@ -5170,8 +5097,10 @@ const ObjectViewer = ({ schema, column, prefix }) => {
5170
5097
  if (properties === undefined) {
5171
5098
  throw new Error(`properties is undefined when using ObjectInput`);
5172
5099
  }
5173
- return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] }), jsxRuntime.jsx(react.Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", gridColumn,
5174
- gridRow, children: Object.keys(properties ?? {}).map((key) => {
5100
+ return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [showTitle && (jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] })), jsxRuntime.jsx(react.Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "1", borderRadius: "md", borderWidth: "thin", borderColor: {
5101
+ base: "colorPalette.200",
5102
+ _dark: "colorPalette.800",
5103
+ }, children: Object.keys(properties ?? {}).map((key) => {
5175
5104
  return (
5176
5105
  // @ts-expect-error find suitable types
5177
5106
  jsxRuntime.jsx(ColumnViewer, { column: `${key}`,
@@ -5337,22 +5266,23 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
5337
5266
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsxRuntime.jsx(react.Text, { whiteSpace: "pre-wrap", children: value }), " ", errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
5338
5267
  };
5339
5268
 
5340
- const TimeViewer = ({ column, schema, prefix }) => {
5269
+ const TimeViewer = ({ column, schema, prefix, }) => {
5341
5270
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5342
5271
  const { translate } = useSchemaContext();
5343
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5272
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A" } = schema;
5344
5273
  const isRequired = required?.some((columnId) => columnId === column);
5345
5274
  const colLabel = `${prefix}${column}`;
5346
5275
  const selectedDate = watch(colLabel);
5276
+ const displayedTime = dayjs(`1970-01-01T${selectedDate}Z`).isValid()
5277
+ ? dayjs(`1970-01-01T${selectedDate}Z`).utc().format(displayTimeFormat)
5278
+ : "";
5347
5279
  return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5348
- gridRow, children: [jsxRuntime.jsx(react.Text, { children: selectedDate !== undefined
5349
- ? dayjs(selectedDate).format("hh:mm A")
5350
- : "" }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5280
+ gridRow, children: [jsxRuntime.jsx(react.Text, { children: displayedTime }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5351
5281
  };
5352
5282
 
5353
5283
  const SchemaViewer = ({ schema, prefix, column, }) => {
5354
5284
  const colSchema = schema;
5355
- const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
5285
+ const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
5356
5286
  if (variant === "custom-input") {
5357
5287
  return jsxRuntime.jsx(CustomViewer, { schema: colSchema, prefix, column });
5358
5288
  }
@@ -5364,12 +5294,12 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
5364
5294
  idPickerSanityCheck(column, foreign_key);
5365
5295
  return jsxRuntime.jsx(IdViewer, { schema: colSchema, prefix, column });
5366
5296
  }
5367
- if (variant === "date-picker") {
5368
- return jsxRuntime.jsx(DateViewer, { schema: colSchema, prefix, column });
5369
- }
5370
- if (variant === "time-picker") {
5297
+ if (format === "time") {
5371
5298
  return jsxRuntime.jsx(TimeViewer, { schema: colSchema, prefix, column });
5372
5299
  }
5300
+ if (format === "date") {
5301
+ return jsxRuntime.jsx(DateViewer, { schema: colSchema, prefix, column });
5302
+ }
5373
5303
  if (variant === "text-area") {
5374
5304
  return jsxRuntime.jsx(TextAreaViewer, { schema: colSchema, prefix, column });
5375
5305
  }
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ import { LuX, LuCheck, LuChevronRight, LuChevronDown } from 'react-icons/lu';
7
7
  import { MdOutlineSort, MdFilterAlt, MdSearch, MdClose, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdClear, MdOutlineChecklist, MdDateRange } from 'react-icons/md';
8
8
  import { FaUpDown, FaGripLinesVertical } from 'react-icons/fa6';
9
9
  import { BiDownArrow, BiUpArrow, BiError } from 'react-icons/bi';
10
- import { CgClose } from 'react-icons/cg';
10
+ import { CgClose, CgTrash } from 'react-icons/cg';
11
11
  import Dayzed from '@bsol-oss/dayzed-react19';
12
12
  import { HiMiniEllipsisHorizontal, HiChevronLeft, HiChevronRight } from 'react-icons/hi2';
13
13
  import { IoMdEye, IoMdCheckbox, IoMdClock } from 'react-icons/io';
@@ -3631,13 +3631,17 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
3631
3631
  const isRequired = required?.some((columnId) => columnId === column);
3632
3632
  const { formState: { errors }, setValue, watch, } = useFormContext();
3633
3633
  const fields = (watch(colLabel) ?? []);
3634
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), fields.map((field, index) => (jsxs(Flex, { flexFlow: "column", children: [jsx(Box, { children: index + 1 }), jsx(Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaRenderer, { column: `${index}`,
3635
- prefix: `${colLabel}.`,
3636
- schema: items }) }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { variant: "ghost", onClick: () => {
3637
- setValue(colLabel, fields.filter((_, curIndex) => {
3638
- return curIndex !== index;
3639
- }));
3640
- }, children: translate.t(removeIndex(`${colLabel}.remove`)) }) })] }, `${colLabel}.${index}`))), jsx(Flex, { children: jsx(Button$1, { onClick: () => {
3634
+ return (jsxs(Flex, { gridRow, gridColumn, flexFlow: "column", gap: 2, children: [jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: "column", gap: 2, children: fields.map((field, index) => (jsxs(Flex, { flexFlow: "row", gap: 2, bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
3635
+ base: "colorPalette.200",
3636
+ _dark: "colorPalette.800",
3637
+ }, children: [jsx(Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaRenderer, { column: `${index}`,
3638
+ prefix: `${colLabel}.`,
3639
+ // @ts-expect-error find suitable types
3640
+ schema: { showTitle: false, ...(items ?? {}) } }) }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { variant: "ghost", onClick: () => {
3641
+ setValue(colLabel, fields.filter((_, curIndex) => {
3642
+ return curIndex !== index;
3643
+ }));
3644
+ }, children: jsx(Icon, { children: jsx(CgTrash, {}) }) }) })] }, `${colLabel}.${index}`))) }), jsx(Flex, { children: jsx(Button$1, { onClick: () => {
3641
3645
  if (type === "number") {
3642
3646
  setValue(colLabel, [...fields, 0]);
3643
3647
  return;
@@ -4476,7 +4480,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4476
4480
  borderRadius: "4px",
4477
4481
  border: "1px solid #ccc",
4478
4482
  fontSize: "14px",
4479
- }, children: [jsx("option", { value: "5", children: "5" }), jsx("option", { value: "10", children: "10" }), jsx("option", { value: "20", children: "20" }), jsx("option", { value: "50", children: "50" })] }) })] }), jsx(Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: dataList.length > 0 ? (jsx(Flex, { flexFlow: "column wrap", children: dataList.map((item) => {
4483
+ }, children: [jsx("option", { value: "5", children: "5" }), jsx("option", { value: "10", children: "10" }), jsx("option", { value: "20", children: "20" }), jsx("option", { value: "30", children: "30" })] }) })] }), jsx(Grid, { overflowY: "auto", children: dataList.length > 0 ? (jsx(Flex, { flexFlow: "column wrap", gap: 1, children: dataList.map((item) => {
4480
4484
  const selected = isMultiple
4481
4485
  ? watchIds.some((id) => item[column_ref] === id)
4482
4486
  : watchId === item[column_ref];
@@ -4525,7 +4529,7 @@ const NumberInputField = ({ schema, column, prefix, }) => {
4525
4529
  };
4526
4530
 
4527
4531
  const ObjectInput = ({ schema, column, prefix }) => {
4528
- const { properties, gridColumn = "span 12", gridRow = "span 1", required, } = schema;
4532
+ const { properties, gridColumn = "span 12", gridRow = "span 1", required, showTitle = true, } = schema;
4529
4533
  const { translate } = useSchemaContext();
4530
4534
  const colLabel = `${prefix}${column}`;
4531
4535
  const isRequired = required?.some((columnId) => columnId === column);
@@ -4533,7 +4537,10 @@ const ObjectInput = ({ schema, column, prefix }) => {
4533
4537
  if (properties === undefined) {
4534
4538
  throw new Error(`properties is undefined when using ObjectInput`);
4535
4539
  }
4536
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
4540
+ return (jsxs(Box, { gridRow, gridColumn, children: [showTitle && (jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
4541
+ base: "colorPalette.200",
4542
+ _dark: "colorPalette.800",
4543
+ }, gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
4537
4544
  return (
4538
4545
  // @ts-expect-error find suitable types
4539
4546
  jsx(ColumnRenderer, { column: `${key}`,
@@ -4714,7 +4721,7 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
4714
4721
  // Refs for focus management
4715
4722
  const hourInputRef = useRef(null);
4716
4723
  const minuteInputRef = useRef(null);
4717
- const meridiemInputRef = useRef(null);
4724
+ useRef(null);
4718
4725
  // Centralized handler for key events, value changes, and focus management
4719
4726
  const handleKeyDown = (e, field) => {
4720
4727
  const input = e.target;
@@ -4766,9 +4773,10 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
4766
4773
  if (e.key.match(/^[0-9]$/)) {
4767
4774
  const newValue = value + e.key;
4768
4775
  const numValue = parseInt(newValue, 10);
4776
+ console.log("newValue minute", newValue, numValue, numValue > 60, numValue >= 0 && numValue <= 59, e.key);
4769
4777
  if (numValue > 60) {
4770
4778
  const digitValue = parseInt(e.key, 10);
4771
- setHour(digitValue);
4779
+ setMinute(digitValue);
4772
4780
  onChange({ hour, minute: digitValue, meridiem });
4773
4781
  return;
4774
4782
  }
@@ -4777,94 +4785,8 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
4777
4785
  // Set the minute value
4778
4786
  setMinute(numValue);
4779
4787
  onChange({ hour, minute: numValue, meridiem });
4780
- // Move to meridiem input
4781
- e.preventDefault();
4782
- meridiemInputRef.current?.focus();
4783
- }
4784
- }
4785
- }
4786
- else if (field === "meridiem") {
4787
- const key = e.key.toLowerCase();
4788
- if (key === "a") {
4789
- e.preventDefault();
4790
- setMeridiem("am");
4791
- onChange({ hour, minute, meridiem: "am" });
4792
- input.value = "am";
4793
- }
4794
- else if (key === "p") {
4795
- e.preventDefault();
4796
- setMeridiem("pm");
4797
- onChange({ hour, minute, meridiem: "pm" });
4798
- input.value = "pm";
4799
- }
4800
- }
4801
- };
4802
- // Handle input blur events to validate and format values
4803
- const handleBlur = (e, field) => {
4804
- const value = e.target.value;
4805
- if (field === "hour") {
4806
- if (value === "") {
4807
- if (hour !== null) {
4808
- setHour(null);
4809
- onChange({ hour: null, minute, meridiem });
4810
- }
4811
- return;
4812
- }
4813
- const numValue = parseInt(value, 10);
4814
- if (isNaN(numValue) || numValue < 1 || numValue > 12) {
4815
- setHour(null);
4816
- onChange({ hour: null, minute, meridiem });
4817
- }
4818
- else if (hour !== numValue) {
4819
- setHour(numValue);
4820
- onChange({ hour: numValue, minute, meridiem });
4821
- }
4822
- }
4823
- else if (field === "minute") {
4824
- if (value === "") {
4825
- if (minute !== null) {
4826
- setMinute(null);
4827
- onChange({ hour, minute: null, meridiem });
4828
- }
4829
- return;
4830
- }
4831
- const numValue = parseInt(value, 10);
4832
- if (isNaN(numValue) || numValue < 0 || numValue > 59) {
4833
- setMinute(null);
4834
- onChange({ hour, minute: null, meridiem });
4835
- }
4836
- else if (minute !== numValue) {
4837
- setMinute(numValue);
4838
- onChange({ hour, minute: numValue, meridiem });
4839
- }
4840
- }
4841
- else if (field === "meridiem") {
4842
- if (value === "") {
4843
- if (meridiem !== null) {
4844
- setMeridiem(null);
4845
- onChange({ hour, minute, meridiem: null });
4846
- }
4847
- return;
4848
- }
4849
- const lowerValue = value.toLowerCase();
4850
- if (lowerValue !== "am" && lowerValue !== "pm") {
4851
- if (lowerValue === "a") {
4852
- setMeridiem("am");
4853
- onChange({ hour, minute, meridiem: "am" });
4854
- }
4855
- else if (lowerValue === "p") {
4856
- setMeridiem("pm");
4857
- onChange({ hour, minute, meridiem: "pm" });
4858
- }
4859
- else {
4860
- setMeridiem(null);
4861
- onChange({ hour, minute, meridiem: null });
4862
4788
  }
4863
4789
  }
4864
- else if (meridiem !== lowerValue) {
4865
- setMeridiem(lowerValue);
4866
- onChange({ hour, minute, meridiem: lowerValue });
4867
- }
4868
4790
  }
4869
4791
  };
4870
4792
  // Handle meridiem button click
@@ -4880,26 +4802,25 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
4880
4802
  // Focus the hour field after clearing
4881
4803
  hourInputRef.current?.focus();
4882
4804
  };
4883
- function handleFocus(event) {
4884
- event.target.select();
4885
- }
4886
- return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), onBlur: (e) => handleBlur(e, "hour"), onFocus: handleFocus, placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), onBlur: (e) => handleBlur(e, "minute"), onFocus: handleFocus, placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxs(Flex, { gap: "1", children: [jsx(Button$1, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsx(Button$1, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
4805
+ return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxs(Flex, { gap: "1", children: [jsx(Button$1, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsx(Button$1, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
4887
4806
  }
4888
4807
 
4889
4808
  const TimePicker = ({ column, schema, prefix }) => {
4890
4809
  const { watch, formState: { errors }, setValue, } = useFormContext();
4891
4810
  const { translate } = useSchemaContext();
4892
- const { required, gridColumn = "span 4", gridRow = "span 1", format = "HH:mm:ss" } = schema;
4811
+ const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ss", displayTimeFormat = "hh:mm A", } = schema;
4893
4812
  const isRequired = required?.some((columnId) => columnId === column);
4894
4813
  const colLabel = `${prefix}${column}`;
4895
4814
  const [open, setOpen] = useState(false);
4896
4815
  const value = watch(colLabel);
4897
- const formatedTime = value ? dayjs(value).format("hh:mm A") : "";
4816
+ const displayedTime = dayjs(`1970-01-01T${value}Z`).isValid()
4817
+ ? dayjs(`1970-01-01T${value}Z`).utc().format(displayTimeFormat)
4818
+ : "";
4898
4819
  // Parse the initial time parts from the ISO time string (HH:mm:ss)
4899
4820
  const parseTime = (isoTime) => {
4900
4821
  if (!isoTime)
4901
4822
  return { hour: 12, minute: 0, meridiem: "am" };
4902
- const parsed = dayjs(isoTime);
4823
+ const parsed = dayjs(`1970-01-01T${isoTime}Z`).utc();
4903
4824
  if (!parsed.isValid())
4904
4825
  return { hour: 12, minute: 0, meridiem: "am" };
4905
4826
  let hour = parsed.hour();
@@ -4930,7 +4851,9 @@ const TimePicker = ({ column, schema, prefix }) => {
4930
4851
  h = 0;
4931
4852
  else if (meridiem === "pm" && hour < 12)
4932
4853
  h = hour + 12;
4933
- return dayjs().hour(h).minute(minute).second(0).format(format);
4854
+ return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00Z`)
4855
+ .utc()
4856
+ .format(timeFormat);
4934
4857
  };
4935
4858
  // Handle changes to time parts
4936
4859
  const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
@@ -4944,7 +4867,7 @@ const TimePicker = ({ column, schema, prefix }) => {
4944
4867
  return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4945
4868
  gridRow, children: [jsxs(Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(Popover.Trigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
4946
4869
  setOpen(true);
4947
- }, justifyContent: "start", children: [jsx(IoMdClock, {}), value !== undefined ? `${formatedTime}` : ""] }) }), jsx(Portal, { children: jsx(Popover.Positioner, { children: jsx(Popover.Content, { ref: containerRef, children: jsx(Popover.Body, { children: jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
4870
+ }, justifyContent: "start", children: [jsx(IoMdClock, {}), !!value ? `${displayedTime}` : ""] }) }), jsx(Portal, { children: jsx(Popover.Positioner, { children: jsx(Popover.Content, { ref: containerRef, children: jsx(Popover.Body, { children: jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
4948
4871
  am: translate.t(removeIndex(`common.am`)),
4949
4872
  pm: translate.t(removeIndex(`common.pm`)),
4950
4873
  } }) }) }) }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
@@ -5019,15 +4942,19 @@ const ColumnRenderer = ({ column, properties, prefix, }) => {
5019
4942
  };
5020
4943
 
5021
4944
  const ArrayViewer = ({ schema, column, prefix }) => {
5022
- const { gridColumn = "span 4", gridRow = "span 1", required, items } = schema;
4945
+ const { gridColumn = "span 12", gridRow = "span 1", required, items, } = schema;
5023
4946
  const { translate } = useSchemaContext();
5024
4947
  const colLabel = `${prefix}${column}`;
5025
4948
  const isRequired = required?.some((columnId) => columnId === column);
5026
4949
  const { watch, formState: { errors }, } = useFormContext();
5027
4950
  const values = watch(colLabel) ?? [];
5028
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), values.map((field, index) => (jsx(Flex, { flexFlow: "column", children: jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaViewer, { column: `${index}`,
5029
- prefix: `${colLabel}.`,
5030
- schema: items }) }) }, `form-${prefix}${column}.${index}`))), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4951
+ return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: "column", gap: 1, children: values.map((field, index) => (jsx(Flex, { flexFlow: "column", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "2", borderRadius: "md", borderWidth: "thin", borderColor: {
4952
+ base: "colorPalette.200",
4953
+ _dark: "colorPalette.800",
4954
+ }, children: jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaViewer, { column: `${index}`,
4955
+ prefix: `${colLabel}.`,
4956
+ // @ts-expect-error find suitable types
4957
+ schema: { showTitle: false, ...(items ?? {}) } }) }) }, `form-${prefix}${column}.${index}`))) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5031
4958
  };
5032
4959
 
5033
4960
  const BooleanViewer = ({ schema, column, prefix, }) => {
@@ -5142,7 +5069,7 @@ const NumberViewer = ({ schema, column, prefix, }) => {
5142
5069
  };
5143
5070
 
5144
5071
  const ObjectViewer = ({ schema, column, prefix }) => {
5145
- const { properties, gridColumn = "span 12", gridRow = "span 1", required, } = schema;
5072
+ const { properties, gridColumn = "span 12", gridRow = "span 1", required, showTitle = true, } = schema;
5146
5073
  const { translate } = useSchemaContext();
5147
5074
  const colLabel = `${prefix}${column}`;
5148
5075
  const isRequired = required?.some((columnId) => columnId === column);
@@ -5150,8 +5077,10 @@ const ObjectViewer = ({ schema, column, prefix }) => {
5150
5077
  if (properties === undefined) {
5151
5078
  throw new Error(`properties is undefined when using ObjectInput`);
5152
5079
  }
5153
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", gridColumn,
5154
- gridRow, children: Object.keys(properties ?? {}).map((key) => {
5080
+ return (jsxs(Box, { gridRow, gridColumn, children: [showTitle && (jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "1", borderRadius: "md", borderWidth: "thin", borderColor: {
5081
+ base: "colorPalette.200",
5082
+ _dark: "colorPalette.800",
5083
+ }, children: Object.keys(properties ?? {}).map((key) => {
5155
5084
  return (
5156
5085
  // @ts-expect-error find suitable types
5157
5086
  jsx(ColumnViewer, { column: `${key}`,
@@ -5317,22 +5246,23 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
5317
5246
  return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Text, { whiteSpace: "pre-wrap", children: value }), " ", errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
5318
5247
  };
5319
5248
 
5320
- const TimeViewer = ({ column, schema, prefix }) => {
5249
+ const TimeViewer = ({ column, schema, prefix, }) => {
5321
5250
  const { watch, formState: { errors }, } = useFormContext();
5322
5251
  const { translate } = useSchemaContext();
5323
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5252
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A" } = schema;
5324
5253
  const isRequired = required?.some((columnId) => columnId === column);
5325
5254
  const colLabel = `${prefix}${column}`;
5326
5255
  const selectedDate = watch(colLabel);
5256
+ const displayedTime = dayjs(`1970-01-01T${selectedDate}Z`).isValid()
5257
+ ? dayjs(`1970-01-01T${selectedDate}Z`).utc().format(displayTimeFormat)
5258
+ : "";
5327
5259
  return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5328
- gridRow, children: [jsx(Text, { children: selectedDate !== undefined
5329
- ? dayjs(selectedDate).format("hh:mm A")
5330
- : "" }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5260
+ gridRow, children: [jsx(Text, { children: displayedTime }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5331
5261
  };
5332
5262
 
5333
5263
  const SchemaViewer = ({ schema, prefix, column, }) => {
5334
5264
  const colSchema = schema;
5335
- const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
5265
+ const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
5336
5266
  if (variant === "custom-input") {
5337
5267
  return jsx(CustomViewer, { schema: colSchema, prefix, column });
5338
5268
  }
@@ -5344,12 +5274,12 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
5344
5274
  idPickerSanityCheck(column, foreign_key);
5345
5275
  return jsx(IdViewer, { schema: colSchema, prefix, column });
5346
5276
  }
5347
- if (variant === "date-picker") {
5348
- return jsx(DateViewer, { schema: colSchema, prefix, column });
5349
- }
5350
- if (variant === "time-picker") {
5277
+ if (format === "time") {
5351
5278
  return jsx(TimeViewer, { schema: colSchema, prefix, column });
5352
5279
  }
5280
+ if (format === "date") {
5281
+ return jsx(DateViewer, { schema: colSchema, prefix, column });
5282
+ }
5353
5283
  if (variant === "text-area") {
5354
5284
  return jsx(TextAreaViewer, { schema: colSchema, prefix, column });
5355
5285
  }
@@ -22,7 +22,9 @@ export interface CustomJSONSchema7 extends JSONSchema7 {
22
22
  }) => ReactNode;
23
23
  dateFormat?: string;
24
24
  displayDateFormat?: string;
25
- format?: string;
25
+ timeFormat?: string;
26
+ displayTimeFormat?: string;
27
+ showTitle?: boolean;
26
28
  }
27
29
  export interface TagPickerProps {
28
30
  column: string;
@@ -4,4 +4,4 @@ export interface TimeViewerProps {
4
4
  schema: CustomJSONSchema7;
5
5
  prefix: string;
6
6
  }
7
- export declare const TimeViewer: ({ column, schema, prefix }: TimeViewerProps) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const TimeViewer: ({ column, schema, prefix, }: TimeViewerProps) => import("react/jsx-runtime").JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsol-oss/react-datatable5",
3
- "version": "12.0.0-beta.41",
3
+ "version": "12.0.0-beta.43",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",