@bsol-oss/react-datatable5 12.0.0-beta.57 → 12.0.0-beta.59

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.mjs CHANGED
@@ -5,7 +5,7 @@ import * as React from 'react';
5
5
  import React__default, { createContext, useContext, useState, useEffect, useRef } from 'react';
6
6
  import { LuX, LuCheck, LuChevronRight, LuChevronDown } from 'react-icons/lu';
7
7
  import { MdOutlineSort, MdFilterAlt, MdSearch, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdClear, MdOutlineChecklist, MdDateRange } from 'react-icons/md';
8
- import { FaUpDown, FaGripLinesVertical } from 'react-icons/fa6';
8
+ import { FaUpDown, FaGripLinesVertical, FaTrash } from 'react-icons/fa6';
9
9
  import { BiDownArrow, BiUpArrow, BiError } from 'react-icons/bi';
10
10
  import { CgClose, CgTrash } from 'react-icons/cg';
11
11
  import Dayzed from '@bsol-oss/dayzed-react19';
@@ -34,6 +34,7 @@ import zh_TW from 'ajv-i18n/localize/zh-TW';
34
34
  import zh_CN from 'ajv-i18n/localize/zh';
35
35
  import dayjs from 'dayjs';
36
36
  import utc from 'dayjs/plugin/utc';
37
+ import timezone from 'dayjs/plugin/timezone';
37
38
  import { TiDeleteOutline } from 'react-icons/ti';
38
39
 
