@bsol-oss/react-datatable5 12.0.0-beta.38 → 12.0.0-beta.39

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
@@ -3904,15 +3904,18 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
3904
3904
  setOpenSearchResult(true);
3905
3905
  }, justifyContent: "start", children: watchEnum === undefined
3906
3906
  ? ""
3907
- : translate.t(removeIndex(`${colLabel}.${watchEnum}`)) })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
3907
+ : translate.t(removeIndex(`${colLabel}.${watchEnum ?? "null"}`)) })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
3908
3908
  onSearchChange(event);
3909
3909
  setOpenSearchResult(true);
3910
- }, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${translate.t(`${colLabel}.total`)}: ${count}, ${translate.t(`${colLabel}.showing`)} ${limit}` })), jsxRuntime.jsxs(react.Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsxRuntime.jsx(react.Flex, { flexFlow: "column wrap", children: dataList.filter((item) => {
3910
+ }, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${translate.t(`${colLabel}.total`)}: ${count}, ${translate.t(`${colLabel}.showing`)} ${limit}` })), jsxRuntime.jsxs(react.Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsxRuntime.jsx(react.Flex, { flexFlow: "column wrap", children: dataList
3911
+ .filter((item) => {
3911
3912
  const searchTerm = (searchText || "").toLowerCase();
3912
3913
  if (!searchTerm)
3913
3914
  return true;
3914
3915
  // Check if the original enum value contains the search text
3915
- const enumValueMatch = item.toLowerCase().includes(searchTerm);
3916
+ const enumValueMatch = item
3917
+ .toLowerCase()
3918
+ .includes(searchTerm);
3916
3919
  // Check if the display value (translation) contains the search text
3917
3920
  const displayValue = !!renderDisplay === true
3918
3921
  ? renderDisplay(item)
@@ -3921,7 +3924,8 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
3921
3924
  const displayValueString = String(displayValue).toLowerCase();
3922
3925
  const displayValueMatch = displayValueString.includes(searchTerm);
3923
3926
  return enumValueMatch || displayValueMatch;
3924
- }).map((item) => {
3927
+ })
3928
+ .map((item) => {
3925
3929
  const selected = isMultiple
3926
3930
  ? watchEnums.some((enumValue) => item === enumValue)
3927
3931
  : watchEnum == item;
@@ -4726,42 +4730,180 @@ const TextAreaInput = ({ column, schema, prefix, }) => {
4726
4730
  function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
4727
4731
  am: "am",
4728
4732
  pm: "pm",
4729
- }, onChange = () => { }, }) {
4730
- const hours = Array.from({ length: 12 }, (_, i) => {
4731
- const hour = i + 1;
4732
- return hour.toString().padStart(2, "0");
4733
- });
4734
- const minutes = Array.from({ length: 60 }, (_, i) => {
4735
- return i.toString().padStart(2, "0");
4736
- });
4737
- const hoursCollection = react.createListCollection({
4738
- items: hours.map((hour) => ({
4739
- value: hour,
4740
- label: hour,
4741
- })),
4742
- });
4743
- const minutesCollection = react.createListCollection({
4744
- items: minutes.map((hour) => ({
4745
- value: hour,
4746
- label: hour,
4747
- })),
4748
- });
4749
- const meridiemsCollection = react.createListCollection({
4750
- items: ["am", "pm"].map((hour) => ({
4751
- value: hour,
4752
- label: meridiemLabel[hour] ?? hour,
4753
- })),
4754
- });
4755
- return (jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "auto auto auto auto", gap: "4", children: [jsxRuntime.jsxs(react.Select.Root, { width: "4rem", value: [`${hour.toString().padStart(2, "0")}`], onValueChange: (e) => {
4756
- setHour(parseInt(e.value[0]));
4757
- onChange({ hour: parseInt(e.value[0]), minute, meridiem });
4758
- }, collection: hoursCollection, children: [jsxRuntime.jsx(react.Select.HiddenSelect, {}), jsxRuntime.jsx(react.Select.Control, { children: jsxRuntime.jsx(react.Select.Trigger, { children: jsxRuntime.jsx(react.Select.ValueText, { placeholder: "Hour" }) }) }), jsxRuntime.jsx(react.Select.Positioner, { children: jsxRuntime.jsx(react.Select.Content, { children: hoursCollection.items.map(({ value: hour }) => (jsxRuntime.jsxs(react.Select.Item, { item: hour, children: [hour, jsxRuntime.jsx(react.Select.ItemIndicator, {})] }, hour))) }) })] }), jsxRuntime.jsx(react.Text, { children: ":" }), jsxRuntime.jsxs(react.Select.Root, { width: "4rem", value: [`${minute.toString().padStart(2, "0")}`], onValueChange: (e) => {
4759
- setMinute(parseInt(e.value[0]));
4760
- onChange({ hour, minute: parseInt(e.value[0]), meridiem });
4761
- }, collection: minutesCollection, children: [jsxRuntime.jsx(react.Select.HiddenSelect, {}), jsxRuntime.jsx(react.Select.Control, { children: jsxRuntime.jsx(react.Select.Trigger, { children: jsxRuntime.jsx(react.Select.ValueText, { placeholder: "Minute" }) }) }), jsxRuntime.jsx(react.Select.Positioner, { children: jsxRuntime.jsx(react.Select.Content, { children: minutes.map((minute) => (jsxRuntime.jsxs(react.Select.Item, { item: minute, children: [minute, jsxRuntime.jsx(react.Select.ItemIndicator, {})] }, minute))) }) })] }), jsxRuntime.jsxs(react.Select.Root, { width: "8rem", value: [meridiem], onValueChange: (e) => {
4762
- setMeridiem(e.value[0]);
4763
- onChange({ hour, minute, meridiem: e.value[0] });
4764
- }, collection: meridiemsCollection, children: [jsxRuntime.jsx(react.Select.HiddenSelect, {}), jsxRuntime.jsx(react.Select.Control, { children: jsxRuntime.jsx(react.Select.Trigger, { children: jsxRuntime.jsx(react.Select.ValueText, { placeholder: "am/pm" }) }) }), jsxRuntime.jsx(react.Select.Positioner, { children: jsxRuntime.jsx(react.Select.Content, { children: meridiemsCollection.items.map(({ value: hour, label }) => (jsxRuntime.jsxs(react.Select.Item, { item: hour, children: [label, jsxRuntime.jsx(react.Select.ItemIndicator, {})] }, hour))) }) })] })] }));
4733
+ }, onChange = (_newValue) => { }, }) {
4734
+ // Refs for focus management
4735
+ const hourInputRef = React.useRef(null);
4736
+ const minuteInputRef = React.useRef(null);
4737
+ const meridiemInputRef = React.useRef(null);
4738
+ // Centralized handler for key events, value changes, and focus management
4739
+ const handleKeyDown = (e, field) => {
4740
+ const input = e.target;
4741
+ const value = input.value;
4742
+ // Handle navigation between fields
4743
+ if (e.key === "Tab") {
4744
+ // Tab is handled by the browser, no need to override
4745
+ return;
4746
+ }
4747
+ if (e.key === ":" && field === "hour") {
4748
+ e.preventDefault();
4749
+ minuteInputRef.current?.focus();
4750
+ return;
4751
+ }
4752
+ if (e.key === "Backspace" && value === "") {
4753
+ e.preventDefault();
4754
+ if (field === "minute") {
4755
+ hourInputRef.current?.focus();
4756
+ }
4757
+ else if (field === "meridiem") {
4758
+ minuteInputRef.current?.focus();
4759
+ }
4760
+ return;
4761
+ }
4762
+ // Handle number inputs
4763
+ if (field === "hour") {
4764
+ if (e.key.match(/^[0-9]$/)) {
4765
+ const newValue = value + e.key;
4766
+ const numValue = parseInt(newValue, 10);
4767
+ console.log("newValue", newValue, numValue);
4768
+ if (numValue > 12) {
4769
+ const digitValue = parseInt(e.key, 10);
4770
+ setHour(digitValue);
4771
+ onChange({ hour: digitValue, minute, meridiem });
4772
+ return;
4773
+ }
4774
+ // Auto-advance to minutes if we have a valid hour (1-12)
4775
+ if (numValue >= 1 && numValue <= 12) {
4776
+ // Set the hour value
4777
+ setHour(numValue);
4778
+ onChange({ hour: numValue, minute, meridiem });
4779
+ // Move to minute input
4780
+ e.preventDefault();
4781
+ minuteInputRef.current?.focus();
4782
+ }
4783
+ }
4784
+ }
4785
+ else if (field === "minute") {
4786
+ if (e.key.match(/^[0-9]$/)) {
4787
+ const newValue = value + e.key;
4788
+ const numValue = parseInt(newValue, 10);
4789
+ if (numValue > 60) {
4790
+ const digitValue = parseInt(e.key, 10);
4791
+ setHour(digitValue);
4792
+ onChange({ hour, minute: digitValue, meridiem });
4793
+ return;
4794
+ }
4795
+ // Auto-advance to meridiem if we have a valid minute (0-59)
4796
+ if (numValue >= 0 && numValue <= 59) {
4797
+ // Set the minute value
4798
+ setMinute(numValue);
4799
+ onChange({ hour, minute: numValue, meridiem });
4800
+ // Move to meridiem input
4801
+ e.preventDefault();
4802
+ meridiemInputRef.current?.focus();
4803
+ }
4804
+ }
4805
+ }
4806
+ else if (field === "meridiem") {
4807
+ const key = e.key.toLowerCase();
4808
+ if (key === "a") {
4809
+ e.preventDefault();
4810
+ setMeridiem("am");
4811
+ onChange({ hour, minute, meridiem: "am" });
4812
+ input.value = "am";
4813
+ }
4814
+ else if (key === "p") {
4815
+ e.preventDefault();
4816
+ setMeridiem("pm");
4817
+ onChange({ hour, minute, meridiem: "pm" });
4818
+ input.value = "pm";
4819
+ }
4820
+ }
4821
+ };
4822
+ // Handle input blur events to validate and format values
4823
+ const handleBlur = (e, field) => {
4824
+ const value = e.target.value;
4825
+ if (field === "hour") {
4826
+ if (value === "") {
4827
+ if (hour !== null) {
4828
+ setHour(null);
4829
+ onChange({ hour: null, minute, meridiem });
4830
+ }
4831
+ return;
4832
+ }
4833
+ const numValue = parseInt(value, 10);
4834
+ if (isNaN(numValue) || numValue < 1 || numValue > 12) {
4835
+ setHour(null);
4836
+ onChange({ hour: null, minute, meridiem });
4837
+ }
4838
+ else if (hour !== numValue) {
4839
+ setHour(numValue);
4840
+ onChange({ hour: numValue, minute, meridiem });
4841
+ }
4842
+ }
4843
+ else if (field === "minute") {
4844
+ if (value === "") {
4845
+ if (minute !== null) {
4846
+ setMinute(null);
4847
+ onChange({ hour, minute: null, meridiem });
4848
+ }
4849
+ return;
4850
+ }
4851
+ const numValue = parseInt(value, 10);
4852
+ if (isNaN(numValue) || numValue < 0 || numValue > 59) {
4853
+ setMinute(null);
4854
+ onChange({ hour, minute: null, meridiem });
4855
+ }
4856
+ else if (minute !== numValue) {
4857
+ setMinute(numValue);
4858
+ onChange({ hour, minute: numValue, meridiem });
4859
+ }
4860
+ }
4861
+ else if (field === "meridiem") {
4862
+ if (value === "") {
4863
+ if (meridiem !== null) {
4864
+ setMeridiem(null);
4865
+ onChange({ hour, minute, meridiem: null });
4866
+ }
4867
+ return;
4868
+ }
4869
+ const lowerValue = value.toLowerCase();
4870
+ if (lowerValue !== "am" && lowerValue !== "pm") {
4871
+ if (lowerValue === "a") {
4872
+ setMeridiem("am");
4873
+ onChange({ hour, minute, meridiem: "am" });
4874
+ }
4875
+ else if (lowerValue === "p") {
4876
+ setMeridiem("pm");
4877
+ onChange({ hour, minute, meridiem: "pm" });
4878
+ }
4879
+ else {
4880
+ setMeridiem(null);
4881
+ onChange({ hour, minute, meridiem: null });
4882
+ }
4883
+ }
4884
+ else if (meridiem !== lowerValue) {
4885
+ setMeridiem(lowerValue);
4886
+ onChange({ hour, minute, meridiem: lowerValue });
4887
+ }
4888
+ }
4889
+ };
4890
+ // Handle meridiem button click
4891
+ const handleMeridiemClick = (newMeridiem) => {
4892
+ setMeridiem(newMeridiem);
4893
+ onChange({ hour, minute, meridiem: newMeridiem });
4894
+ };
4895
+ const handleClear = () => {
4896
+ setHour(null);
4897
+ setMinute(null);
4898
+ setMeridiem(null);
4899
+ onChange({ hour: null, minute: null, meridiem: null });
4900
+ // Focus the hour field after clearing
4901
+ hourInputRef.current?.focus();
4902
+ };
4903
+ function handleFocus(event) {
4904
+ event.target.select();
4905
+ }
4906
+ return (jsxRuntime.jsx(react.Flex, { direction: "column", gap: 3, children: jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsxRuntime.jsx(react.Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), onBlur: (e) => handleBlur(e, "hour"), onFocus: handleFocus, placeholder: "HH", maxLength: 2, textAlign: "center" }), jsxRuntime.jsx(react.Text, { children: ":" }), jsxRuntime.jsx(react.Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), onBlur: (e) => handleBlur(e, "minute"), onFocus: handleFocus, placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxRuntime.jsxs(react.Flex, { gap: "1", children: [jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }) }));
4765
4907
  }
