@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.js CHANGED
@@ -35,6 +35,7 @@ var zh_TW = require('ajv-i18n/localize/zh-TW');
35
35
  var zh_CN = require('ajv-i18n/localize/zh');
36
36
  var dayjs = require('dayjs');
37
37
  var utc = require('dayjs/plugin/utc');
38
+ var timezone = require('dayjs/plugin/timezone');
38
39
  var ti = require('react-icons/ti');
39
40
 
40
41
  function _interopNamespaceDefault(e) {
@@ -201,7 +202,7 @@ const monthNamesFull = [
201
202
  "November",
202
203
  "December",
203
204
  ];
204
- const weekdayNamesShort$1 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
205
+ const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
205
206
  function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, selected = [], firstDayOfWeek = 0, }) {
206
207
  const [hoveredDate, setHoveredDate] = React.useState();
207
208
  const onMouseLeave = () => {
@@ -236,7 +237,7 @@ function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, se
236
237
  offset: 12,
237
238
  }), children: ">>" })] }), jsxRuntime.jsx(react.Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", gap: 4, children: calendars.map((calendar) => (jsxRuntime.jsxs(react.Grid, { gap: 4, children: [jsxRuntime.jsxs(react.Grid, { justifyContent: "center", children: [monthNamesFull[calendar.month], " ", calendar.year] }), jsxRuntime.jsx(react.Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
238
239
  const weekday = (weekdayNum + firstDayOfWeek) % 7;
239
- return (jsxRuntime.jsx(react.Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort$1[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
240
+ return (jsxRuntime.jsx(react.Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
240
241
  }) }), jsxRuntime.jsx(react.Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: calendar.weeks.map((week, windex) => week.map((dateObj, index) => {
241
242
  const key = `${calendar.month}${calendar.year}${windex}${index}`;
242
243
  if (!dateObj) {
@@ -3693,6 +3694,7 @@ const SchemaFormContext = React.createContext({
3693
3694
  rowNumber: 0,
3694
3695
  requestOptions: {},
3695
3696
  validationLocale: 'en',
3697
+ timezone: 'Asia/Hong_Kong',
3696
3698
  });
3697
3699
 
3698
3700
  const useSchemaContext = () => {
@@ -3999,27 +4001,14 @@ const CustomInput = ({ column, schema, prefix }) => {
3999
4001
  }));
4000
4002
  };
4001
4003
 
4002
- const monthNamesShort = [
4003
- "Jan",
4004
- "Feb",
4005
- "Mar",
4006
- "Apr",
4007
- "May",
4008
- "Jun",
4009
- "Jul",
4010
- "Aug",
4011
- "Sep",
4012
- "Oct",
4013
- "Nov",
4014
- "Dec",
4015
- ];
4016
- const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
4017
4004
  const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firstDayOfWeek = 0, }) => {
4005
+ const { labels } = React.useContext(DatePickerContext);
4006
+ const { monthNamesShort, weekdayNamesShort, backButtonLabel, forwardButtonLabel } = labels;
4018
4007
  if (calendars.length) {
4019
4008
  return (jsxRuntime.jsxs(react.Grid, { children: [jsxRuntime.jsxs(react.Grid, { templateColumns: "repeat(4, auto)", justifyContent: "center", children: [jsxRuntime.jsx(react.Button, { variant: "ghost", ...getBackProps({
4020
4009
  calendars,
4021
4010
  offset: 12,
4022
- }), children: "<<" }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getBackProps({ calendars }), children: "Back" }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getForwardProps({ calendars }), children: "Next" }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getForwardProps({
4011
+ }), children: "<<" }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getBackProps({ calendars }), children: backButtonLabel }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getForwardProps({ calendars }), children: forwardButtonLabel }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getForwardProps({
4023
4012
  calendars,
4024
4013
  offset: 12,
4025
4014
  }), children: ">>" })] }), jsxRuntime.jsx(react.Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", children: calendars.map((calendar) => (jsxRuntime.jsxs(react.Grid, { gap: 4, children: [jsxRuntime.jsxs(react.Grid, { justifyContent: "center", children: [monthNamesShort[calendar.month], " ", calendar.year] }), jsxRuntime.jsxs(react.Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [[0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
@@ -4062,9 +4051,52 @@ const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firs
4062
4051
  }
4063
4052
  return null;
4064
4053
  };
4054
+ const DatePickerContext = React.createContext({
4055
+ labels: {
4056
+ monthNamesShort: [
4057
+ "Jan",
4058
+ "Feb",
4059
+ "Mar",
4060
+ "Apr",
4061
+ "May",
4062
+ "Jun",
4063
+ "Jul",
4064
+ "Aug",
4065
+ "Sep",
4066
+ "Oct",
4067
+ "Nov",
4068
+ "Dec",
4069
+ ],
4070
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
4071
+ backButtonLabel: "Back",
4072
+ forwardButtonLabel: "Next",
4073
+ },
4074
+ });
4065
4075
  let DatePicker$1 = class DatePicker extends React.Component {
4066
4076
  render() {
4067
- return (jsxRuntime.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) => (jsxRuntime.jsx(Calendar, { ...dayzedData, firstDayOfWeek: this.props.firstDayOfWeek })) }));
4077
+ const { labels = {
4078
+ monthNamesShort: [
4079
+ "Jan",
4080
+ "Feb",
4081
+ "Mar",
4082
+ "Apr",
4083
+ "May",
4084
+ "Jun",
4085
+ "Jul",
4086
+ "Aug",
4087
+ "Sep",
4088
+ "Oct",
4089
+ "Nov",
4090
+ "Dec",
4091
+ ],
4092
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
4093
+ backButtonLabel: "Back",
4094
+ forwardButtonLabel: "Next",
4095
+ }, } = this.props;
4096
+ return (jsxRuntime.jsx(DatePickerContext.Provider, { value: { labels }, children: jsxRuntime.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:
4097
+ // @ts-expect-error - Dayzed types need to be fixed
4098
+ (dayzedData) => (jsxRuntime.jsx(Calendar, { ...dayzedData,
4099
+ firstDayOfWeek: this.props.firstDayOfWeek })) }) }));
4068
4100
  }