39
40
  const DataTableContext = createContext({
@@ -181,7 +182,7 @@ const monthNamesFull = [
181
182
  "November",
182
183
  "December",
183
184
  ];
184
- const weekdayNamesShort$1 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
185
+ const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
185
186
  function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, selected = [], firstDayOfWeek = 0, }) {
186
187
  const [hoveredDate, setHoveredDate] = useState();
187
188
  const onMouseLeave = () => {
@@ -216,7 +217,7 @@ function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, se
216
217
  offset: 12,
217
218
  }), children: ">>" })] }), jsx(Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", gap: 4, children: calendars.map((calendar) => (jsxs(Grid, { gap: 4, children: [jsxs(Grid, { justifyContent: "center", children: [monthNamesFull[calendar.month], " ", calendar.year] }), jsx(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
218
219
  const weekday = (weekdayNum + firstDayOfWeek) % 7;
219
- return (jsx(Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort$1[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
220
+ return (jsx(Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
220
221
  }) }), jsx(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: calendar.weeks.map((week, windex) => week.map((dateObj, index) => {
221
222
  const key = `${calendar.month}${calendar.year}${windex}${index}`;
222
223
  if (!dateObj) {
@@ -3673,6 +3674,7 @@ const SchemaFormContext = createContext({
3673
3674
  rowNumber: 0,
3674
3675
  requestOptions: {},
3675
3676
  validationLocale: 'en',
3677
+ timezone: 'Asia/Hong_Kong',
3676
3678
  });
3677
3679
 
3678
3680
  const useSchemaContext = () => {
@@ -3979,27 +3981,14 @@ const CustomInput = ({ column, schema, prefix }) => {
3979
3981
  }));
3980
3982
  };
3981
3983
 
3982
- const monthNamesShort = [
3983
- "Jan",
3984
- "Feb",
3985
- "Mar",
3986
- "Apr",
3987
- "May",
3988
- "Jun",
3989
- "Jul",
3990
- "Aug",
3991
- "Sep",
3992
- "Oct",
3993
- "Nov",
3994
- "Dec",
3995
- ];
3996
- const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
3997
3984
  const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firstDayOfWeek = 0, }) => {
3985
+ const { labels } = useContext(DatePickerContext);
3986
+ const { monthNamesShort, weekdayNamesShort, backButtonLabel, forwardButtonLabel } = labels;
3998
3987
  if (calendars.length) {
3999
3988
  return (jsxs(Grid, { children: [jsxs(Grid, { templateColumns: "repeat(4, auto)", justifyContent: "center", children: [jsx(Button$1, { variant: "ghost", ...getBackProps({
4000
3989
  calendars,
4001
3990
  offset: 12,
4002
- }), children: "<<" }), jsx(Button$1, { variant: "ghost", ...getBackProps({ calendars }), children: "Back" }), jsx(Button$1, { variant: "ghost", ...getForwardProps({ calendars }), children: "Next" }), jsx(Button$1, { variant: "ghost", ...getForwardProps({
3991
+ }), children: "<<" }), jsx(Button$1, { variant: "ghost", ...getBackProps({ calendars }), children: backButtonLabel }), jsx(Button$1, { variant: "ghost", ...getForwardProps({ calendars }), children: forwardButtonLabel }), jsx(Button$1, { variant: "ghost", ...getForwardProps({
4003
3992
  calendars,
4004
3993
  offset: 12,
4005
3994
  }), children: ">>" })] }), jsx(Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", children: calendars.map((calendar) => (jsxs(Grid, { gap: 4, children: [jsxs(Grid, { justifyContent: "center", children: [monthNamesShort[calendar.month], " ", calendar.year] }), jsxs(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [[0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
@@ -4042,9 +4031,52 @@ const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firs
4042
4031
  }
4043
4032
  return null;
4044
4033
  };
4034
+ const DatePickerContext = createContext({
4035
+ labels: {
4036
+ monthNamesShort: [
4037
+ "Jan",
4038
+ "Feb",
4039
+ "Mar",
4040
+ "Apr",
4041
+ "May",
4042
+ "Jun",
4043
+ "Jul",
4044
+ "Aug",
4045
+ "Sep",
4046
+ "Oct",
4047
+ "Nov",
4048
+ "Dec",
4049
+ ],
4050
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
4051
+ backButtonLabel: "Back",
4052
+ forwardButtonLabel: "Next",
4053
+ },
4054
+ });
4045
4055
  let DatePicker$1 = class DatePicker extends React__default.Component {
4046
4056
  render() {
4047
- return (jsx(Dayzed, { onDateSelected: this.props.onDateSelected, selected: this.props.selected, firstDayOfWeek: this.props.firstDayOfWeek, showOutsideDays: this.props.showOutsideDays, date: this.props.date, minDate: this.props.minDate, maxDate: this.props.maxDate, monthsToDisplay: this.props.monthsToDisplay, render: (dayzedData) => (jsx(Calendar, { ...dayzedData, firstDayOfWeek: this.props.firstDayOfWeek })) }));
4057
+ const { labels = {
4058
+ monthNamesShort: [
4059
+ "Jan",
4060
+ "Feb",
4061
+ "Mar",
4062
+ "Apr",
4063
+ "May",
4064
+ "Jun",
4065
+ "Jul",
4066
+ "Aug",
4067
+ "Sep",
4068
+ "Oct",
4069
+ "Nov",
4070
+ "Dec",
4071
+ ],
4072
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
4073
+ backButtonLabel: "Back",
4074
+ forwardButtonLabel: "Next",
4075
+ }, } = this.props;
4076
+ return (jsx(DatePickerContext.Provider, { value: { labels }, children: jsx(Dayzed, { onDateSelected: this.props.onDateSelected, selected: this.props.selected, firstDayOfWeek: this.props.firstDayOfWeek, showOutsideDays: this.props.showOutsideDays, date: this.props.date, minDate: this.props.minDate, maxDate: this.props.maxDate, monthsToDisplay: this.props.monthsToDisplay, render:
4077
+ // @ts-expect-error - Dayzed types need to be fixed
4078
+ (dayzedData) => (jsx(Calendar, { ...dayzedData,
4079
+ firstDayOfWeek: this.props.firstDayOfWeek })) }) }));
4048
4080
  }
4049
4081
  };
4050
4082
 
@@ -4066,24 +4098,27 @@ const PopoverRoot = Popover.Root;
4066
4098
  const PopoverBody = Popover.Body;
4067
4099
  const PopoverTrigger = Popover.Trigger;
4068
4100
 
4101
+ function translateWrapper({ prefix, column, label, translate, }) {
4102
+ return translate.t(removeIndex(`${prefix}${column}.${label}`));
4103
+ }
4104
+
4069
4105
  dayjs.extend(utc);
4106
+ dayjs.extend(timezone);
4070
4107
  const DatePicker = ({ column, schema, prefix }) => {
4071
4108
  const { watch, formState: { errors }, setValue, } = useFormContext();
4072
- const { translate } = useSchemaContext();
4073
- const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD[T]HH:mm:ss[Z]", } = schema;
4109
+ const { translate, timezone } = useSchemaContext();
4110
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
4074
4111
  const isRequired = required?.some((columnId) => columnId === column);
4075
4112
  const colLabel = `${prefix}${column}`;
4076
4113
  const [open, setOpen] = useState(false);
4077
4114
  const selectedDate = watch(colLabel);
4078
- const displayDate = dayjs.utc(selectedDate).format(displayDateFormat);
4115
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
4079
4116
  useEffect(() => {
4080
4117
  try {
4081
4118
  if (selectedDate) {
4082
4119
  // Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
4083
4120
  // For example, parse as UTC:
4084
- const parsedDate = dayjs.utc(selectedDate);
4085
- // Or if you want to parse in local timezone without shifting:
4086
- // const parsedDate = dayjs.tz(selectedDate, dayjs.tz.guess());
4121
+ const parsedDate = dayjs(selectedDate).tz(timezone);
4087
4122
  if (!parsedDate.isValid())
4088
4123
  return;
4089
4124
  // Format according to dateFormat from schema
@@ -4101,19 +4136,48 @@ const DatePicker = ({ column, schema, prefix }) => {
4101
4136
  console.error(e);
4102
4137
  }
4103
4138
  }, [selectedDate, dateFormat, colLabel, setValue]);
4104
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4139
+ const customTranslate = (label) => {
4140
+ return translateWrapper({ prefix, column, label, translate });
4141
+ };
4142
+ return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
4105
4143
  gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
4106
4144
  setOpen(true);
4107
- }, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DatePicker$1
4108
- // @ts-expect-error TODO: find appropriate types
4109
- , {
4110
- // @ts-expect-error TODO: find appropriate types
4111
- selected: new Date(selectedDate),
4112
- // @ts-expect-error TODO: find appropriate types
4113
- onDateSelected: ({ date }) => {
4145
+ }, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
4114
4146
  setValue(colLabel, dayjs(date).format(dateFormat));
4115
4147
  setOpen(false);
4116
- } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4148
+ }, labels: {
4149
+ monthNamesShort: [
4150
+ translate.t(`common.month_1`, { defaultValue: "January" }),
4151
+ translate.t(`common.month_2`, { defaultValue: "February" }),
4152
+ translate.t(`common.month_3`, { defaultValue: "March" }),
4153
+ translate.t(`common.month_4`, { defaultValue: "April" }),
4154
+ translate.t(`common.month_5`, { defaultValue: "May" }),
4155
+ translate.t(`common.month_6`, { defaultValue: "June" }),
4156
+ translate.t(`common.month_7`, { defaultValue: "July" }),
4157
+ translate.t(`common.month_8`, { defaultValue: "August" }),
4158
+ translate.t(`common.month_9`, { defaultValue: "September" }),
4159
+ translate.t(`common.month_10`, { defaultValue: "October" }),
4160
+ translate.t(`common.month_11`, { defaultValue: "November" }),
4161
+ translate.t(`common.month_12`, { defaultValue: "December" }),
4162
+ ],
4163
+ weekdayNamesShort: [
4164
+ translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4165
+ translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4166
+ translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4167
+ translate.t(`common.weekday_4`, {
4168
+ defaultValue: "Wed",
4169
+ }),
4170
+ translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4171
+ translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4172
+ translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4173
+ ],
4174
+ backButtonLabel: translate.t(`common.back_button`, {
4175
+ defaultValue: "Back",
4176
+ }),
4177
+ forwardButtonLabel: translate.t(`common.forward_button`, {
4178
+ defaultValue: "Forward",
4179
+ }),
4180
+ } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
4117
4181
  };
4118
4182
 
4119
4183
  function filterArray(array, searchTerm) {
@@ -5096,22 +5160,23 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
5096
5160
  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, {}) })] }) }));