4766
4908
 
4767
4909
  const TimePicker = ({ column, schema, prefix }) => {
@@ -4772,7 +4914,7 @@ const TimePicker = ({ column, schema, prefix }) => {
4772
4914
  const colLabel = `${prefix}${column}`;
4773
4915
  const [open, setOpen] = React.useState(false);
4774
4916
  const value = watch(colLabel);
4775
- const formatedTime = dayjs(value).format("hh:mm A");
4917
+ const formatedTime = value ? dayjs(value).format("hh:mm A") : "";
4776
4918
  // Parse the initial time parts from the ISO time string (HH:mm:ss)
4777
4919
  const parseTime = (isoTime) => {
4778
4920
  if (!isoTime)
@@ -4801,6 +4943,8 @@ const TimePicker = ({ column, schema, prefix }) => {
4801
4943
  }, [value]);
4802
4944
  // Convert hour, minute, meridiem to 24-hour ISO time string
4803
4945
  const toIsoTime = (hour, minute, meridiem) => {
4946
+ if (hour === null || minute === null || meridiem === null)
4947
+ return null;
4804
4948
  let h = hour;
4805
4949
  if (meridiem === "am" && hour === 12)
4806
4950
  h = 0;
@@ -4821,8 +4965,8 @@ const TimePicker = ({ column, schema, prefix }) => {
4821
4965
  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: () => {
4822
4966
  setOpen(true);
4823
4967
  }, justifyContent: "start", children: [jsxRuntime.jsx(io.IoMdClock, {}), value !== undefined ? `${formatedTime}` : ""] }) }), jsxRuntime.jsx(react.Portal, { children: jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { ref: containerRef, children: jsxRuntime.jsx(react.Popover.Body, { children: jsxRuntime.jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
4824
- am: translate.t(removeIndex(`${colLabel}.am`)),
4825
- pm: translate.t(removeIndex(`${colLabel}.pm`)),
4968
+ am: translate.t(removeIndex(`common.am`)),
4969
+ pm: translate.t(removeIndex(`common.pm`)),
4826
4970
  } }) }) }) }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4827