4069
4101
  };
4070
4102
 
@@ -4086,24 +4118,27 @@ const PopoverRoot = react.Popover.Root;
4086
4118
  const PopoverBody = react.Popover.Body;
4087
4119
  const PopoverTrigger = react.Popover.Trigger;
4088
4120
 
4121
+ function translateWrapper({ prefix, column, label, translate, }) {
4122
+ return translate.t(removeIndex(`${prefix}${column}.${label}`));
4123
+ }
4124
+
4089
4125
  dayjs.extend(utc);
4126
+ dayjs.extend(timezone);
4090
4127
  const DatePicker = ({ column, schema, prefix }) => {
4091
4128
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
4092
- const { translate } = useSchemaContext();
4093
- const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD[T]HH:mm:ss[Z]", } = schema;
4129
+ const { translate, timezone } = useSchemaContext();
4130
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
4094
4131
  const isRequired = required?.some((columnId) => columnId === column);
4095
4132
  const colLabel = `${prefix}${column}`;
4096
4133
  const [open, setOpen] = React.useState(false);
4097
4134
  const selectedDate = watch(colLabel);
4098
- const displayDate = dayjs.utc(selectedDate).format(displayDateFormat);
4135
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
4099
4136
  React.useEffect(() => {
4100
4137
  try {
4101
4138
  if (selectedDate) {
4102
4139
  // Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
4103
4140
  // For example, parse as UTC:
4104
- const parsedDate = dayjs.utc(selectedDate);
4105
- // Or if you want to parse in local timezone without shifting:
4106
- // const parsedDate = dayjs.tz(selectedDate, dayjs.tz.guess());
4141
+ const parsedDate = dayjs(selectedDate).tz(timezone);
4107
4142
  if (!parsedDate.isValid())
4108
4143
  return;
4109
4144
  // Format according to dateFormat from schema
@@ -4121,19 +4156,48 @@ const DatePicker = ({ column, schema, prefix }) => {
4121
4156
  console.error(e);
4122
4157
  }
4123
4158
  }, [selectedDate, dateFormat, colLabel, setValue]);
4124
- return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4159
+ const customTranslate = (label) => {
4160
+ return translateWrapper({ prefix, column, label, translate });
4161
+ };
4162
+ return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
4125
4163
  gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
4126
4164
  setOpen(true);
4127
- }, justifyContent: "start", children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DatePicker$1
4128
- // @ts-expect-error TODO: find appropriate types
4129
- , {
4130
- // @ts-expect-error TODO: find appropriate types
4131
- selected: new Date(selectedDate),
4132
- // @ts-expect-error TODO: find appropriate types
4133
- onDateSelected: ({ date }) => {
4165
+ }, justifyContent: "start", children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
4134
4166
  setValue(colLabel, dayjs(date).format(dateFormat));
4135
4167
  setOpen(false);
4136
- } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4168
+ }, labels: {
4169
+ monthNamesShort: [
4170
+ translate.t(`common.month_1`, { defaultValue: "January" }),
4171
+ translate.t(`common.month_2`, { defaultValue: "February" }),
4172
+ translate.t(`common.month_3`, { defaultValue: "March" }),
4173
+ translate.t(`common.month_4`, { defaultValue: "April" }),
4174
+ translate.t(`common.month_5`, { defaultValue: "May" }),
4175
+ translate.t(`common.month_6`, { defaultValue: "June" }),
4176
+ translate.t(`common.month_7`, { defaultValue: "July" }),
4177
+ translate.t(`common.month_8`, { defaultValue: "August" }),
4178
+ translate.t(`common.month_9`, { defaultValue: "September" }),
4179
+ translate.t(`common.month_10`, { defaultValue: "October" }),
4180
+ translate.t(`common.month_11`, { defaultValue: "November" }),
4181
+ translate.t(`common.month_12`, { defaultValue: "December" }),
4182
+ ],
4183
+ weekdayNamesShort: [
4184
+ translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4185
+ translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4186
+ translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4187
+ translate.t(`common.weekday_4`, {
4188
+ defaultValue: "Wed",
4189
+ }),
4190
+ translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4191
+ translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4192
+ translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4193
+ ],
4194
+ backButtonLabel: translate.t(`common.back_button`, {
4195
+ defaultValue: "Back",
4196
+ }),
4197
+ forwardButtonLabel: translate.t(`common.forward_button`, {
4198
+ defaultValue: "Forward",
4199
+ }),
4200
+ } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
4137
4201
  };