5097
5161
  }
5098
5162
 
5163
+ dayjs.extend(timezone);
5099
5164
  const TimePicker = ({ column, schema, prefix }) => {
5100
5165
  const { watch, formState: { errors }, setValue, } = useFormContext();
5101
- const { translate } = useSchemaContext();
5102
- const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ss", displayTimeFormat = "hh:mm A", } = schema;
5166
+ const { translate, timezone } = useSchemaContext();
5167
+ const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5103
5168
  const isRequired = required?.some((columnId) => columnId === column);
5104
5169
  const colLabel = `${prefix}${column}`;
5105
5170
  const [open, setOpen] = useState(false);
5106
5171
  const value = watch(colLabel);
5107
- const displayedTime = dayjs(`1970-01-01T${value}Z`).isValid()
5108
- ? dayjs(`1970-01-01T${value}Z`).utc().format(displayTimeFormat)
5172
+ const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
5173
+ ? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
5109
5174
  : "";
5110
5175
  // Parse the initial time parts from the ISO time string (HH:mm:ss)
5111
5176
  const parseTime = (isoTime) => {
5112
5177
  if (!isoTime)
5113
5178
  return { hour: 12, minute: 0, meridiem: "am" };
5114
- const parsed = dayjs(`1970-01-01T${isoTime}Z`).utc();
5179
+ const parsed = dayjs(`1970-01-01T${isoTime}`).tz(timezone);
5115
5180
  if (!parsed.isValid())
5116
5181
  return { hour: 12, minute: 0, meridiem: "am" };
5117
5182
  let hour = parsed.hour();
@@ -5142,8 +5207,8 @@ const TimePicker = ({ column, schema, prefix }) => {
5142
5207
  h = 0;
5143
5208
  else if (meridiem === "pm" && hour < 12)
5144
5209
  h = hour + 12;
5145
- return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00Z`)
5146
- .utc()
5210
+ return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00`)
5211
+ .tz(timezone)
5147
5212
  .format(timeFormat);
5148
5213
  };
5149
5214
  // Handle changes to time parts
@@ -5159,11 +5224,289 @@ const TimePicker = ({ column, schema, prefix }) => {
5159
5224
  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: () => {
5160
5225
  setOpen(true);
5161
5226
  }, 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: {
5162
- am: translate.t(removeIndex(`common.am`)),
5163
- pm: translate.t(removeIndex(`common.pm`)),
5227
+ am: translate.t(`common.am`, { defaultValue: "AM" }),
5228
+ pm: translate.t(`common.pm`, { defaultValue: "PM" }),
5164
5229
  } }) }) }) }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5165
5230
  };
5166
5231
 