4971
  };
4828
4972
 
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Image, EmptyState as EmptyState$2, VStack, Alert, Card, Tooltip as Tooltip$1, Group, InputElement, Icon, List, Table as Table$1, Checkbox as Checkbox$1, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Accordion, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Textarea, createListCollection, Select, Center, Heading } from '@chakra-ui/react';
2
+ import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Image, EmptyState as EmptyState$2, VStack, Alert, Card, Tooltip as Tooltip$1, Group, InputElement, Icon, List, Table as Table$1, Checkbox as Checkbox$1, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Accordion, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Textarea, Center, Heading } from '@chakra-ui/react';
3
3
  import { AiOutlineColumnWidth } from 'react-icons/ai';
4
4
  import * as React from 'react';
5
5
  import React__default, { createContext, useContext, useState, useEffect, useRef } from 'react';
@@ -3884,15 +3884,18 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
3884
3884
  setOpenSearchResult(true);
3885
3885
  }, justifyContent: "start", children: watchEnum === undefined
3886
3886
  ? ""
3887
- : translate.t(removeIndex(`${colLabel}.${watchEnum}`)) })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
3887
+ : translate.t(removeIndex(`${colLabel}.${watchEnum ?? "null"}`)) })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
3888
3888
  onSearchChange(event);
3889
3889
  setOpenSearchResult(true);