4138
4202
 
4139
4203
  function filterArray(array, searchTerm) {
@@ -5116,22 +5180,23 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
5116
5180
  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, {}) })] }) }));
5117
5181
  }
5118
5182
 
5183
+ dayjs.extend(timezone);
5119
5184
  const TimePicker = ({ column, schema, prefix }) => {
5120
5185
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
5121
- const { translate } = useSchemaContext();
5122
- const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ss", displayTimeFormat = "hh:mm A", } = schema;
5186
+ const { translate, timezone } = useSchemaContext();
5187
+ const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5123
5188
  const isRequired = required?.some((columnId) => columnId === column);
5124
5189
  const colLabel = `${prefix}${column}`;
5125
5190
  const [open, setOpen] = React.useState(false);
5126
5191
  const value = watch(colLabel);
5127
- const displayedTime = dayjs(`1970-01-01T${value}Z`).isValid()
5128
- ? dayjs(`1970-01-01T${value}Z`).utc().format(displayTimeFormat)
5192
+ const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
5193
+ ? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
5129
5194
  : "";
5130
5195
  // Parse the initial time parts from the ISO time string (HH:mm:ss)
5131
5196
  const parseTime = (isoTime) => {
5132
5197
  if (!isoTime)
5133
5198
  return { hour: 12, minute: 0, meridiem: "am" };
5134
- const parsed = dayjs(`1970-01-01T${isoTime}Z`).utc();
5199
+ const parsed = dayjs(`1970-01-01T${isoTime}`).tz(timezone);
5135
5200
  if (!parsed.isValid())
5136
5201
  return { hour: 12, minute: 0, meridiem: "am" };
5137
5202
  let hour = parsed.hour();
@@ -5162,8 +5227,8 @@ const TimePicker = ({ column, schema, prefix }) => {
5162
5227
  h = 0;
5163
5228
  else if (meridiem === "pm" && hour < 12)
5164
5229
  h = hour + 12;
5165
- return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00Z`)
5166
- .utc()
5230
+ return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00`)
5231
+ .tz(timezone)
5167
5232
  .format(timeFormat);
5168
5233
  };
5169
5234
  // Handle changes to time parts
@@ -5179,11 +5244,289 @@ const TimePicker = ({ column, schema, prefix }) => {
5179
5244
  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: () => {
5180
5245
  setOpen(true);
5181
5246
  }, 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: {
5182
- am: translate.t(removeIndex(`common.am`)),
5183
- pm: translate.t(removeIndex(`common.pm`)),
5247
+ am: translate.t(`common.am`, { defaultValue: "AM" }),
5248
+ pm: translate.t(`common.pm`, { defaultValue: "PM" }),
5184
5249
  } }) }) }) }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5185
5250
  };
5186
5251
 