5232
+ function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
5233
+ // Refs for focus management
5234
+ const hourInputRef = useRef(null);
5235
+ const minuteInputRef = useRef(null);
5236
+ const secondInputRef = useRef(null);
5237
+ // Centralized handler for key events, value changes, and focus management
5238
+ const handleKeyDown = (e, field) => {
5239
+ const input = e.target;
5240
+ const value = input.value;
5241
+ // Handle navigation between fields
5242
+ if (e.key === "Tab") {
5243
+ return;
5244
+ }
5245
+ if (e.key === ":" && field === "hour") {
5246
+ e.preventDefault();
5247
+ minuteInputRef.current?.focus();
5248
+ return;
5249
+ }
5250
+ if (e.key === ":" && field === "minute") {
5251
+ e.preventDefault();
5252
+ secondInputRef.current?.focus();
5253
+ return;
5254
+ }
5255
+ if (e.key === "Backspace" && value === "") {
5256
+ e.preventDefault();
5257
+ if (field === "minute") {
5258
+ hourInputRef.current?.focus();
5259
+ }
5260
+ else if (field === "second") {
5261
+ minuteInputRef.current?.focus();
5262
+ }
5263
+ return;
5264
+ }
5265
+ // Handle number inputs
5266
+ if (field === "hour") {
5267
+ if (e.key.match(/^[0-9]$/)) {
5268
+ const newValue = value + e.key;
5269
+ const numValue = parseInt(newValue, 10);
5270
+ if (numValue > 23) {
5271
+ const digitValue = parseInt(e.key, 10);
5272
+ setHour(digitValue);
5273
+ onChange({ hour: digitValue, minute, second });
5274
+ return;
5275
+ }
5276
+ if (numValue >= 0 && numValue <= 23) {
5277
+ setHour(numValue);
5278
+ onChange({ hour: numValue, minute, second });
5279
+ e.preventDefault();
5280
+ minuteInputRef.current?.focus();
5281
+ }
5282
+ }
5283
+ }
5284
+ else if (field === "minute") {
5285
+ if (e.key.match(/^[0-9]$/)) {
5286
+ const newValue = value + e.key;
5287
+ const numValue = parseInt(newValue, 10);
5288
+ if (numValue > 59) {
5289
+ const digitValue = parseInt(e.key, 10);
5290
+ setMinute(digitValue);
5291
+ onChange({ hour, minute: digitValue, second });
5292
+ return;
5293
+ }
5294
+ if (numValue >= 0 && numValue <= 59) {
5295
+ setMinute(numValue);
5296
+ onChange({ hour, minute: numValue, second });
5297
+ e.preventDefault();
5298
+ secondInputRef.current?.focus();
5299
+ }
5300
+ }
5301
+ }
5302
+ else if (field === "second") {
5303
+ if (e.key.match(/^[0-9]$/)) {
5304
+ const newValue = value + e.key;
5305
+ const numValue = parseInt(newValue, 10);
5306
+ if (numValue > 59) {
5307
+ const digitValue = parseInt(e.key, 10);
5308
+ setSecond(digitValue);
5309
+ onChange({ hour, minute, second: digitValue });
5310
+ return;
5311
+ }
5312
+ if (numValue >= 0 && numValue <= 59) {
5313
+ setSecond(numValue);
5314
+ onChange({ hour, minute, second: numValue });
5315
+ }
5316
+ }
5317
+ }
5318
+ };
5319
+ const handleClear = () => {
5320
+ setHour(null);
5321
+ setMinute(null);
5322
+ setSecond(null);
5323
+ onChange({ hour: null, minute: null, second: null });
5324
+ hourInputRef.current?.focus();
5325
+ };
5326
+ return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 10px 60px auto", gap: "2", width: "auto", minWidth: "300px", 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" }), jsx(Text, { children: ":" }), jsx(Input, { ref: secondInputRef, type: "text", value: second === null ? "" : second.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "second"), placeholder: "SS", maxLength: 2, textAlign: "center" }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
5327
+ }
5328
+
5329
+ function DateTimePicker$1({ value, onChange, format = "date-time", showSeconds = false, labels = {
5330
+ monthNamesShort: [
5331
+ "Jan",
5332
+ "Feb",
5333
+ "Mar",
5334
+ "Apr",
5335
+ "May",
5336
+ "Jun",
5337
+ "Jul",
5338
+ "Aug",
5339
+ "Sep",
5340
+ "Oct",
5341
+ "Nov",
5342
+ "Dec",
5343
+ ],
5344
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
5345
+ backButtonLabel: "Back",
5346
+ forwardButtonLabel: "Next",
5347
+ }, timezone = "Asia/Hong_Kong", }) {
5348
+ const [selectedDate, setSelectedDate] = useState(value || "");
5349
+ // Time state for 12-hour format
5350
+ const [hour12, setHour12] = useState(value ? dayjs(value).hour() % 12 || 12 : null);
5351
+ const [minute, setMinute] = useState(value ? dayjs(value).minute() : null);
5352
+ const [meridiem, setMeridiem] = useState(value ? (dayjs(value).hour() >= 12 ? "pm" : "am") : null);
5353
+ // Time state for 24-hour format
5354
+ const [hour24, setHour24] = useState(value ? dayjs(value).hour() : null);
5355
+ const [second, setSecond] = useState(value ? dayjs(value).second() : null);
5356
+ const handleDateChange = (date) => {
5357
+ setSelectedDate(date);
5358
+ updateDateTime(dayjs(date).tz(timezone).toISOString());
5359
+ };
5360
+ const handleTimeChange = (timeData) => {
5361
+ if (format === "iso-date-time") {
5362
+ setHour24(timeData.hour);
5363
+ setMinute(timeData.minute);
5364
+ if (showSeconds)
5365
+ setSecond(timeData.second);
5366
+ }
5367
+ else {
5368
+ setHour12(timeData.hour);
5369
+ setMinute(timeData.minute);
5370
+ setMeridiem(timeData.meridiem);
5371
+ }
5372
+ updateDateTime(dayjs(selectedDate).tz(timezone).toISOString(), timeData);
5373
+ };
5374
+ const updateDateTime = (date, timeData) => {
5375
+ if (!date) {
5376
+ onChange?.(undefined);
5377
+ return;
5378
+ }
5379
+ // use dayjs to convert the date to the timezone
5380
+ const newDate = dayjs(date).tz(timezone).toDate();
5381
+ if (format === "iso-date-time") {
5382
+ const h = timeData?.hour ?? hour24;
5383
+ const m = timeData?.minute ?? minute;
5384
+ const s = showSeconds ? timeData?.second ?? second : 0;
5385
+ if (h !== null)
5386
+ newDate.setHours(h);
5387
+ if (m !== null)
5388
+ newDate.setMinutes(m);
5389
+ if (s !== null)
5390
+ newDate.setSeconds(s);
5391
+ }
5392
+ else {
5393
+ const h = timeData?.hour ?? hour12;
5394
+ const m = timeData?.minute ?? minute;
5395
+ const mer = timeData?.meridiem ?? meridiem;
5396
+ if (h !== null && mer !== null) {
5397
+ let hour24 = h;
5398
+ if (mer === "am" && h === 12)
5399
+ hour24 = 0;
5400
+ else if (mer === "pm" && h < 12)
5401
+ hour24 = h + 12;
5402
+ newDate.setHours(hour24);
5403
+ }
5404
+ if (m !== null)
5405
+ newDate.setMinutes(m);
5406
+ newDate.setSeconds(0);
5407
+ }
5408
+ onChange?.(dayjs(newDate).tz(timezone).toISOString());
5409
+ };
5410
+ const handleClear = () => {
5411
+ setSelectedDate("");
5412
+ setHour12(null);
5413
+ setHour24(null);
5414
+ setMinute(null);
5415
+ setSecond(null);
5416
+ setMeridiem(null);
5417
+ onChange?.(undefined);
5418
+ };
5419
+ const isISO = format === "iso-date-time";
5420
+ return (jsxs(Flex, { direction: "column", gap: 4, p: 4, border: "1px solid", borderColor: "gray.200", borderRadius: "md", children: [jsx(DatePicker$1, { selected: selectedDate
5421
+ ? dayjs(selectedDate).tz(timezone).toDate()
5422
+ : new Date(), onDateSelected: ({ date }) => handleDateChange(dayjs(date).tz(timezone).toISOString()), monthsToDisplay: 1, labels: labels }), jsxs(Grid, { templateColumns: "1fr auto", alignItems: "center", gap: 4, children: [isISO ? (jsx(IsoTimePicker, { hour: hour24, setHour: setHour24, minute: minute, setMinute: setMinute, second: second, setSecond: setSecond, onChange: handleTimeChange })) : (jsx(TimePicker$1, { hour: hour12, setHour: setHour12, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange })), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "outline", colorScheme: "red", children: jsx(Icon, { as: FaTrash }) })] }), selectedDate && (jsxs(Flex, { gap: 2, children: [jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).format(isISO
5423
+ ? showSeconds
5424
+ ? "YYYY-MM-DD HH:mm:ss"
5425
+ : "YYYY-MM-DD HH:mm"
5426
+ : "YYYY-MM-DD hh:mm A ") }), jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).tz(timezone).format("Z") }), jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: timezone })] }))] }));
5427
+ }
5428
+
5429
+ dayjs.extend(utc);
5430
+ dayjs.extend(timezone);
5431
+ const DateTimePicker = ({ column, schema, prefix, }) => {
5432
+ const { watch, formState: { errors }, setValue, } = useFormContext();
5433
+ const { translate, timezone } = useSchemaContext();
5434
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5435
+ // with timezone
5436
+ dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
5437
+ const isRequired = required?.some((columnId) => columnId === column);
5438
+ const colLabel = `${prefix}${column}`;
5439
+ const [open, setOpen] = useState(false);
5440
+ const selectedDate = watch(colLabel);
5441
+ const displayDate = dayjs(selectedDate)
5442
+ .tz(timezone)
5443
+ .format(displayDateFormat);
5444
+ useEffect(() => {
5445
+ try {
5446
+ if (selectedDate) {
5447
+ // Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
5448
+ // For example, parse as UTC:
5449
+ const parsedDate = dayjs(selectedDate).tz(timezone);
5450
+ if (!parsedDate.isValid())
5451
+ return;
5452
+ // Format according to dateFormat from schema
5453
+ const formatted = parsedDate.format(dateFormat);
5454
+ // Update the form value only if different to avoid loops
5455
+ if (formatted !== selectedDate) {
5456
+ setValue(colLabel, formatted, {
5457
+ shouldValidate: true,
5458
+ shouldDirty: true,
5459
+ });
5460
+ }
5461
+ }
5462
+ }
5463
+ catch (e) {
5464
+ console.error(e);
5465
+ }
5466
+ }, [selectedDate, dateFormat, colLabel, setValue]);
5467
+ const customTranslate = (label) => {
5468
+ return translateWrapper({ prefix, column, label, translate });
5469
+ };
5470
+ return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
5471
+ gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5472
+ setOpen(true);
5473
+ }, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { minW: "450px", children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
5474
+ setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5475
+ }, timezone: timezone, labels: {
5476
+ monthNamesShort: [
5477
+ translate.t(`common.month_1`, { defaultValue: "January" }),
5478
+ translate.t(`common.month_2`, { defaultValue: "February" }),
5479
+ translate.t(`common.month_3`, { defaultValue: "March" }),
5480
+ translate.t(`common.month_4`, { defaultValue: "April" }),
5481
+ translate.t(`common.month_5`, { defaultValue: "May" }),
5482
+ translate.t(`common.month_6`, { defaultValue: "June" }),
5483
+ translate.t(`common.month_7`, { defaultValue: "July" }),
5484
+ translate.t(`common.month_8`, { defaultValue: "August" }),
5485
+ translate.t(`common.month_9`, { defaultValue: "September" }),
5486
+ translate.t(`common.month_10`, { defaultValue: "October" }),
5487
+ translate.t(`common.month_11`, { defaultValue: "November" }),
5488
+ translate.t(`common.month_12`, { defaultValue: "December" }),
5489
+ ],
5490
+ weekdayNamesShort: [
5491
+ translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5492
+ translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5493
+ translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5494
+ translate.t(`common.weekday_4`, {
5495
+ defaultValue: "Wed",
5496
+ }),
5497
+ translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5498
+ translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5499
+ translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5500
+ ],
5501
+ backButtonLabel: translate.t(`common.back_button`, {
5502
+ defaultValue: "Back",
5503
+ }),
5504
+ forwardButtonLabel: translate.t(`common.forward_button`, {
5505
+ defaultValue: "Forward",
5506
+ }),
5507
+ } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5508
+ };
5509
+
5167
5510
  const SchemaRenderer = ({ schema, prefix, column, }) => {
5168
5511
  const colSchema = schema;
5169
5512
  const { type, variant, properties: innerProperties, foreign_key, format, items, } = schema;
@@ -5184,6 +5527,9 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
5184
5527
  if (format === "time") {
5185
5528
  return jsx(TimePicker, { schema: colSchema, prefix, column });
5186
5529
  }
5530
+ if (format === "date-time") {
5531
+ return jsx(DateTimePicker, { schema: colSchema, prefix, column });
5532
+ }
5187
5533
  if (variant === "text-area") {
5188
5534
  return jsx(TextAreaInput, { schema: colSchema, prefix, column });
5189
5535
  }
@@ -5275,20 +5621,16 @@ const CustomViewer = ({ column, schema, prefix }) => {
5275
5621
 
5276
5622
  const DateViewer = ({ column, schema, prefix }) => {
5277
5623
  const { watch, formState: { errors }, } = useFormContext();
5278
- const { translate } = useSchemaContext();
5624
+ const { translate, timezone } = useSchemaContext();
5279
5625
  const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
5280
5626
  const isRequired = required?.some((columnId) => columnId === column);
5281
5627
  const colLabel = `${prefix}${column}`;
5282
5628
  const selectedDate = watch(colLabel);
5283
- const displayDate = dayjs.utc(selectedDate).format(displayDateFormat);
5629
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
5284
5630
  return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5285
5631
  gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5286
5632
  };
5287
5633
 
5288
- function translateWrapper({ prefix, column, label, translate, }) {
5289
- return translate.t(removeIndex(`${prefix}${column}.${label}`));
5290
- }
5291
-
5292
5634
  const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5293
5635
  const { watch, formState: { errors }, } = useFormContext();
5294
5636
  const { translate } = useSchemaContext();
@@ -5544,20 +5886,34 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
5544
5886
  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`)) }))] }) }));
5545
5887
  };
5546
5888
 
5547
- const TimeViewer = ({ column, schema, prefix, }) => {
5889
+ const TimeViewer = ({ column, schema, prefix }) => {
5548
5890
  const { watch, formState: { errors }, } = useFormContext();
5549
- const { translate } = useSchemaContext();
5550
- const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A" } = schema;
5891
+ const { translate, timezone } = useSchemaContext();
5892
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5551
5893
  const isRequired = required?.some((columnId) => columnId === column);
5552
5894
  const colLabel = `${prefix}${column}`;
5553
5895
  const selectedDate = watch(colLabel);
5554
- const displayedTime = dayjs(`1970-01-01T${selectedDate}Z`).isValid()
5555
- ? dayjs(`1970-01-01T${selectedDate}Z`).utc().format(displayTimeFormat)
5896
+ const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
5897
+ .tz(timezone)
5898
+ .isValid()
5899
+ ? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
5556
5900
  : "";
5557
5901
  return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5558
5902
  gridRow, children: [jsx(Text, { children: displayedTime }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5559
5903
  };
5560
5904
 
5905
+ const DateTimeViewer = ({ column, schema, prefix }) => {
5906
+ const { watch, formState: { errors }, } = useFormContext();
5907
+ const { translate, timezone } = useSchemaContext();
5908
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
5909
+ const isRequired = required?.some((columnId) => columnId === column);
5910
+ const colLabel = `${prefix}${column}`;
5911
+ const selectedDate = watch(colLabel);
5912
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
5913
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5914
+ gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5915
+ };
5916
+
5561
5917
  const SchemaViewer = ({ schema, prefix, column, }) => {
5562
5918
  const colSchema = schema;
5563
5919
  const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
@@ -5578,6 +5934,9 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
5578
5934
  if (format === "date") {
5579
5935
  return jsx(DateViewer, { schema: colSchema, prefix, column });
5580
5936
  }
5937
+ if (format === "date-time") {
5938
+ return jsx(DateTimeViewer, { schema: colSchema, prefix, column });
5939
+ }
5581
5940
  if (variant === "text-area") {
5582
5941
  return jsx(TextAreaViewer, { schema: colSchema, prefix, column });
5583
5942
  }
@@ -5680,21 +6039,25 @@ const FormBody = () => {
5680
6039
  // Enhanced validation function using AJV with i18n support
5681
6040
  const validateFormData = (data) => {
5682
6041
  try {
5683
- const validationResult = validateData(data, schema, { locale: validationLocale });
6042
+ const validationResult = validateData(data, schema, {
6043
+ locale: validationLocale,
6044
+ });
5684
6045
  return validationResult;
5685
6046
  }
5686
6047
  catch (error) {
5687
- const errorMessage = validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5688
- ? `驗證錯誤: ${error instanceof Error ? error.message : '未知驗證錯誤'}`
5689
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5690
- ? `验证错误: ${error instanceof Error ? error.message : '未知验证错误'}`
5691
- : `Validation error: ${error instanceof Error ? error.message : 'Unknown validation error'}`;
6048
+ const errorMessage = validationLocale === "zh-HK" || validationLocale === "zh-TW"
6049
+ ? `驗證錯誤: ${error instanceof Error ? error.message : "未知驗證錯誤"}`
6050
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6051
+ ? `验证错误: ${error instanceof Error ? error.message : "未知验证错误"}`
6052
+ : `Validation error: ${error instanceof Error ? error.message : "Unknown validation error"}`;
5692
6053
  return {
5693
6054
  isValid: false,
5694
- errors: [{
5695
- field: 'validation',
5696
- message: errorMessage
5697
- }]
6055
+ errors: [
6056
+ {
6057
+ field: "validation",
6058
+ message: errorMessage,
6059
+ },
6060
+ ],
5698
6061
  };
5699
6062
  }
5700
6063
  };
@@ -5727,13 +6090,13 @@ const FormBody = () => {
5727
6090
  if (!validationResult.isValid) {
5728
6091
  // Set validation errors
5729
6092
  const validationErrorMessage = {
5730
- type: 'validation',
6093
+ type: "validation",
5731
6094
  errors: validationResult.errors,
5732
- message: validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5733
- ? '表單驗證失敗'
5734
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5735
- ? '表单验证失败'
5736
- : 'Form validation failed'
6095
+ message: validationLocale === "zh-HK" || validationLocale === "zh-TW"
6096
+ ? "表單驗證失敗"
6097
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6098
+ ? "表单验证失败"
6099
+ : "Form validation failed",
5737
6100
  };
5738
6101
  onSubmitError(validationErrorMessage);
5739
6102
  return;
@@ -5746,22 +6109,22 @@ const FormBody = () => {
5746
6109
  };
5747
6110
  // Custom error renderer for validation errors with i18n support
5748
6111
  const renderValidationErrors = (validationErrors) => {
5749
- const title = validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5750
- ? `表單驗證失敗 (${validationErrors.length} 個錯誤${validationErrors.length > 1 ? '' : ''})`
5751
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5752
- ? `表单验证失败 (${validationErrors.length} 个错误${validationErrors.length > 1 ? '' : ''})`
5753
- : `Form Validation Failed (${validationErrors.length} error${validationErrors.length > 1 ? 's' : ''})`;
5754
- const formLabel = validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5755
- ? '表單'
5756
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5757
- ? '表单'
5758
- : 'Form';
5759
- const currentValueLabel = validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5760
- ? '目前值:'
5761
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5762
- ? '当前值:'
5763
- : 'Current value:';
5764
- return (jsxs(Alert.Root, { status: "error", children: [jsx(Alert.Indicator, {}), jsx(Alert.Title, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "validation-errors", children: [jsx(AccordionItemTrigger, { children: title }), jsx(AccordionItemContent, { children: jsx(Box, { mt: 2, children: validationErrors.map((err, index) => (jsxs(Box, { mb: 2, p: 2, bg: "red.50", borderLeft: "4px solid", borderColor: "red.500", children: [jsxs(Text, { fontWeight: "bold", color: "red.700", children: [err.field === 'root' ? formLabel : err.field, ":"] }), jsx(Text, { color: "red.600", children: err.message }), err.value !== undefined && (jsxs(Text, { fontSize: "sm", color: "red.500", mt: 1, children: [currentValueLabel, " ", JSON.stringify(err.value)] }))] }, index))) }) })] }) }) })] }));
6112
+ const title = validationLocale === "zh-HK" || validationLocale === "zh-TW"
6113
+ ? `表單驗證失敗 (${validationErrors.length} 個錯誤${validationErrors.length > 1 ? "" : ""})`
6114
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6115
+ ? `表单验证失败 (${validationErrors.length} 个错误${validationErrors.length > 1 ? "" : ""})`
6116
+ : `Form Validation Failed (${validationErrors.length} error${validationErrors.length > 1 ? "s" : ""})`;
6117
+ const formLabel = validationLocale === "zh-HK" || validationLocale === "zh-TW"
6118
+ ? "表單"
6119
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6120
+ ? "表单"
6121
+ : "Form";
6122
+ const currentValueLabel = validationLocale === "zh-HK" || validationLocale === "zh-TW"
6123
+ ? "目前值:"
6124
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6125
+ ? "当前值:"
6126
+ : "Current value:";
6127
+ return (jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "validation-errors", children: [jsx(AccordionItemTrigger, { children: title }), jsx(AccordionItemContent, { children: validationErrors.map((err, index) => (jsxs(Box, { mb: 2, p: 2, bg: "red.50", borderLeft: "4px solid", borderColor: "red.500", children: [jsxs(Text, { fontWeight: "bold", color: "red.700", children: [err.field === "root" ? formLabel : err.field, ":"] }), jsx(Text, { color: "red.600", children: err.message }), err.value !== undefined && (jsxs(Text, { fontSize: "sm", color: "red.500", mt: 1, whiteSpace: "pre-wrap", wordBreak: "break-all", children: [currentValueLabel, " ", JSON.stringify(err.value, null, 2)] }))] }, index))) })] }) }));
5765
6128
  };
5766
6129
  const renderColumns = ({ order, keys, ignore, include, }) => {
5767
6130
  const included = include.length > 0 ? include : keys;
@@ -5798,7 +6161,8 @@ const FormBody = () => {
5798
6161
  setIsConfirming(false);
5799
6162
  }, variant: "subtle", children: translate.t("cancel") }), jsx(Button$1, { onClick: () => {
5800
6163
  onFormSubmit(validatedData);
5801
- }, children: translate.t("confirm") })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && (jsx(Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsx(Fragment, { children: error?.type === 'validation' && error?.errors ? (renderValidationErrors(error.errors)) : (jsx(Alert.Root, { status: "error", children: jsx(Alert.Title, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "b", children: [jsxs(AccordionItemTrigger, { children: [jsx(Alert.Indicator, {}), `${error}`] }), jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) }) })) })) }))] }));
6164
+ }, children: translate.t("confirm") })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && (jsx(Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsx(Fragment, { children: error?.type === "validation" &&
6165
+ error?.errors ? (renderValidationErrors(error.errors)) : (jsx(Alert.Root, { status: "error", children: jsx(Alert.Title, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "b", children: [jsxs(AccordionItemTrigger, { children: [jsx(Alert.Indicator, {}), `${error}`] }), jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) }) })) })) }))] }));
5802
6166
  }
5803
6167
  return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: ordered.map((column) => {
5804
6168
  return (jsx(ColumnRenderer
@@ -5808,7 +6172,8 @@ const FormBody = () => {
5808
6172
  properties: properties, prefix: ``, column }, `form-input-${column}`));
5809
6173
  }) }), jsxs(Flex, { justifyContent: "end", gap: "2", children: [jsx(Button$1, { onClick: () => {
5810
6174
  methods.reset();
5811
- }, variant: "subtle", children: translate.t("reset") }), jsx(SubmitButton, {})] }), isError && error?.type === 'validation' && (jsx(Box, { mt: 4, children: error?.errors && renderValidationErrors(error.errors) }))] }));
6175
+ }, variant: "subtle", children: translate.t("reset") }), jsx(SubmitButton, {})] }), isError && error?.type === "validation" && (jsx(Box, { mt: 4, children: error?.errors &&
6176
+ renderValidationErrors(error.errors) }))] }));
5812
6177
  };
5813
6178
 
5814
6179
  const FormTitle = () => {