3890
- }, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${translate.t(`${colLabel}.total`)}: ${count}, ${translate.t(`${colLabel}.showing`)} ${limit}` })), jsxs(Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsx(Flex, { flexFlow: "column wrap", children: dataList.filter((item) => {
3890
+ }, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${translate.t(`${colLabel}.total`)}: ${count}, ${translate.t(`${colLabel}.showing`)} ${limit}` })), jsxs(Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsx(Flex, { flexFlow: "column wrap", children: dataList
3891
+ .filter((item) => {
3891
3892
  const searchTerm = (searchText || "").toLowerCase();
3892
3893
  if (!searchTerm)
3893
3894
  return true;
3894
3895
  // Check if the original enum value contains the search text
3895
- const enumValueMatch = item.toLowerCase().includes(searchTerm);
3896
+ const enumValueMatch = item
3897
+ .toLowerCase()
3898
+ .includes(searchTerm);
3896
3899
  // Check if the display value (translation) contains the search text
3897
3900
  const displayValue = !!renderDisplay === true
3898
3901
  ? renderDisplay(item)
@@ -3901,7 +3904,8 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
3901
3904
  const displayValueString = String(displayValue).toLowerCase();
3902
3905
  const displayValueMatch = displayValueString.includes(searchTerm);
3903
3906
  return enumValueMatch || displayValueMatch;
3904
- }).map((item) => {
3907
+ })
3908
+ .map((item) => {
3905
3909
  const selected = isMultiple
3906
3910
  ? watchEnums.some((enumValue) => item === enumValue)
3907
3911
  : watchEnum == item;
@@ -4706,42 +4710,180 @@ const TextAreaInput = ({ column, schema, prefix, }) => {
4706
4710
  function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
4707
4711
  am: "am",
4708
4712
  pm: "pm",
4709
- }, onChange = () => { }, }) {
4710
- const hours = Array.from({ length: 12 }, (_, i) => {
4711
- const hour = i + 1;
4712
- return hour.toString().padStart(2, "0");
4713
- });
4714
- const minutes = Array.from({ length: 60 }, (_, i) => {
4715
- return i.toString().padStart(2, "0");
4716
- });
4717
- const hoursCollection = createListCollection({
4718
- items: hours.map((hour) => ({
4719
- value: hour,
4720
- label: hour,
4721
- })),
4722
- });
4723
- const minutesCollection = createListCollection({
4724
- items: minutes.map((hour) => ({
4725
- value: hour,
4726
- label: hour,
4727
- })),
4728
- });
4729
- const meridiemsCollection = createListCollection({
4730
- items: ["am", "pm"].map((hour) => ({
4731
- value: hour,
4732
- label: meridiemLabel[hour] ?? hour,
4733
- })),
4734
- });
4735
- return (jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "auto auto auto auto", gap: "4", children: [jsxs(Select.Root, { width: "4rem", value: [`${hour.toString().padStart(2, "0")}`], onValueChange: (e) => {
4736
- setHour(parseInt(e.value[0]));
4737
- onChange({ hour: parseInt(e.value[0]), minute, meridiem });
4738
- }, collection: hoursCollection, children: [jsx(Select.HiddenSelect, {}), jsx(Select.Control, { children: jsx(Select.Trigger, { children: jsx(Select.ValueText, { placeholder: "Hour" }) }) }), jsx(Select.Positioner, { children: jsx(Select.Content, { children: hoursCollection.items.map(({ value: hour }) => (jsxs(Select.Item, { item: hour, children: [hour, jsx(Select.ItemIndicator, {})] }, hour))) }) })] }), jsx(Text, { children: ":" }), jsxs(Select.Root, { width: "4rem", value: [`${minute.toString().padStart(2, "0")}`], onValueChange: (e) => {
4739
- setMinute(parseInt(e.value[0]));
4740
- onChange({ hour, minute: parseInt(e.value[0]), meridiem });
4741
- }, collection: minutesCollection, children: [jsx(Select.HiddenSelect, {}), jsx(Select.Control, { children: jsx(Select.Trigger, { children: jsx(Select.ValueText, { placeholder: "Minute" }) }) }), jsx(Select.Positioner, { children: jsx(Select.Content, { children: minutes.map((minute) => (jsxs(Select.Item, { item: minute, children: [minute, jsx(Select.ItemIndicator, {})] }, minute))) }) })] }), jsxs(Select.Root, { width: "8rem", value: [meridiem], onValueChange: (e) => {
4742
- setMeridiem(e.value[0]);
4743
- onChange({ hour, minute, meridiem: e.value[0] });
4744
- }, collection: meridiemsCollection, children: [jsx(Select.HiddenSelect, {}), jsx(Select.Control, { children: jsx(Select.Trigger, { children: jsx(Select.ValueText, { placeholder: "am/pm" }) }) }), jsx(Select.Positioner, { children: jsx(Select.Content, { children: meridiemsCollection.items.map(({ value: hour, label }) => (jsxs(Select.Item, { item: hour, children: [label, jsx(Select.ItemIndicator, {})] }, hour))) }) })] })] }));
4713
+ }, onChange = (_newValue) => { }, }) {
4714
+ // Refs for focus management
4715
+ const hourInputRef = useRef(null);
4716
+ const minuteInputRef = useRef(null);
4717
+ const meridiemInputRef = useRef(null);
4718
+ // Centralized handler for key events, value changes, and focus management
4719
+ const handleKeyDown = (e, field) => {
4720
+ const input = e.target;
4721
+ const value = input.value;
4722
+ // Handle navigation between fields
4723
+ if (e.key === "Tab") {
4724
+ // Tab is handled by the browser, no need to override
4725
+ return;
4726
+ }
4727
+ if (e.key === ":" && field === "hour") {
4728
+ e.preventDefault();
4729
+ minuteInputRef.current?.focus();
4730
+ return;
4731
+ }
4732
+ if (e.key === "Backspace" && value === "") {
4733
+ e.preventDefault();
4734
+ if (field === "minute") {
4735
+ hourInputRef.current?.focus();
4736
+ }
4737
+ else if (field === "meridiem") {
4738
+ minuteInputRef.current?.focus();
4739
+ }
4740
+ return;
4741
+ }
4742
+ // Handle number inputs
4743
+ if (field === "hour") {
4744
+ if (e.key.match(/^[0-9]$/)) {
4745
+ const newValue = value + e.key;
4746
+ const numValue = parseInt(newValue, 10);
4747
+ console.log("newValue", newValue, numValue);
4748
+ if (numValue > 12) {
4749
+ const digitValue = parseInt(e.key, 10);
4750
+ setHour(digitValue);
4751
+ onChange({ hour: digitValue, minute, meridiem });
4752
+ return;
4753
+ }
4754
+ // Auto-advance to minutes if we have a valid hour (1-12)
4755
+ if (numValue >= 1 && numValue <= 12) {
4756
+ // Set the hour value
4757
+ setHour(numValue);
4758
+ onChange({ hour: numValue, minute, meridiem });
4759
+ // Move to minute input
4760
+ e.preventDefault();
4761
+ minuteInputRef.current?.focus();
4762
+ }
4763
+ }
4764
+ }
4765
+ else if (field === "minute") {
4766
+ if (e.key.match(/^[0-9]$/)) {
4767
+ const newValue = value + e.key;
4768
+ const numValue = parseInt(newValue, 10);
4769
+ if (numValue > 60) {
4770
+ const digitValue = parseInt(e.key, 10);
4771
+ setHour(digitValue);
4772
+ onChange({ hour, minute: digitValue, meridiem });
4773
+ return;
4774
+ }
4775
+ // Auto-advance to meridiem if we have a valid minute (0-59)
4776
+ if (numValue >= 0 && numValue <= 59) {
4777
+ // Set the minute value
4778
+ setMinute(numValue);
4779
+ onChange({ hour, minute: numValue, meridiem });
4780
+ // Move to meridiem input
4781
+ e.preventDefault();
4782
+ meridiemInputRef.current?.focus();
4783
+ }
4784
+ }
4785
+ }
4786
+ else if (field === "meridiem") {
4787
+ const key = e.key.toLowerCase();
4788
+ if (key === "a") {
4789
+ e.preventDefault();
4790
+ setMeridiem("am");
4791
+ onChange({ hour, minute, meridiem: "am" });
4792
+ input.value = "am";
4793
+ }
4794
+ else if (key === "p") {
4795
+ e.preventDefault();
4796
+ setMeridiem("pm");
4797
+ onChange({ hour, minute, meridiem: "pm" });
4798
+ input.value = "pm";
4799
+ }
4800
+ }
4801
+ };
4802
+ // Handle input blur events to validate and format values
4803
+ const handleBlur = (e, field) => {
4804
+ const value = e.target.value;
4805
+ if (field === "hour") {
4806
+ if (value === "") {
4807
+ if (hour !== null) {
4808
+ setHour(null);
4809
+ onChange({ hour: null, minute, meridiem });
4810
+ }
4811
+ return;
4812
+ }
4813
+ const numValue = parseInt(value, 10);
4814
+ if (isNaN(numValue) || numValue < 1 || numValue > 12) {
4815
+ setHour(null);
4816
+ onChange({ hour: null, minute, meridiem });
4817
+ }
4818
+ else if (hour !== numValue) {
4819
+ setHour(numValue);
4820
+ onChange({ hour: numValue, minute, meridiem });
4821
+ }
4822
+ }
4823
+ else if (field === "minute") {
4824
+ if (value === "") {
4825
+ if (minute !== null) {
4826
+ setMinute(null);
4827
+ onChange({ hour, minute: null, meridiem });
4828
+ }
4829
+ return;
4830
+ }
4831
+ const numValue = parseInt(value, 10);
4832
+ if (isNaN(numValue) || numValue < 0 || numValue > 59) {
4833
+ setMinute(null);
4834
+ onChange({ hour, minute: null, meridiem });
4835
+ }
4836
+ else if (minute !== numValue) {
4837
+ setMinute(numValue);
4838
+ onChange({ hour, minute: numValue, meridiem });
4839
+ }
4840
+ }
4841
+ else if (field === "meridiem") {
4842
+ if (value === "") {
4843
+ if (meridiem !== null) {
4844
+ setMeridiem(null);
4845
+ onChange({ hour, minute, meridiem: null });
4846
+ }
4847
+ return;
4848
+ }
4849
+ const lowerValue = value.toLowerCase();
4850
+ if (lowerValue !== "am" && lowerValue !== "pm") {
4851
+ if (lowerValue === "a") {
4852
+ setMeridiem("am");
4853
+ onChange({ hour, minute, meridiem: "am" });
4854
+ }
4855
+ else if (lowerValue === "p") {
4856
+ setMeridiem("pm");
4857
+ onChange({ hour, minute, meridiem: "pm" });
4858
+ }
4859
+ else {
4860
+ setMeridiem(null);
4861
+ onChange({ hour, minute, meridiem: null });
4862
+ }
4863
+ }
4864
+ else if (meridiem !== lowerValue) {
4865
+ setMeridiem(lowerValue);
4866
+ onChange({ hour, minute, meridiem: lowerValue });
4867
+ }
4868
+ }
4869
+ };
4870
+ // Handle meridiem button click
4871
+ const handleMeridiemClick = (newMeridiem) => {
4872
+ setMeridiem(newMeridiem);
4873
+ onChange({ hour, minute, meridiem: newMeridiem });
4874
+ };
4875
+ const handleClear = () => {
4876
+ setHour(null);
4877
+ setMinute(null);
4878
+ setMeridiem(null);
4879
+ onChange({ hour: null, minute: null, meridiem: null });
4880
+ // Focus the hour field after clearing
4881
+ hourInputRef.current?.focus();
4882
+ };
4883
+ function handleFocus(event) {
4884
+ event.target.select();
4885
+ }
4886
+ return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), onBlur: (e) => handleBlur(e, "hour"), onFocus: handleFocus, placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), onBlur: (e) => handleBlur(e, "minute"), onFocus: handleFocus, placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxs(Flex, { gap: "1", children: [jsx(Button$1, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsx(Button$1, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
4745
4887
  }
4746
4888
 
4747
4889
  const TimePicker = ({ column, schema, prefix }) => {
@@ -4752,7 +4894,7 @@ const TimePicker = ({ column, schema, prefix }) => {
4752
4894
  const colLabel = `${prefix}${column}`;
4753
4895
  const [open, setOpen] = useState(false);
4754
4896
  const value = watch(colLabel);
4755
- const formatedTime = dayjs(value).format("hh:mm A");
4897
+ const formatedTime = value ? dayjs(value).format("hh:mm A") : "";
4756
4898
  // Parse the initial time parts from the ISO time string (HH:mm:ss)
4757
4899
  const parseTime = (isoTime) => {
4758
4900
  if (!isoTime)
@@ -4781,6 +4923,8 @@ const TimePicker = ({ column, schema, prefix }) => {
4781
4923
  }, [value]);
4782
4924
  // Convert hour, minute, meridiem to 24-hour ISO time string
4783
4925
  const toIsoTime = (hour, minute, meridiem) => {
4926
+ if (hour === null || minute === null || meridiem === null)
4927
+ return null;
4784
4928
  let h = hour;
4785
4929
  if (meridiem === "am" && hour === 12)
4786
4930
  h = 0;
@@ -4801,8 +4945,8 @@ const TimePicker = ({ column, schema, prefix }) => {
4801
4945
  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: () => {
4802
4946
  setOpen(true);
4803
4947
  }, justifyContent: "start", children: [jsx(IoMdClock, {}), value !== undefined ? `${formatedTime}` : ""] }) }), jsx(Portal, { children: jsx(Popover.Positioner, { children: jsx(Popover.Content, { ref: containerRef, children: jsx(Popover.Body, { children: jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
4804
- am: translate.t(removeIndex(`${colLabel}.am`)),
4805
- pm: translate.t(removeIndex(`${colLabel}.pm`)),
4948
+ am: translate.t(removeIndex(`common.am`)),
4949
+ pm: translate.t(removeIndex(`common.pm`)),
4806
4950
  } }) }) }) }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4807
4951
  };
4808
4952
 
@@ -1,14 +1,15 @@
1
+ import { Dispatch, SetStateAction } from "react";
1
2
  interface TimePickerProps {
2
- hour: number;
3
- setHour: (hour: number) => void;
4
- minute: number;
5
- setMinute: (minute: number) => void;
6
- meridiem: "am" | "pm";
7
- setMeridiem: (meridiem: "am" | "pm") => void;
3
+ hour: number | null;
4
+ setHour: Dispatch<SetStateAction<number | null>>;
5
+ minute: number | null;
6
+ setMinute: Dispatch<SetStateAction<number | null>>;
7
+ meridiem: "am" | "pm" | null;
8
+ setMeridiem: Dispatch<SetStateAction<"am" | "pm" | null>>;
8
9
  onChange?: (newValue: {
9
- hour: number;
10
- minute: number;
11
- meridiem: "am" | "pm";
10
+ hour: number | null;
11
+ minute: number | null;
12
+ meridiem: "am" | "pm" | null;
12
13
  }) => void;
13
14
  meridiemLabel?: {
14
15
  am: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsol-oss/react-datatable5",
3
- "version": "12.0.0-beta.38",
3
+ "version": "12.0.0-beta.39",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",