5252
+ function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
5253
+ // Refs for focus management
5254
+ const hourInputRef = React.useRef(null);
5255
+ const minuteInputRef = React.useRef(null);
5256
+ const secondInputRef = React.useRef(null);
5257
+ // Centralized handler for key events, value changes, and focus management
5258
+ const handleKeyDown = (e, field) => {
5259
+ const input = e.target;
5260
+ const value = input.value;
5261
+ // Handle navigation between fields
5262
+ if (e.key === "Tab") {
5263
+ return;
5264
+ }
5265
+ if (e.key === ":" && field === "hour") {
5266
+ e.preventDefault();
5267
+ minuteInputRef.current?.focus();
5268
+ return;
5269
+ }
5270
+ if (e.key === ":" && field === "minute") {
5271
+ e.preventDefault();
5272
+ secondInputRef.current?.focus();
5273
+ return;
5274
+ }
5275
+ if (e.key === "Backspace" && value === "") {
5276
+ e.preventDefault();
5277
+ if (field === "minute") {
5278
+ hourInputRef.current?.focus();
5279
+ }
5280
+ else if (field === "second") {
5281
+ minuteInputRef.current?.focus();
5282
+ }
5283
+ return;
5284
+ }
5285
+ // Handle number inputs
5286
+ if (field === "hour") {
5287
+ if (e.key.match(/^[0-9]$/)) {
5288
+ const newValue = value + e.key;
5289
+ const numValue = parseInt(newValue, 10);
5290
+ if (numValue > 23) {
5291
+ const digitValue = parseInt(e.key, 10);
5292
+ setHour(digitValue);
5293
+ onChange({ hour: digitValue, minute, second });
5294
+ return;
5295
+ }
5296
+ if (numValue >= 0 && numValue <= 23) {
5297
+ setHour(numValue);
5298
+ onChange({ hour: numValue, minute, second });
5299
+ e.preventDefault();
5300
+ minuteInputRef.current?.focus();
5301
+ }
5302
+ }
5303
+ }
5304
+ else if (field === "minute") {
5305
+ if (e.key.match(/^[0-9]$/)) {
5306
+ const newValue = value + e.key;
5307
+ const numValue = parseInt(newValue, 10);
5308
+ if (numValue > 59) {
5309
+ const digitValue = parseInt(e.key, 10);
5310
+ setMinute(digitValue);
5311
+ onChange({ hour, minute: digitValue, second });
5312
+ return;
5313
+ }
5314
+ if (numValue >= 0 && numValue <= 59) {
5315
+ setMinute(numValue);
5316
+ onChange({ hour, minute: numValue, second });
5317
+ e.preventDefault();
5318
+ secondInputRef.current?.focus();
5319
+ }
5320
+ }
5321
+ }
5322
+ else if (field === "second") {
5323
+ if (e.key.match(/^[0-9]$/)) {
5324
+ const newValue = value + e.key;
5325
+ const numValue = parseInt(newValue, 10);
5326
+ if (numValue > 59) {
5327
+ const digitValue = parseInt(e.key, 10);
5328
+ setSecond(digitValue);
5329
+ onChange({ hour, minute, second: digitValue });
5330
+ return;
5331
+ }
5332
+ if (numValue >= 0 && numValue <= 59) {
5333
+ setSecond(numValue);
5334
+ onChange({ hour, minute, second: numValue });
5335
+ }
5336
+ }
5337
+ }
5338
+ };
5339
+ const handleClear = () => {
5340
+ setHour(null);
5341
+ setMinute(null);
5342
+ setSecond(null);
5343
+ onChange({ hour: null, minute: null, second: null });
5344
+ hourInputRef.current?.focus();
5345
+ };
5346
+ return (jsxRuntime.jsx(react.Flex, { direction: "column", gap: 3, children: jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 10px 60px auto", gap: "2", width: "auto", minWidth: "300px", 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.jsx(react.Text, { children: ":" }), jsxRuntime.jsx(react.Input, { ref: secondInputRef, type: "text", value: second === null ? "" : second.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "second"), placeholder: "SS", maxLength: 2, textAlign: "center" }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }) }));
5347
+ }
5348
+
5349
+ function DateTimePicker$1({ value, onChange, format = "date-time", showSeconds = false, labels = {
5350
+ monthNamesShort: [
5351
+ "Jan",
5352
+ "Feb",
5353
+ "Mar",
5354
+ "Apr",
5355
+ "May",
5356
+ "Jun",
5357
+ "Jul",
5358
+ "Aug",
5359
+ "Sep",
5360
+ "Oct",
5361
+ "Nov",
5362
+ "Dec",
5363
+ ],
5364
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
5365
+ backButtonLabel: "Back",
5366
+ forwardButtonLabel: "Next",
5367
+ }, timezone = "Asia/Hong_Kong", }) {
5368
+ const [selectedDate, setSelectedDate] = React.useState(value || "");
5369
+ // Time state for 12-hour format
5370
+ const [hour12, setHour12] = React.useState(value ? dayjs(value).hour() % 12 || 12 : null);
5371
+ const [minute, setMinute] = React.useState(value ? dayjs(value).minute() : null);
5372
+ const [meridiem, setMeridiem] = React.useState(value ? (dayjs(value).hour() >= 12 ? "pm" : "am") : null);
5373
+ // Time state for 24-hour format
5374
+ const [hour24, setHour24] = React.useState(value ? dayjs(value).hour() : null);
5375
+ const [second, setSecond] = React.useState(value ? dayjs(value).second() : null);
5376
+ const handleDateChange = (date) => {
5377
+ setSelectedDate(date);
5378
+ updateDateTime(dayjs(date).tz(timezone).toISOString());
5379
+ };
5380
+ const handleTimeChange = (timeData) => {
5381
+ if (format === "iso-date-time") {
5382
+ setHour24(timeData.hour);
5383
+ setMinute(timeData.minute);
5384
+ if (showSeconds)
5385
+ setSecond(timeData.second);
5386
+ }
5387
+ else {
5388
+ setHour12(timeData.hour);
5389
+ setMinute(timeData.minute);
5390
+ setMeridiem(timeData.meridiem);
5391
+ }
5392
+ updateDateTime(dayjs(selectedDate).tz(timezone).toISOString(), timeData);
5393
+ };
5394
+ const updateDateTime = (date, timeData) => {
5395
+ if (!date) {
5396
+ onChange?.(undefined);
5397
+ return;
5398
+ }
5399
+ // use dayjs to convert the date to the timezone
5400
+ const newDate = dayjs(date).tz(timezone).toDate();
5401
+ if (format === "iso-date-time") {
5402
+ const h = timeData?.hour ?? hour24;
5403
+ const m = timeData?.minute ?? minute;
5404
+ const s = showSeconds ? timeData?.second ?? second : 0;
5405
+ if (h !== null)
5406
+ newDate.setHours(h);
5407
+ if (m !== null)
5408
+ newDate.setMinutes(m);
5409
+ if (s !== null)
5410
+ newDate.setSeconds(s);
5411
+ }
5412
+ else {
5413
+ const h = timeData?.hour ?? hour12;
5414
+ const m = timeData?.minute ?? minute;
5415
+ const mer = timeData?.meridiem ?? meridiem;
5416
+ if (h !== null && mer !== null) {
5417
+ let hour24 = h;
5418
+ if (mer === "am" && h === 12)
5419
+ hour24 = 0;
5420
+ else if (mer === "pm" && h < 12)
5421
+ hour24 = h + 12;
5422
+ newDate.setHours(hour24);
5423
+ }
5424
+ if (m !== null)
5425
+ newDate.setMinutes(m);
5426
+ newDate.setSeconds(0);
5427
+ }
5428
+ onChange?.(dayjs(newDate).tz(timezone).toISOString());
5429
+ };
5430
+ const handleClear = () => {
5431
+ setSelectedDate("");
5432
+ setHour12(null);
5433
+ setHour24(null);
5434
+ setMinute(null);
5435
+ setSecond(null);
5436
+ setMeridiem(null);
5437
+ onChange?.(undefined);
5438
+ };
5439
+ const isISO = format === "iso-date-time";
5440
+ return (jsxRuntime.jsxs(react.Flex, { direction: "column", gap: 4, p: 4, border: "1px solid", borderColor: "gray.200", borderRadius: "md", children: [jsxRuntime.jsx(DatePicker$1, { selected: selectedDate
5441
+ ? dayjs(selectedDate).tz(timezone).toDate()
5442
+ : new Date(), onDateSelected: ({ date }) => handleDateChange(dayjs(date).tz(timezone).toISOString()), monthsToDisplay: 1, labels: labels }), jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr auto", alignItems: "center", gap: 4, children: [isISO ? (jsxRuntime.jsx(IsoTimePicker, { hour: hour24, setHour: setHour24, minute: minute, setMinute: setMinute, second: second, setSecond: setSecond, onChange: handleTimeChange })) : (jsxRuntime.jsx(TimePicker$1, { hour: hour12, setHour: setHour12, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange })), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "outline", colorScheme: "red", children: jsxRuntime.jsx(react.Icon, { as: fa6.FaTrash }) })] }), selectedDate && (jsxRuntime.jsxs(react.Flex, { gap: 2, children: [jsxRuntime.jsx(react.Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).format(isISO
5443
+ ? showSeconds
5444
+ ? "YYYY-MM-DD HH:mm:ss"
5445
+ : "YYYY-MM-DD HH:mm"
5446
+ : "YYYY-MM-DD hh:mm A ") }), jsxRuntime.jsx(react.Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).tz(timezone).format("Z") }), jsxRuntime.jsx(react.Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: timezone })] }))] }));
5447
+ }
5448
+
5449
+ dayjs.extend(utc);
5450
+ dayjs.extend(timezone);
5451
+ const DateTimePicker = ({ column, schema, prefix, }) => {
5452
+ const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
5453
+ const { translate, timezone } = useSchemaContext();
5454
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5455
+ // with timezone
5456
+ dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
5457
+ const isRequired = required?.some((columnId) => columnId === column);
5458
+ const colLabel = `${prefix}${column}`;
5459
+ const [open, setOpen] = React.useState(false);
5460
+ const selectedDate = watch(colLabel);
5461
+ const displayDate = dayjs(selectedDate)
5462
+ .tz(timezone)
5463
+ .format(displayDateFormat);
5464
+ React.useEffect(() => {
5465
+ try {
5466
+ if (selectedDate) {
5467
+ // Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
5468
+ // For example, parse as UTC:
5469
+ const parsedDate = dayjs(selectedDate).tz(timezone);
5470
+ if (!parsedDate.isValid())
5471
+ return;
5472
+ // Format according to dateFormat from schema
5473
+ const formatted = parsedDate.format(dateFormat);
5474
+ // Update the form value only if different to avoid loops
5475
+ if (formatted !== selectedDate) {
5476
+ setValue(colLabel, formatted, {
5477
+ shouldValidate: true,
5478
+ shouldDirty: true,
5479
+ });
5480
+ }
5481
+ }
5482
+ }
5483
+ catch (e) {
5484
+ console.error(e);
5485
+ }
5486
+ }, [selectedDate, dateFormat, colLabel, setValue]);
5487
+ const customTranslate = (label) => {
5488
+ return translateWrapper({ prefix, column, label, translate });
5489
+ };
5490
+ return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
5491
+ gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5492
+ setOpen(true);
5493
+ }, justifyContent: "start", children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsxRuntime.jsx(PopoverContent, { minW: "450px", children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
5494
+ setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5495
+ }, timezone: timezone, labels: {
5496
+ monthNamesShort: [
5497
+ translate.t(`common.month_1`, { defaultValue: "January" }),
5498
+ translate.t(`common.month_2`, { defaultValue: "February" }),
5499
+ translate.t(`common.month_3`, { defaultValue: "March" }),
5500
+ translate.t(`common.month_4`, { defaultValue: "April" }),
5501
+ translate.t(`common.month_5`, { defaultValue: "May" }),
5502
+ translate.t(`common.month_6`, { defaultValue: "June" }),
5503
+ translate.t(`common.month_7`, { defaultValue: "July" }),
5504
+ translate.t(`common.month_8`, { defaultValue: "August" }),
5505
+ translate.t(`common.month_9`, { defaultValue: "September" }),
5506
+ translate.t(`common.month_10`, { defaultValue: "October" }),
5507
+ translate.t(`common.month_11`, { defaultValue: "November" }),
5508
+ translate.t(`common.month_12`, { defaultValue: "December" }),
5509
+ ],
5510
+ weekdayNamesShort: [
5511
+ translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5512
+ translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5513
+ translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5514
+ translate.t(`common.weekday_4`, {
5515
+ defaultValue: "Wed",
5516
+ }),
5517
+ translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5518
+ translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5519
+ translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5520
+ ],
5521
+ backButtonLabel: translate.t(`common.back_button`, {
5522
+ defaultValue: "Back",
5523
+ }),
5524
+ forwardButtonLabel: translate.t(`common.forward_button`, {
5525
+ defaultValue: "Forward",
5526
+ }),
5527
+ } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5528
+ };
5529
+
5187
5530
  const SchemaRenderer = ({ schema, prefix, column, }) => {
5188
5531
  const colSchema = schema;
5189
5532
  const { type, variant, properties: innerProperties, foreign_key, format, items, } = schema;
@@ -5204,6 +5547,9 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
5204
5547
  if (format === "time") {
5205
5548
  return jsxRuntime.jsx(TimePicker, { schema: colSchema, prefix, column });
5206
5549
  }
5550
+ if (format === "date-time") {
5551
+ return jsxRuntime.jsx(DateTimePicker, { schema: colSchema, prefix, column });
5552
+ }
5207
5553
  if (variant === "text-area") {
5208
5554
  return jsxRuntime.jsx(TextAreaInput, { schema: colSchema, prefix, column });
5209
5555
  }
@@ -5295,20 +5641,16 @@ const CustomViewer = ({ column, schema, prefix }) => {
5295
5641
 
5296
5642
  const DateViewer = ({ column, schema, prefix }) => {
5297
5643
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5298
- const { translate } = useSchemaContext();
5644
+ const { translate, timezone } = useSchemaContext();
5299
5645
  const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
5300
5646
  const isRequired = required?.some((columnId) => columnId === column);
5301
5647
  const colLabel = `${prefix}${column}`;
5302
5648
  const selectedDate = watch(colLabel);
5303
- const displayDate = dayjs.utc(selectedDate).format(displayDateFormat);
5649
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
5304
5650
  return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5305
5651
  gridRow, children: [jsxRuntime.jsxs(react.Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5306
5652
  };
5307
5653
 
5308
- function translateWrapper({ prefix, column, label, translate, }) {
5309
- return translate.t(removeIndex(`${prefix}${column}.${label}`));
5310
- }
5311
-
5312
5654
  const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5313
5655
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5314
5656
  const { translate } = useSchemaContext();
@@ -5564,20 +5906,34 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
5564
5906
  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`)) }))] }) }));
5565
5907
  };
5566
5908
 
5567
- const TimeViewer = ({ column, schema, prefix, }) => {
5909
+ const TimeViewer = ({ column, schema, prefix }) => {
5568
5910
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5569
- const { translate } = useSchemaContext();
5570
- const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A" } = schema;
5911
+ const { translate, timezone } = useSchemaContext();
5912
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5571
5913
  const isRequired = required?.some((columnId) => columnId === column);
5572
5914
  const colLabel = `${prefix}${column}`;
5573
5915
  const selectedDate = watch(colLabel);
5574
- const displayedTime = dayjs(`1970-01-01T${selectedDate}Z`).isValid()
5575
- ? dayjs(`1970-01-01T${selectedDate}Z`).utc().format(displayTimeFormat)
5916
+ const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
5917
+ .tz(timezone)
5918
+ .isValid()
5919
+ ? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
5576
5920
  : "";
5577
5921
  return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5578
5922
  gridRow, children: [jsxRuntime.jsx(react.Text, { children: displayedTime }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5579
5923
  };
5580
5924
 
5925
+ const DateTimeViewer = ({ column, schema, prefix }) => {
5926
+ const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5927
+ const { translate, timezone } = useSchemaContext();
5928
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
5929
+ const isRequired = required?.some((columnId) => columnId === column);
5930
+ const colLabel = `${prefix}${column}`;
5931
+ const selectedDate = watch(colLabel);
5932
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
5933
+ return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5934
+ gridRow, children: [jsxRuntime.jsxs(react.Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5935
+ };
5936
+
5581
5937
  const SchemaViewer = ({ schema, prefix, column, }) => {
5582
5938
  const colSchema = schema;
5583
5939
  const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
@@ -5598,6 +5954,9 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
5598
5954
  if (format === "date") {
5599
5955
  return jsxRuntime.jsx(DateViewer, { schema: colSchema, prefix, column });
5600
5956
  }
5957
+ if (format === "date-time") {
5958
+ return jsxRuntime.jsx(DateTimeViewer, { schema: colSchema, prefix, column });
5959
+ }
5601
5960
  if (variant === "text-area") {
5602
5961
  return jsxRuntime.jsx(TextAreaViewer, { schema: colSchema, prefix, column });
5603
5962
  }
@@ -5700,21 +6059,25 @@ const FormBody = () => {
5700
6059
  // Enhanced validation function using AJV with i18n support
5701
6060
  const validateFormData = (data) => {
5702
6061
  try {
5703
- const validationResult = validateData(data, schema, { locale: validationLocale });
6062
+ const validationResult = validateData(data, schema, {
6063
+ locale: validationLocale,
6064
+ });
5704
6065
  return validationResult;
5705
6066
  }
5706
6067
  catch (error) {
5707
- const errorMessage = validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5708
- ? `驗證錯誤: ${error instanceof Error ? error.message : '未知驗證錯誤'}`
5709
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5710
- ? `验证错误: ${error instanceof Error ? error.message : '未知验证错误'}`
5711
- : `Validation error: ${error instanceof Error ? error.message : 'Unknown validation error'}`;
6068
+ const errorMessage = validationLocale === "zh-HK" || validationLocale === "zh-TW"
6069
+ ? `驗證錯誤: ${error instanceof Error ? error.message : "未知驗證錯誤"}`
6070
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6071
+ ? `验证错误: ${error instanceof Error ? error.message : "未知验证错误"}`
6072
+ : `Validation error: ${error instanceof Error ? error.message : "Unknown validation error"}`;
5712
6073
  return {
5713
6074
  isValid: false,
5714
- errors: [{
5715
- field: 'validation',
5716
- message: errorMessage
5717
- }]
6075
+ errors: [
6076
+ {
6077
+ field: "validation",
6078
+ message: errorMessage,
6079
+ },
6080
+ ],
5718
6081
  };
5719
6082
  }
5720
6083
  };
@@ -5747,13 +6110,13 @@ const FormBody = () => {
5747
6110
  if (!validationResult.isValid) {
5748
6111
  // Set validation errors
5749
6112
  const validationErrorMessage = {
5750
- type: 'validation',
6113
+ type: "validation",
5751
6114
  errors: validationResult.errors,
5752
- message: validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5753
- ? '表單驗證失敗'
5754
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5755
- ? '表单验证失败'
5756
- : 'Form validation failed'
6115
+ message: validationLocale === "zh-HK" || validationLocale === "zh-TW"
6116
+ ? "表單驗證失敗"
6117
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6118
+ ? "表单验证失败"
6119
+ : "Form validation failed",
5757
6120
  };
5758
6121
  onSubmitError(validationErrorMessage);
5759
6122
  return;
@@ -5766,22 +6129,22 @@ const FormBody = () => {
5766
6129
  };
5767
6130
  // Custom error renderer for validation errors with i18n support
5768
6131
  const renderValidationErrors = (validationErrors) => {
5769
- const title = validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5770
- ? `表單驗證失敗 (${validationErrors.length} 個錯誤${validationErrors.length > 1 ? '' : ''})`
5771
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5772
- ? `表单验证失败 (${validationErrors.length} 个错误${validationErrors.length > 1 ? '' : ''})`
5773
- : `Form Validation Failed (${validationErrors.length} error${validationErrors.length > 1 ? 's' : ''})`;
5774
- const formLabel = validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5775
- ? '表單'
5776
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5777
- ? '表单'
5778
- : 'Form';
5779
- const currentValueLabel = validationLocale === 'zh-HK' || validationLocale === 'zh-TW'
5780
- ? '目前值:'
5781
- : validationLocale === 'zh-CN' || validationLocale === 'zh'
5782
- ? '当前值:'
5783
- : 'Current value:';
5784
- return (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Title, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: "validation-errors", children: [jsxRuntime.jsx(AccordionItemTrigger, { children: title }), jsxRuntime.jsx(AccordionItemContent, { children: jsxRuntime.jsx(react.Box, { mt: 2, children: validationErrors.map((err, index) => (jsxRuntime.jsxs(react.Box, { mb: 2, p: 2, bg: "red.50", borderLeft: "4px solid", borderColor: "red.500", children: [jsxRuntime.jsxs(react.Text, { fontWeight: "bold", color: "red.700", children: [err.field === 'root' ? formLabel : err.field, ":"] }), jsxRuntime.jsx(react.Text, { color: "red.600", children: err.message }), err.value !== undefined && (jsxRuntime.jsxs(react.Text, { fontSize: "sm", color: "red.500", mt: 1, children: [currentValueLabel, " ", JSON.stringify(err.value)] }))] }, index))) }) })] }) }) })] }));
6132
+ const title = validationLocale === "zh-HK" || validationLocale === "zh-TW"
6133
+ ? `表單驗證失敗 (${validationErrors.length} 個錯誤${validationErrors.length > 1 ? "" : ""})`
6134
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6135
+ ? `表单验证失败 (${validationErrors.length} 个错误${validationErrors.length > 1 ? "" : ""})`
6136
+ : `Form Validation Failed (${validationErrors.length} error${validationErrors.length > 1 ? "s" : ""})`;
6137
+ const formLabel = validationLocale === "zh-HK" || validationLocale === "zh-TW"
6138
+ ? "表單"
6139
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6140
+ ? "表单"
6141
+ : "Form";
6142
+ const currentValueLabel = validationLocale === "zh-HK" || validationLocale === "zh-TW"
6143
+ ? "目前值:"
6144
+ : validationLocale === "zh-CN" || validationLocale === "zh"
6145
+ ? "当前值:"
6146
+ : "Current value:";
6147
+ return (jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: "validation-errors", children: [jsxRuntime.jsx(AccordionItemTrigger, { children: title }), jsxRuntime.jsx(AccordionItemContent, { children: validationErrors.map((err, index) => (jsxRuntime.jsxs(react.Box, { mb: 2, p: 2, bg: "red.50", borderLeft: "4px solid", borderColor: "red.500", children: [jsxRuntime.jsxs(react.Text, { fontWeight: "bold", color: "red.700", children: [err.field === "root" ? formLabel : err.field, ":"] }), jsxRuntime.jsx(react.Text, { color: "red.600", children: err.message }), err.value !== undefined && (jsxRuntime.jsxs(react.Text, { fontSize: "sm", color: "red.500", mt: 1, whiteSpace: "pre-wrap", wordBreak: "break-all", children: [currentValueLabel, " ", JSON.stringify(err.value, null, 2)] }))] }, index))) })] }) }));
5785
6148
  };
5786
6149
  const renderColumns = ({ order, keys, ignore, include, }) => {
5787
6150
  const included = include.length > 0 ? include : keys;
@@ -5818,7 +6181,8 @@ const FormBody = () => {
5818
6181
  setIsConfirming(false);
5819
6182
  }, variant: "subtle", children: translate.t("cancel") }), jsxRuntime.jsx(react.Button, { onClick: () => {
5820
6183
  onFormSubmit(validatedData);
5821
- }, children: translate.t("confirm") })] }), isSubmiting && (jsxRuntime.jsx(react.Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsxRuntime.jsx(react.Center, { h: "full", children: jsxRuntime.jsx(react.Spinner, { color: "teal.500" }) }) })), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: error?.type === 'validation' && error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsx(react.Alert.Root, { status: "error", children: jsxRuntime.jsx(react.Alert.Title, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: "b", children: [jsxRuntime.jsxs(AccordionItemTrigger, { children: [jsxRuntime.jsx(react.Alert.Indicator, {}), `${error}`] }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) }) })) })) }))] }));
6184
+ }, children: translate.t("confirm") })] }), isSubmiting && (jsxRuntime.jsx(react.Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsxRuntime.jsx(react.Center, { h: "full", children: jsxRuntime.jsx(react.Spinner, { color: "teal.500" }) }) })), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: error?.type === "validation" &&
6185
+ error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsx(react.Alert.Root, { status: "error", children: jsxRuntime.jsx(react.Alert.Title, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: "b", children: [jsxRuntime.jsxs(AccordionItemTrigger, { children: [jsxRuntime.jsx(react.Alert.Indicator, {}), `${error}`] }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) }) })) })) }))] }));
5822
6186
  }
5823
6187
  return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: ordered.map((column) => {
5824
6188
  return (jsxRuntime.jsx(ColumnRenderer
@@ -5828,7 +6192,8 @@ const FormBody = () => {
5828
6192
  properties: properties, prefix: ``, column }, `form-input-${column}`));
5829
6193
  }) }), jsxRuntime.jsxs(react.Flex, { justifyContent: "end", gap: "2", children: [jsxRuntime.jsx(react.Button, { onClick: () => {
5830
6194
  methods.reset();
5831
- }, variant: "subtle", children: translate.t("reset") }), jsxRuntime.jsx(SubmitButton, {})] }), isError && error?.type === 'validation' && (jsxRuntime.jsx(react.Box, { mt: 4, children: error?.errors && renderValidationErrors(error.errors) }))] }));
6195
+ }, variant: "subtle", children: translate.t("reset") }), jsxRuntime.jsx(SubmitButton, {})] }), isError && error?.type === "validation" && (jsxRuntime.jsx(react.Box, { mt: 4, children: error?.errors &&
6196
+ renderValidationErrors(error.errors) }))] }));
5832
6197
  };
5833
6198
 
5834
6199
  const FormTitle = () => {