@rufous/ui 0.2.78 → 0.2.81

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.
Files changed (4) hide show
  1. package/dist/main.cjs +1814 -1799
  2. package/dist/main.css +3 -8
  3. package/dist/main.js +1827 -1812
  4. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1742,1058 +1742,692 @@ var TextField = forwardRef3(({
1742
1742
  TextField.displayName = "TextField";
1743
1743
 
1744
1744
  // lib/TextFields/AddressLookup.tsx
1745
- import React69, { useState as useState4, useRef as useRef3, useEffect as useEffect4 } from "react";
1745
+ import React70, { useState as useState5, useRef as useRef4, useEffect as useEffect5 } from "react";
1746
1746
  import Axios from "axios";
1747
1747
  import { Country, State, City } from "country-state-city";
1748
- var AddressLookup = ({
1749
- value = {},
1750
- onChange = () => {
1751
- },
1752
- label = "Address",
1753
- error = {},
1754
- size = "medium",
1755
- sx = {},
1756
- layout = "stack",
1757
- required = false,
1758
- token = ""
1759
- }) => {
1760
- const { theme } = useRufousTheme();
1761
- const [suggestions, setSuggestions] = useState4([]);
1762
- const [loading, setLoading] = useState4(false);
1763
- const [showSuggestions, setShowSuggestions] = useState4(false);
1764
- const [googleFields, setGoogleFields] = useState4({
1765
- country: false,
1766
- state: false,
1767
- city: false,
1768
- pincode: false
1769
- });
1770
- const debounceTimeout = useRef3(null);
1748
+
1749
+ // lib/TextFields/Autocomplete.tsx
1750
+ import React69, {
1751
+ useState as useState4,
1752
+ useRef as useRef3,
1753
+ useEffect as useEffect4,
1754
+ useCallback
1755
+ } from "react";
1756
+ import ReactDOM2 from "react-dom";
1757
+ var ChevronDownIcon = () => /* @__PURE__ */ React69.createElement("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React69.createElement("polyline", { points: "6 9 12 15 18 9" }));
1758
+ var CloseSmIcon = ({ size = 16 }) => /* @__PURE__ */ React69.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }, /* @__PURE__ */ React69.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), /* @__PURE__ */ React69.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" }));
1759
+ var CheckIcon = () => /* @__PURE__ */ React69.createElement("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React69.createElement("polyline", { points: "20 6 9 17 4 12" }));
1760
+ function defaultGetLabel(option) {
1761
+ if (option === null || option === void 0) return "";
1762
+ if (typeof option === "string") return option;
1763
+ if (typeof option === "object" && "label" in option)
1764
+ return String(option.label);
1765
+ return String(option);
1766
+ }
1767
+ function defaultFilter(options, inputValue, getLabel) {
1768
+ if (!inputValue) return options;
1769
+ const q = inputValue.toLowerCase();
1770
+ return options.filter((o) => getLabel(o).toLowerCase().includes(q));
1771
+ }
1772
+ function AutocompleteInner(props, _ref) {
1773
+ const {
1774
+ options,
1775
+ value,
1776
+ onChange,
1777
+ inputValue: controlledInput,
1778
+ onInputChange,
1779
+ getOptionLabel = defaultGetLabel,
1780
+ isOptionEqualToValue,
1781
+ groupBy,
1782
+ filterOptions,
1783
+ renderOption,
1784
+ getOptionDisabled,
1785
+ multiple = false,
1786
+ freeSolo = false,
1787
+ clearable = true,
1788
+ loading = false,
1789
+ loadingText = "Loading\u2026",
1790
+ noOptionsText = "No options",
1791
+ limitTags,
1792
+ label,
1793
+ placeholder,
1794
+ variant = "outlined",
1795
+ size = "medium",
1796
+ error = false,
1797
+ helperText,
1798
+ fullWidth = false,
1799
+ disabled = false,
1800
+ required = false,
1801
+ className = "",
1802
+ style,
1803
+ sx,
1804
+ onOpen,
1805
+ onClose
1806
+ } = props;
1807
+ const [open, setOpen] = useState4(false);
1808
+ const [inputStr, setInputStr] = useState4("");
1809
+ const [focusedIdx, setFocusedIdx] = useState4(-1);
1810
+ const [popupStyle, setPopupStyle] = useState4({});
1771
1811
  const containerRef = useRef3(null);
1772
- const apiKey = token || "";
1773
- const countries = Country.getAllCountries();
1774
- const [states, setStates] = useState4([]);
1775
- const [cities, setCities] = useState4([]);
1776
- useEffect4(() => {
1777
- const handleClickOutside = (event) => {
1778
- if (containerRef.current && !containerRef.current.contains(event.target)) {
1779
- setShowSuggestions(false);
1780
- }
1781
- };
1782
- document.addEventListener("mousedown", handleClickOutside);
1783
- return () => document.removeEventListener("mousedown", handleClickOutside);
1784
- }, []);
1785
- useEffect4(() => {
1786
- if (value.country || value.state || value.city || value.pincode) {
1787
- setGoogleFields({
1788
- country: !!value.country,
1789
- state: !!value.state,
1790
- city: !!value.city,
1791
- pincode: !!value.pincode
1812
+ const popupRef = useRef3(null);
1813
+ const inputRef = useRef3(null);
1814
+ const listRef = useRef3(null);
1815
+ const inputId = useRef3(`rf-ac-${Math.random().toString(36).slice(2, 9)}`).current;
1816
+ const sxClass = useSx(sx);
1817
+ const calcPopupStyle = useCallback(() => {
1818
+ if (!containerRef.current) return;
1819
+ const rect = containerRef.current.getBoundingClientRect();
1820
+ const POPUP_MAX_HEIGHT = 280;
1821
+ const GAP2 = 4;
1822
+ const viewportH = window.innerHeight;
1823
+ const viewportW = window.innerWidth;
1824
+ const spaceBelow = viewportH - rect.bottom - GAP2;
1825
+ const spaceAbove = rect.top - GAP2;
1826
+ const openUpward = spaceBelow < POPUP_MAX_HEIGHT && spaceAbove > spaceBelow;
1827
+ const minLeft = 8;
1828
+ const maxLeft = viewportW - rect.width - 8;
1829
+ const left = Math.min(Math.max(rect.left, minLeft), maxLeft);
1830
+ if (openUpward) {
1831
+ setPopupStyle({
1832
+ bottom: viewportH - rect.top + GAP2,
1833
+ top: "auto",
1834
+ left,
1835
+ width: rect.width
1836
+ });
1837
+ } else {
1838
+ setPopupStyle({
1839
+ top: rect.bottom + GAP2,
1840
+ bottom: "auto",
1841
+ left,
1842
+ width: rect.width
1792
1843
  });
1793
1844
  }
1794
1845
  }, []);
1795
- useEffect4(() => {
1796
- if (value.country) {
1797
- const country = countries.find((c) => c.name === value.country);
1798
- if (country) {
1799
- const stateList = State.getStatesOfCountry(country.isoCode);
1800
- setStates(stateList);
1801
- } else {
1802
- setStates([]);
1846
+ const activeInput = controlledInput !== void 0 ? controlledInput : inputStr;
1847
+ const selectedValues = multiple ? Array.isArray(value) ? value : [] : value != null ? [value] : [];
1848
+ const isEqual = useCallback(
1849
+ (a, b) => isOptionEqualToValue ? isOptionEqualToValue(a, b) : a === b,
1850
+ [isOptionEqualToValue]
1851
+ );
1852
+ const isSelected = useCallback(
1853
+ (opt) => selectedValues.some((v) => isEqual(opt, v)),
1854
+ [selectedValues, isEqual]
1855
+ );
1856
+ const filtered = filterOptions ? filterOptions(options, activeInput) : defaultFilter(options, activeInput, getOptionLabel);
1857
+ const flatEntries = [];
1858
+ if (groupBy) {
1859
+ const groups = {};
1860
+ const order = [];
1861
+ filtered.forEach((opt) => {
1862
+ const g = groupBy(opt);
1863
+ if (!groups[g]) {
1864
+ groups[g] = [];
1865
+ order.push(g);
1803
1866
  }
1804
- } else {
1805
- setStates([]);
1867
+ groups[g].push(opt);
1868
+ });
1869
+ order.forEach((g) => {
1870
+ flatEntries.push({ kind: "group", label: g });
1871
+ groups[g].forEach((opt) => {
1872
+ flatEntries.push({ kind: "option", option: opt, flatIdx: flatEntries.filter((e) => e.kind === "option").length });
1873
+ });
1874
+ });
1875
+ } else {
1876
+ filtered.forEach((opt, i) => flatEntries.push({ kind: "option", option: opt, flatIdx: i }));
1877
+ }
1878
+ const selectableOptions = flatEntries.filter((e) => e.kind === "option");
1879
+ const openPopup = useCallback(() => {
1880
+ if (disabled) return;
1881
+ calcPopupStyle();
1882
+ setOpen(true);
1883
+ setFocusedIdx(-1);
1884
+ onOpen?.();
1885
+ }, [disabled, calcPopupStyle, onOpen]);
1886
+ const closePopup = useCallback((justSelected = false) => {
1887
+ setOpen(false);
1888
+ setFocusedIdx(-1);
1889
+ onClose?.();
1890
+ if (!justSelected && !freeSolo && !multiple && value == null) {
1891
+ setInputStr("");
1892
+ onInputChange?.("");
1806
1893
  }
1807
- }, [value.country]);
1894
+ }, [freeSolo, multiple, value, onInputChange, onClose]);
1808
1895
  useEffect4(() => {
1809
- if (value.state && value.country) {
1810
- const country = countries.find((c) => c.name === value.country);
1811
- if (country) {
1812
- const state = State.getStatesOfCountry(country.isoCode).find((s2) => s2.name === value.state);
1813
- if (state) {
1814
- const cityList = City.getCitiesOfState(country.isoCode, state.isoCode);
1815
- setCities(cityList);
1816
- } else {
1817
- setCities([]);
1818
- }
1819
- } else {
1820
- setCities([]);
1896
+ if (!open) return;
1897
+ const handleOutside = (e) => {
1898
+ const target = e.target;
1899
+ const insideContainer = containerRef.current?.contains(target);
1900
+ const insidePopup = popupRef.current?.contains(target);
1901
+ if (!insideContainer && !insidePopup) {
1902
+ closePopup();
1821
1903
  }
1904
+ };
1905
+ document.addEventListener("mousedown", handleOutside);
1906
+ window.addEventListener("scroll", calcPopupStyle, true);
1907
+ window.addEventListener("resize", calcPopupStyle);
1908
+ return () => {
1909
+ document.removeEventListener("mousedown", handleOutside);
1910
+ window.removeEventListener("scroll", calcPopupStyle, true);
1911
+ window.removeEventListener("resize", calcPopupStyle);
1912
+ };
1913
+ }, [open, closePopup, calcPopupStyle]);
1914
+ useEffect4(() => {
1915
+ if (controlledInput !== void 0) return;
1916
+ if (!multiple) {
1917
+ const v = value;
1918
+ setInputStr(v != null ? getOptionLabel(v) : "");
1919
+ }
1920
+ }, [value, multiple, getOptionLabel, controlledInput]);
1921
+ const selectOption = (opt) => {
1922
+ if (getOptionDisabled?.(opt)) return;
1923
+ if (multiple) {
1924
+ const already = isSelected(opt);
1925
+ const next = already ? selectedValues.filter((v) => !isEqual(v, opt)) : [...selectedValues, opt];
1926
+ onChange?.(next);
1927
+ setInputStr("");
1928
+ onInputChange?.("");
1929
+ inputRef.current?.focus();
1822
1930
  } else {
1823
- setCities([]);
1931
+ onChange?.(opt);
1932
+ setInputStr(getOptionLabel(opt));
1933
+ onInputChange?.(getOptionLabel(opt));
1934
+ closePopup(true);
1824
1935
  }
1825
- }, [value.state, value.country]);
1826
- const handleChange = (field, newVal) => {
1827
- onChange({
1828
- ...value,
1829
- [field]: newVal
1830
- });
1936
+ setFocusedIdx(-1);
1831
1937
  };
1832
- const fetchPlaceDetails = async (placeId, mainText = "") => {
1833
- if (!apiKey) {
1834
- console.warn("Google Places API Key (token) is missing.");
1835
- return;
1836
- }
1837
- setLoading(true);
1838
- try {
1839
- const res = await Axios.get(
1840
- `https://places.googleapis.com/v1/places/${placeId}`,
1841
- {
1842
- headers: {
1843
- "Content-Type": "application/json",
1844
- "X-Goog-Api-Key": apiKey,
1845
- "X-Goog-FieldMask": "addressComponents,formattedAddress"
1846
- }
1847
- }
1848
- );
1849
- const comps = res.data.addressComponents || [];
1850
- const findComp = (type) => comps.find((c) => c.types.includes(type))?.longText || "";
1851
- const city = findComp("locality") || findComp("sublocality_level_1");
1852
- const state = findComp("administrative_area_level_1");
1853
- const country = findComp("country");
1854
- const pincode = findComp("postal_code");
1855
- setGoogleFields({
1856
- country: !!country,
1857
- state: !!state,
1858
- city: !!city,
1859
- pincode: !!pincode
1860
- });
1861
- const updatedData = {
1862
- ...value,
1863
- addressLine1: mainText || value.addressLine1,
1864
- addressLine2: res.data.formattedAddress || value.addressLine2,
1865
- city,
1866
- state,
1867
- country,
1868
- pincode
1869
- };
1870
- onChange(updatedData);
1871
- setShowSuggestions(false);
1872
- } catch (err) {
1873
- console.error("Error fetching place details:", err);
1874
- } finally {
1875
- setLoading(false);
1876
- }
1938
+ const clearAll = (e) => {
1939
+ e.stopPropagation();
1940
+ onChange?.(multiple ? [] : null);
1941
+ setInputStr("");
1942
+ onInputChange?.("");
1943
+ inputRef.current?.focus();
1877
1944
  };
1878
- const handleQuerySuggestions = async (query) => {
1879
- if (!apiKey || !query || query.length < 3) {
1880
- setSuggestions([]);
1881
- setShowSuggestions(false);
1882
- return;
1883
- }
1884
- setLoading(true);
1885
- try {
1886
- const res = await Axios.post(
1887
- `https://places.googleapis.com/v1/places:autocomplete`,
1888
- { input: query },
1889
- {
1890
- headers: {
1891
- "Content-Type": "application/json",
1892
- "X-Goog-Api-Key": apiKey
1893
- }
1894
- }
1895
- );
1896
- setSuggestions(res.data.suggestions || []);
1897
- setShowSuggestions(true);
1898
- } catch (err) {
1899
- console.error("Autocomplete Error:", err);
1900
- } finally {
1901
- setLoading(false);
1902
- }
1945
+ const removeTag = (opt, e) => {
1946
+ e.stopPropagation();
1947
+ const next = selectedValues.filter((v) => !isEqual(v, opt));
1948
+ onChange?.(next);
1903
1949
  };
1904
- const handleCountryChange = (newCountry) => {
1905
- onChange({
1906
- ...value,
1907
- country: newCountry,
1908
- state: "",
1909
- city: ""
1910
- });
1911
- setGoogleFields({ ...googleFields, country: false, state: false, city: false });
1950
+ const handleInputChange = (e) => {
1951
+ const v = e.target.value;
1952
+ setInputStr(v);
1953
+ onInputChange?.(v);
1954
+ if (!open) openPopup();
1912
1955
  };
1913
- const handleStateChange = (newState) => {
1914
- onChange({
1915
- ...value,
1916
- state: newState,
1917
- city: ""
1956
+ const handleKeyDown = (e) => {
1957
+ if (e.key === "ArrowDown") {
1958
+ e.preventDefault();
1959
+ if (!open) {
1960
+ openPopup();
1961
+ return;
1962
+ }
1963
+ setFocusedIdx((i) => {
1964
+ const next = (i + 1) % selectableOptions.length;
1965
+ scrollOptionIntoView(next);
1966
+ return next;
1967
+ });
1968
+ } else if (e.key === "ArrowUp") {
1969
+ e.preventDefault();
1970
+ if (!open) {
1971
+ openPopup();
1972
+ return;
1973
+ }
1974
+ setFocusedIdx((i) => {
1975
+ const next = (i - 1 + selectableOptions.length) % selectableOptions.length;
1976
+ scrollOptionIntoView(next);
1977
+ return next;
1978
+ });
1979
+ } else if (e.key === "Enter") {
1980
+ e.preventDefault();
1981
+ if (!open) {
1982
+ openPopup();
1983
+ return;
1984
+ }
1985
+ if (focusedIdx >= 0 && focusedIdx < selectableOptions.length) {
1986
+ selectOption(selectableOptions[focusedIdx].option);
1987
+ } else if (freeSolo && activeInput) {
1988
+ onChange?.(activeInput);
1989
+ if (!multiple) closePopup();
1990
+ }
1991
+ } else if (e.key === "Escape") {
1992
+ closePopup();
1993
+ } else if (e.key === "Backspace" && multiple && !activeInput && selectedValues.length > 0) {
1994
+ removeTag(selectedValues[selectedValues.length - 1], { stopPropagation: () => {
1995
+ } });
1996
+ }
1997
+ };
1998
+ const scrollOptionIntoView = (idx) => {
1999
+ requestAnimationFrame(() => {
2000
+ const el = listRef.current?.querySelector(`[data-idx="${idx}"]`);
2001
+ el?.scrollIntoView({ block: "nearest" });
1918
2002
  });
1919
2003
  };
1920
- return /* @__PURE__ */ React69.createElement("div", { className: "address-lookup-container", style: sx, ref: containerRef }, /* @__PURE__ */ React69.createElement("div", { className: `address-lookup-grid address-lookup-grid-${layout}` }, /* @__PURE__ */ React69.createElement("div", { className: "address-lookup-grid-item col-l1" }, /* @__PURE__ */ React69.createElement(
1921
- TextField,
1922
- {
1923
- label,
1924
- name: "addressLine1",
1925
- fullWidth: true,
1926
- value: value.addressLine1 || "",
1927
- required,
1928
- autoComplete: "off",
1929
- onChange: (e) => {
1930
- const val = e.target.value;
1931
- handleChange("addressLine1", val);
1932
- if (!val) {
1933
- onChange({
1934
- ...value,
1935
- addressLine1: "",
1936
- city: "",
1937
- state: "",
1938
- country: "",
1939
- pincode: ""
1940
- });
1941
- setSuggestions([]);
1942
- setShowSuggestions(false);
1943
- setGoogleFields({ country: false, state: false, city: false, pincode: false });
1944
- } else {
1945
- if (debounceTimeout.current) clearTimeout(debounceTimeout.current);
1946
- debounceTimeout.current = setTimeout(() => {
1947
- handleQuerySuggestions(val);
1948
- }, 500);
1949
- }
1950
- },
1951
- onFocus: () => suggestions.length > 0 && setShowSuggestions(true)
1952
- }
1953
- ), loading && /* @__PURE__ */ React69.createElement("div", { className: "loading-indicator" }, /* @__PURE__ */ React69.createElement(circularProgress_default, { size: 20 })), showSuggestions && suggestions.length > 0 && /* @__PURE__ */ React69.createElement("div", { className: "autocomplete-dropdown" }, suggestions.map((option, idx) => /* @__PURE__ */ React69.createElement(
2004
+ const hasClearable = clearable && !disabled && (multiple ? selectedValues.length > 0 : value != null);
2005
+ const visibleTags = multiple && limitTags != null ? selectedValues.slice(0, limitTags) : selectedValues;
2006
+ const hiddenCount = multiple && limitTags != null ? Math.max(0, selectedValues.length - limitTags) : 0;
2007
+ const isFloating = Boolean(
2008
+ open || activeInput || (multiple ? selectedValues.length > 0 : value != null)
2009
+ );
2010
+ const rootClasses = [
2011
+ "rf-text-field",
2012
+ `rf-text-field--${variant}`,
2013
+ `rf-text-field--${size}`,
2014
+ "rf-text-field--primary",
2015
+ error ? "rf-text-field--error" : "",
2016
+ fullWidth ? "rf-text-field--full-width" : "",
2017
+ disabled ? "rf-text-field--disabled" : "",
2018
+ isFloating ? "rf-text-field--floating" : "",
2019
+ label ? "rf-text-field--has-label" : "",
2020
+ "rf-text-field--adorned-end",
2021
+ "rf-autocomplete",
2022
+ sxClass,
2023
+ className
2024
+ ].filter(Boolean).join(" ");
2025
+ const inputPlaceholder = placeholder || (variant === "outlined" ? " " : void 0);
2026
+ return /* @__PURE__ */ React69.createElement("div", { ref: containerRef, className: rootClasses, style }, /* @__PURE__ */ React69.createElement(
1954
2027
  "div",
1955
2028
  {
1956
- key: idx,
1957
- className: "autocomplete-option",
2029
+ className: "rf-text-field__wrapper",
1958
2030
  onClick: () => {
1959
- const mainText = option?.placePrediction?.structuredFormat?.mainText?.text || "";
1960
- handleChange("addressLine1", mainText);
1961
- fetchPlaceDetails(option.placePrediction.placeId, mainText);
2031
+ if (!disabled) {
2032
+ inputRef.current?.focus();
2033
+ if (!open) openPopup();
2034
+ }
1962
2035
  }
1963
2036
  },
1964
- /* @__PURE__ */ React69.createElement("div", { className: "autocomplete-main-text" }, option?.placePrediction?.structuredFormat?.mainText?.text),
1965
- /* @__PURE__ */ React69.createElement("div", { className: "autocomplete-secondary-text" }, option?.placePrediction?.structuredFormat?.secondaryText?.text)
1966
- ))), error.addressLine1 && /* @__PURE__ */ React69.createElement("div", { className: "field-error-text" }, error.addressLine1)), layout === "compact" && /* @__PURE__ */ React69.createElement("div", { className: "address-lookup-grid-item col-l2" }, /* @__PURE__ */ React69.createElement(
1967
- TextField,
1968
- {
1969
- label: "Address Line 2",
1970
- name: "addressLine2",
1971
- fullWidth: true,
1972
- value: value.addressLine2 || "",
1973
- onChange: (e) => handleChange("addressLine2", e.target.value)
1974
- }
1975
- )), layout !== "compact" && /* @__PURE__ */ React69.createElement("div", { className: "address-lookup-grid-item col-l2" }, /* @__PURE__ */ React69.createElement(
1976
- TextField,
1977
- {
1978
- label: "Address Line 2",
1979
- name: "addressLine2",
1980
- fullWidth: true,
1981
- value: value.addressLine2 || "",
1982
- onChange: (e) => handleChange("addressLine2", e.target.value)
1983
- }
1984
- )), /* @__PURE__ */ React69.createElement("div", { className: "address-lookup-grid-item col-country" }, /* @__PURE__ */ React69.createElement(
1985
- TextField,
1986
- {
1987
- label: "Country",
1988
- name: "country",
1989
- fullWidth: true,
1990
- value: value.country || "",
1991
- required,
1992
- className: googleFields.country && value.country ? "field-disabled" : "",
1993
- readOnly: googleFields.country && !!value.country,
1994
- onChange: (e) => handleCountryChange(e.target.value),
1995
- list: "countries-list"
1996
- }
1997
- ), /* @__PURE__ */ React69.createElement("datalist", { id: "countries-list" }, countries.map((c) => /* @__PURE__ */ React69.createElement("option", { key: c.isoCode, value: c.name }))), error.country && /* @__PURE__ */ React69.createElement("div", { className: "field-error-text" }, error.country)), /* @__PURE__ */ React69.createElement("div", { className: "address-lookup-grid-item col-state" }, /* @__PURE__ */ React69.createElement(
1998
- TextField,
1999
- {
2000
- label: "State",
2001
- name: "state",
2002
- fullWidth: true,
2003
- value: value.state || "",
2004
- required,
2005
- disabled: !value.country,
2006
- className: googleFields.state && value.state ? "field-disabled" : "",
2007
- readOnly: googleFields.state && !!value.state,
2008
- onChange: (e) => handleStateChange(e.target.value),
2009
- list: "states-list"
2010
- }
2011
- ), /* @__PURE__ */ React69.createElement("datalist", { id: "states-list" }, states.map((s2) => /* @__PURE__ */ React69.createElement("option", { key: s2.isoCode, value: s2.name }))), error.state && /* @__PURE__ */ React69.createElement("div", { className: "field-error-text" }, error.state)), /* @__PURE__ */ React69.createElement("div", { className: "address-lookup-grid-item col-city" }, /* @__PURE__ */ React69.createElement(
2012
- TextField,
2013
- {
2014
- label: "City",
2015
- name: "city",
2016
- fullWidth: true,
2017
- value: value.city || "",
2018
- required,
2019
- disabled: !value.state,
2020
- className: googleFields.city && value.city ? "field-disabled" : "",
2021
- readOnly: googleFields.city && !!value.city,
2022
- onChange: (e) => handleChange("city", e.target.value),
2023
- list: "cities-list"
2024
- }
2025
- ), /* @__PURE__ */ React69.createElement("datalist", { id: "cities-list" }, cities.map((c, i) => /* @__PURE__ */ React69.createElement("option", { key: i, value: c.name }))), error.city && /* @__PURE__ */ React69.createElement("div", { className: "field-error-text" }, error.city)), /* @__PURE__ */ React69.createElement("div", { className: "address-lookup-grid-item col-pin" }, /* @__PURE__ */ React69.createElement(
2026
- TextField,
2027
- {
2028
- label: "Pincode",
2029
- name: "pincode",
2030
- fullWidth: true,
2031
- value: value.pincode || "",
2032
- required,
2033
- className: googleFields.pincode && value.pincode ? "field-disabled" : "",
2034
- readOnly: googleFields.pincode && !!value.pincode,
2035
- onChange: (e) => handleChange("pincode", e.target.value)
2036
- }
2037
- ), error.pincode && /* @__PURE__ */ React69.createElement("div", { className: "field-error-text" }, error.pincode))));
2038
- };
2039
- var AddressLookup_default = AddressLookup;
2040
-
2041
- // lib/TextFields/DateField.tsx
2042
- import React70, {
2043
- useState as useState5,
2044
- useRef as useRef4,
2045
- useEffect as useEffect5,
2046
- useCallback
2047
- } from "react";
2048
- import { createPortal } from "react-dom";
2049
- var WEEKDAYS = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"];
2050
- var MONTHS = [
2051
- "January",
2052
- "February",
2053
- "March",
2054
- "April",
2055
- "May",
2056
- "June",
2057
- "July",
2058
- "August",
2059
- "September",
2060
- "October",
2061
- "November",
2062
- "December"
2063
- ];
2064
- var MONTHS_SHORT = [
2065
- "Jan",
2066
- "Feb",
2067
- "Mar",
2068
- "Apr",
2069
- "May",
2070
- "Jun",
2071
- "Jul",
2072
- "Aug",
2073
- "Sep",
2074
- "Oct",
2075
- "Nov",
2076
- "Dec"
2077
- ];
2078
- var formatDisplay = (d, fmt = "MM/DD/YYYY") => {
2079
- const mm = String(d.getMonth() + 1).padStart(2, "0");
2080
- const dd = String(d.getDate()).padStart(2, "0");
2081
- const yyyy = String(d.getFullYear());
2082
- const day = d.getDate();
2083
- switch (fmt) {
2084
- case "DD/MM/YYYY":
2085
- return `${dd}/${mm}/${yyyy}`;
2086
- case "YYYY-MM-DD":
2087
- return `${yyyy}-${mm}-${dd}`;
2088
- case "DD-MM-YYYY":
2089
- return `${dd}-${mm}-${yyyy}`;
2090
- case "MM-DD-YYYY":
2091
- return `${mm}-${dd}-${yyyy}`;
2092
- case "YYYY/MM/DD":
2093
- return `${yyyy}/${mm}/${dd}`;
2094
- case "DD MMM YYYY":
2095
- return `${dd} ${MONTHS_SHORT[d.getMonth()]} ${yyyy}`;
2096
- case "MMM DD, YYYY":
2097
- return `${MONTHS_SHORT[d.getMonth()]} ${dd}, ${yyyy}`;
2098
- case "DD MMMM YYYY":
2099
- return `${dd} ${MONTHS[d.getMonth()]} ${yyyy}`;
2100
- case "MMMM DD, YYYY":
2101
- return `${MONTHS[d.getMonth()]} ${dd}, ${yyyy}`;
2102
- case "MM/DD/YYYY":
2103
- default:
2104
- return `${mm}/${dd}/${yyyy}`;
2105
- }
2106
- };
2107
- var formatTimeDisplay = (h, m, ampm) => `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")} ${ampm}`;
2108
- var parseMonthName = (name) => {
2109
- const lower = name.toLowerCase();
2110
- let idx = MONTHS.findIndex((m) => m.toLowerCase() === lower);
2111
- if (idx >= 0) return idx;
2112
- idx = MONTHS_SHORT.findIndex((m) => m.toLowerCase() === lower);
2113
- return idx;
2114
- };
2115
- var parseDisplay = (str, fmt = "MM/DD/YYYY") => {
2116
- if (fmt === "DD MMM YYYY" || fmt === "DD MMMM YYYY") {
2117
- const parts2 = str.split(" ");
2118
- if (parts2.length !== 3) return null;
2119
- const dd2 = parseInt(parts2[0], 10);
2120
- const mm2 = parseMonthName(parts2[1]);
2121
- const yyyy2 = parseInt(parts2[2], 10);
2122
- if (isNaN(dd2) || mm2 < 0 || isNaN(yyyy2) || yyyy2 < 1e3) return null;
2123
- const d2 = new Date(yyyy2, mm2, dd2);
2124
- return isNaN(d2.getTime()) ? null : d2;
2125
- }
2126
- if (fmt === "MMM DD, YYYY" || fmt === "MMMM DD, YYYY") {
2127
- const cleaned = str.replace(",", "");
2128
- const parts2 = cleaned.split(" ").filter(Boolean);
2129
- if (parts2.length !== 3) return null;
2130
- const mm2 = parseMonthName(parts2[0]);
2131
- const dd2 = parseInt(parts2[1], 10);
2132
- const yyyy2 = parseInt(parts2[2], 10);
2133
- if (mm2 < 0 || isNaN(dd2) || isNaN(yyyy2) || yyyy2 < 1e3) return null;
2134
- const d2 = new Date(yyyy2, mm2, dd2);
2135
- return isNaN(d2.getTime()) ? null : d2;
2136
- }
2137
- const sep = str.includes("/") ? "/" : "-";
2138
- const parts = str.split(sep);
2139
- if (parts.length !== 3) return null;
2140
- const nums = parts.map(Number);
2141
- let yyyy, mm, dd;
2142
- switch (fmt) {
2143
- case "DD/MM/YYYY":
2144
- case "DD-MM-YYYY":
2145
- [dd, mm, yyyy] = nums;
2146
- break;
2147
- case "YYYY-MM-DD":
2148
- case "YYYY/MM/DD":
2149
- [yyyy, mm, dd] = nums;
2150
- break;
2151
- case "MM-DD-YYYY":
2152
- case "MM/DD/YYYY":
2153
- default:
2154
- [mm, dd, yyyy] = nums;
2155
- break;
2037
+ multiple && visibleTags.map((opt, i) => /* @__PURE__ */ React69.createElement("span", { key: i, className: "rf-autocomplete__tag" }, /* @__PURE__ */ React69.createElement("span", { style: { overflow: "hidden", textOverflow: "ellipsis" } }, getOptionLabel(opt)), /* @__PURE__ */ React69.createElement(
2038
+ "button",
2039
+ {
2040
+ type: "button",
2041
+ className: "rf-autocomplete__tag-delete",
2042
+ onMouseDown: (e) => e.preventDefault(),
2043
+ onClick: (e) => removeTag(opt, e),
2044
+ tabIndex: -1
2045
+ },
2046
+ /* @__PURE__ */ React69.createElement(CloseSmIcon, { size: 12 })
2047
+ ))),
2048
+ hiddenCount > 0 && /* @__PURE__ */ React69.createElement("span", { className: "rf-autocomplete__tag-more" }, "+", hiddenCount, " more"),
2049
+ /* @__PURE__ */ React69.createElement(
2050
+ "input",
2051
+ {
2052
+ ref: inputRef,
2053
+ id: inputId,
2054
+ className: "rf-text-field__input",
2055
+ type: "text",
2056
+ value: activeInput,
2057
+ onChange: handleInputChange,
2058
+ onFocus: () => {
2059
+ if (!open) openPopup();
2060
+ },
2061
+ onKeyDown: handleKeyDown,
2062
+ placeholder: !multiple || selectedValues.length === 0 ? inputPlaceholder : void 0,
2063
+ disabled,
2064
+ autoComplete: "off",
2065
+ role: "combobox",
2066
+ "aria-expanded": open,
2067
+ "aria-haspopup": "listbox",
2068
+ "aria-autocomplete": "list"
2069
+ }
2070
+ ),
2071
+ label && /* @__PURE__ */ React69.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, required && /* @__PURE__ */ React69.createElement("span", { className: "rf-text-field__asterisk" }, " *")),
2072
+ variant === "outlined" && /* @__PURE__ */ React69.createElement("fieldset", { className: "rf-text-field__notch" }, label ? /* @__PURE__ */ React69.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ React69.createElement("span", null, label, required ? " *" : "")) : /* @__PURE__ */ React69.createElement("legend", { className: "rf-text-field__legend--empty" })),
2073
+ /* @__PURE__ */ React69.createElement("div", { className: "rf-autocomplete__endgroup" }, hasClearable && /* @__PURE__ */ React69.createElement(
2074
+ "button",
2075
+ {
2076
+ type: "button",
2077
+ className: "rf-autocomplete__icon-btn",
2078
+ onMouseDown: (e) => e.preventDefault(),
2079
+ onClick: clearAll,
2080
+ tabIndex: -1,
2081
+ "aria-label": "Clear"
2082
+ },
2083
+ /* @__PURE__ */ React69.createElement(CloseSmIcon, { size: 16 })
2084
+ ), !freeSolo && /* @__PURE__ */ React69.createElement(
2085
+ "button",
2086
+ {
2087
+ type: "button",
2088
+ className: `rf-autocomplete__icon-btn rf-autocomplete__icon-btn--popup ${open ? "rf-autocomplete__icon-btn--open" : ""}`,
2089
+ onMouseDown: (e) => {
2090
+ e.preventDefault();
2091
+ open ? closePopup() : openPopup();
2092
+ },
2093
+ tabIndex: -1,
2094
+ "aria-label": open ? "Close" : "Open"
2095
+ },
2096
+ /* @__PURE__ */ React69.createElement(ChevronDownIcon, null)
2097
+ ))
2098
+ ), helperText && /* @__PURE__ */ React69.createElement("div", { className: `rf-text-field__helper-text${error ? " rf-text-field__helper-text--error" : ""}` }, helperText), open && !disabled && ReactDOM2.createPortal(
2099
+ /* @__PURE__ */ React69.createElement("div", { ref: popupRef, className: "rf-autocomplete__popup", role: "presentation", style: popupStyle }, loading ? /* @__PURE__ */ React69.createElement("div", { className: "rf-autocomplete__loading" }, /* @__PURE__ */ React69.createElement("span", { className: "rf-ac-spinner" }), loadingText) : flatEntries.length === 0 ? /* @__PURE__ */ React69.createElement("div", { className: "rf-autocomplete__no-options" }, noOptionsText) : /* @__PURE__ */ React69.createElement("ul", { ref: listRef, className: "rf-autocomplete__listbox", role: "listbox" }, groupBy ? (
2100
+ // Grouped render
2101
+ (() => {
2102
+ const rendered = [];
2103
+ let groupItems = [];
2104
+ let currentGroup = "";
2105
+ flatEntries.forEach((entry, ei) => {
2106
+ if (entry.kind === "group") {
2107
+ if (groupItems.length > 0) {
2108
+ rendered.push(
2109
+ /* @__PURE__ */ React69.createElement("li", { key: `g-${currentGroup}`, role: "presentation" }, /* @__PURE__ */ React69.createElement("div", { className: "rf-autocomplete__group-header" }, currentGroup), /* @__PURE__ */ React69.createElement("ul", { className: "rf-autocomplete__group-items", role: "group" }, groupItems))
2110
+ );
2111
+ groupItems = [];
2112
+ }
2113
+ currentGroup = entry.label;
2114
+ } else {
2115
+ const { option, flatIdx } = entry;
2116
+ groupItems.push(renderOptionItem(option, flatIdx));
2117
+ }
2118
+ if (ei === flatEntries.length - 1 && groupItems.length > 0) {
2119
+ rendered.push(
2120
+ /* @__PURE__ */ React69.createElement("li", { key: `g-${currentGroup}`, role: "presentation" }, /* @__PURE__ */ React69.createElement("div", { className: "rf-autocomplete__group-header" }, currentGroup), /* @__PURE__ */ React69.createElement("ul", { className: "rf-autocomplete__group-items", role: "group" }, groupItems))
2121
+ );
2122
+ }
2123
+ });
2124
+ return rendered;
2125
+ })()
2126
+ ) : selectableOptions.map(({ option, flatIdx }) => renderOptionItem(option, flatIdx)))),
2127
+ document.body
2128
+ ));
2129
+ function renderOptionItem(option, flatIdx) {
2130
+ const selected = isSelected(option);
2131
+ const focused = focusedIdx === flatIdx;
2132
+ const optDisabled = getOptionDisabled?.(option) ?? false;
2133
+ const label2 = getOptionLabel(option);
2134
+ return /* @__PURE__ */ React69.createElement(
2135
+ "li",
2136
+ {
2137
+ key: label2 + flatIdx,
2138
+ "data-idx": flatIdx,
2139
+ role: "option",
2140
+ "aria-selected": selected,
2141
+ "aria-disabled": optDisabled,
2142
+ className: [
2143
+ "rf-autocomplete__option",
2144
+ selected ? "rf-autocomplete__option--selected" : "",
2145
+ focused ? "rf-autocomplete__option--focused" : "",
2146
+ optDisabled ? "rf-autocomplete__option--disabled" : ""
2147
+ ].filter(Boolean).join(" "),
2148
+ onMouseEnter: () => setFocusedIdx(flatIdx),
2149
+ onMouseLeave: () => setFocusedIdx(-1),
2150
+ onMouseDown: (e) => e.preventDefault(),
2151
+ onClick: () => selectOption(option)
2152
+ },
2153
+ renderOption ? renderOption(option, { selected, focused, index: flatIdx }) : /* @__PURE__ */ React69.createElement("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, label2),
2154
+ !renderOption && /* @__PURE__ */ React69.createElement("span", { className: "rf-autocomplete__option-check" }, /* @__PURE__ */ React69.createElement(CheckIcon, null))
2155
+ );
2156
2156
  }
2157
- if (!mm || !dd || !yyyy || yyyy < 1e3) return null;
2158
- const d = new Date(yyyy, mm - 1, dd);
2159
- if (isNaN(d.getTime())) return null;
2160
- return d;
2161
- };
2162
- var isoToDate = (iso) => {
2163
- if (!iso) return null;
2164
- const [datePart] = iso.split("T");
2165
- const [y, mo, d] = datePart.split("-").map(Number);
2166
- if (!y || !mo || !d) return null;
2167
- return new Date(y, mo - 1, d);
2168
- };
2169
- var today = () => {
2170
- const t = /* @__PURE__ */ new Date();
2171
- return new Date(t.getFullYear(), t.getMonth(), t.getDate());
2172
- };
2173
- var isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
2174
- var isDatetimeType = (t) => t !== "date";
2175
- var buildISO = (date, type, hour, minute, ampm) => {
2176
- const y = date.getFullYear();
2177
- const mo = String(date.getMonth() + 1).padStart(2, "0");
2178
- const d = String(date.getDate()).padStart(2, "0");
2179
- if (type === "date") return `${y}-${mo}-${d}`;
2180
- let h24 = hour % 12;
2181
- if (ampm === "PM") h24 += 12;
2182
- return `${y}-${mo}-${d}T${String(h24).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
2183
- };
2184
- var parseTimeFromISO = (iso) => {
2185
- const timePart = iso.split("T")[1] || "";
2186
- const [hStr, mStr] = timePart.split(":");
2187
- let h24 = parseInt(hStr, 10) || 0;
2188
- const m = parseInt(mStr, 10) || 0;
2189
- const ampm = h24 < 12 ? "AM" : "PM";
2190
- let h = h24 % 12;
2191
- if (h === 0) h = 12;
2192
- return { h, m, ampm };
2193
- };
2194
- var CalendarIcon = () => /* @__PURE__ */ React70.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React70.createElement("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2", ry: "2" }), /* @__PURE__ */ React70.createElement("line", { x1: "16", y1: "2", x2: "16", y2: "6" }), /* @__PURE__ */ React70.createElement("line", { x1: "8", y1: "2", x2: "8", y2: "6" }), /* @__PURE__ */ React70.createElement("line", { x1: "3", y1: "10", x2: "21", y2: "10" }));
2195
- var ChevUp = () => /* @__PURE__ */ React70.createElement("svg", { width: "10", height: "7", viewBox: "0 0 10 7", fill: "currentColor" }, /* @__PURE__ */ React70.createElement("path", { d: "M5 0L10 7H0L5 0Z" }));
2196
- var ChevDown = () => /* @__PURE__ */ React70.createElement("svg", { width: "10", height: "7", viewBox: "0 0 10 7", fill: "currentColor" }, /* @__PURE__ */ React70.createElement("path", { d: "M5 7L0 0H10L5 7Z" }));
2197
- var ITEM_H = 36;
2198
- var ScrollColumn = ({ items, selected, onSelect, infinite = true }) => {
2199
- const listRef = useRef4(null);
2200
- const isInternalScroll = useRef4(false);
2201
- const scrollTimeout = useRef4(null);
2202
- const MULTIPLIER = infinite ? 100 : 1;
2203
- const virtualItems = infinite ? Array(MULTIPLIER).fill(items).flat() : items;
2204
- const centerOffset = infinite ? Math.floor(MULTIPLIER / 2) * items.length : 0;
2205
- const VISUAL_OFFSET = 54;
2157
+ }
2158
+ var Autocomplete = React69.forwardRef(AutocompleteInner);
2159
+ Autocomplete.displayName = "Autocomplete";
2160
+
2161
+ // lib/TextFields/AddressLookup.tsx
2162
+ var AddressLookup = ({
2163
+ value = {},
2164
+ onChange = () => {
2165
+ },
2166
+ label = "Address",
2167
+ error = {},
2168
+ size = "medium",
2169
+ sx = {},
2170
+ layout = "stack",
2171
+ required = false,
2172
+ token = ""
2173
+ }) => {
2174
+ const { theme } = useRufousTheme();
2175
+ const [suggestions, setSuggestions] = useState5([]);
2176
+ const [loading, setLoading] = useState5(false);
2177
+ const [showSuggestions, setShowSuggestions] = useState5(false);
2178
+ const debounceTimeout = useRef4(null);
2179
+ const containerRef = useRef4(null);
2180
+ const apiKey = token || "";
2181
+ const countries = Country.getAllCountries();
2182
+ const [states, setStates] = useState5([]);
2183
+ const [cities, setCities] = useState5([]);
2206
2184
  useEffect5(() => {
2207
- if (listRef.current) {
2208
- const targetIndex = centerOffset + selected;
2209
- listRef.current.scrollTop = targetIndex * ITEM_H - (infinite ? VISUAL_OFFSET : 0);
2210
- }
2211
- }, [centerOffset, infinite, selected]);
2185
+ const handleClickOutside = (event) => {
2186
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
2187
+ setShowSuggestions(false);
2188
+ }
2189
+ };
2190
+ document.addEventListener("mousedown", handleClickOutside);
2191
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2192
+ }, []);
2212
2193
  useEffect5(() => {
2213
- if (listRef.current && !isInternalScroll.current) {
2214
- const targetIndex = centerOffset + selected;
2215
- listRef.current.scrollTo({
2216
- top: targetIndex * ITEM_H - (infinite ? VISUAL_OFFSET : 0),
2217
- behavior: "smooth"
2218
- });
2219
- }
2220
- isInternalScroll.current = false;
2221
- }, [selected, centerOffset, infinite]);
2222
- const handleScroll = () => {
2223
- if (!listRef.current) return;
2224
- const scrollTop = listRef.current.scrollTop;
2225
- const adjustedScrollTop = infinite ? scrollTop + VISUAL_OFFSET : scrollTop;
2226
- const index = Math.round(adjustedScrollTop / ITEM_H);
2227
- const actualIndex = infinite ? (index % items.length + items.length) % items.length : Math.max(0, Math.min(items.length - 1, index));
2228
- if (infinite) {
2229
- const buffer = items.length * 10;
2230
- if (index < buffer || index > virtualItems.length - buffer) {
2231
- const newIndex = centerOffset + actualIndex;
2232
- listRef.current.scrollTop = newIndex * ITEM_H - VISUAL_OFFSET;
2233
- return;
2194
+ if (value.country) {
2195
+ const country = countries.find((c) => c.name === value.country);
2196
+ if (country) {
2197
+ const stateList = State.getStatesOfCountry(country.isoCode);
2198
+ setStates(stateList);
2199
+ } else {
2200
+ setStates([]);
2234
2201
  }
2202
+ } else {
2203
+ setStates([]);
2235
2204
  }
2236
- if (scrollTimeout.current) clearTimeout(scrollTimeout.current);
2237
- scrollTimeout.current = setTimeout(() => {
2238
- if (actualIndex !== selected) {
2239
- isInternalScroll.current = true;
2240
- onSelect(actualIndex);
2205
+ }, [value.country]);
2206
+ useEffect5(() => {
2207
+ if (value.state && value.country) {
2208
+ const country = countries.find((c) => c.name === value.country);
2209
+ if (country) {
2210
+ const state = State.getStatesOfCountry(country.isoCode).find((s2) => s2.name === value.state);
2211
+ if (state) {
2212
+ const cityList = City.getCitiesOfState(country.isoCode, state.isoCode);
2213
+ setCities(cityList);
2214
+ } else {
2215
+ setCities([]);
2216
+ }
2217
+ } else {
2218
+ setCities([]);
2241
2219
  }
2242
- }, 100);
2243
- };
2244
- return /* @__PURE__ */ React70.createElement("div", { className: "rf-timescroll__col-wrapper" }, /* @__PURE__ */ React70.createElement(
2245
- "div",
2246
- {
2247
- className: "rf-timescroll__col",
2248
- ref: listRef,
2249
- onScroll: handleScroll
2250
- },
2251
- !infinite && /* @__PURE__ */ React70.createElement("div", { className: "rf-timescroll__spacer" }),
2252
- virtualItems.map((label, idx) => /* @__PURE__ */ React70.createElement(
2253
- "div",
2254
- {
2255
- key: `${label}-${idx}`,
2256
- className: `rf-timescroll__item ${idx % items.length === selected ? "rf-timescroll__item--active" : ""}`
2257
- },
2258
- label
2259
- )),
2260
- !infinite && /* @__PURE__ */ React70.createElement("div", { className: "rf-timescroll__spacer" })
2261
- ), /* @__PURE__ */ React70.createElement("div", { className: "rf-timescroll__mask rf-timescroll__mask--top" }), /* @__PURE__ */ React70.createElement("div", { className: "rf-timescroll__mask rf-timescroll__mask--bottom" }));
2262
- };
2263
- var SpinnerPanel = ({
2264
- hour,
2265
- minute,
2266
- ampm,
2267
- onHourChange,
2268
- onMinuteChange,
2269
- onHourInput,
2270
- onMinuteInput,
2271
- onAmpmToggle
2272
- }) => /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__time-row" }, /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__time-input-wrap" }, /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__time-spin-btn", onMouseDown: (e) => e.preventDefault(), onClick: () => onHourChange(1) }, /* @__PURE__ */ React70.createElement(ChevUp, null)), /* @__PURE__ */ React70.createElement(
2273
- "input",
2274
- {
2275
- type: "number",
2276
- className: "rf-date-picker__time-digit",
2277
- value: String(hour).padStart(2, "0"),
2278
- min: 1,
2279
- max: 12,
2280
- onChange: onHourInput,
2281
- onMouseDown: (e) => e.stopPropagation()
2282
- }
2283
- ), /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__time-spin-btn", onMouseDown: (e) => e.preventDefault(), onClick: () => onHourChange(-1) }, /* @__PURE__ */ React70.createElement(ChevDown, null))), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__time-colon" }, ":"), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__time-input-wrap" }, /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__time-spin-btn", onMouseDown: (e) => e.preventDefault(), onClick: () => onMinuteChange(1) }, /* @__PURE__ */ React70.createElement(ChevUp, null)), /* @__PURE__ */ React70.createElement(
2284
- "input",
2285
- {
2286
- type: "number",
2287
- className: "rf-date-picker__time-digit",
2288
- value: String(minute).padStart(2, "0"),
2289
- min: 0,
2290
- max: 59,
2291
- onChange: onMinuteInput,
2292
- onMouseDown: (e) => e.stopPropagation()
2293
- }
2294
- ), /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__time-spin-btn", onMouseDown: (e) => e.preventDefault(), onClick: () => onMinuteChange(-1) }, /* @__PURE__ */ React70.createElement(ChevDown, null))), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__ampm" }, /* @__PURE__ */ React70.createElement(
2295
- "button",
2296
- {
2297
- type: "button",
2298
- className: `rf-date-picker__ampm-btn ${ampm === "AM" ? "rf-date-picker__ampm-btn--active" : ""}`,
2299
- onMouseDown: (e) => e.preventDefault(),
2300
- onClick: () => onAmpmToggle("AM")
2301
- },
2302
- "AM"
2303
- ), /* @__PURE__ */ React70.createElement(
2304
- "button",
2305
- {
2306
- type: "button",
2307
- className: `rf-date-picker__ampm-btn ${ampm === "PM" ? "rf-date-picker__ampm-btn--active" : ""}`,
2308
- onMouseDown: (e) => e.preventDefault(),
2309
- onClick: () => onAmpmToggle("PM")
2310
- },
2311
- "PM"
2312
- )));
2313
- var CalendarBody = ({
2314
- viewMonth,
2315
- viewYear,
2316
- selectedDate,
2317
- todayDate,
2318
- dayCells,
2319
- onDayClick,
2320
- onPrev,
2321
- onNext,
2322
- onMonthSelect,
2323
- onYearSelect
2324
- }) => {
2325
- const [pickerView, setPickerView] = useState5("calendar");
2326
- const handleMonthClick = () => {
2327
- setPickerView(pickerView === "month" ? "calendar" : "month");
2220
+ } else {
2221
+ setCities([]);
2222
+ }
2223
+ }, [value.state, value.country]);
2224
+ const handleChange = (field, newVal) => {
2225
+ onChange({
2226
+ ...value,
2227
+ [field]: newVal
2228
+ });
2328
2229
  };
2329
- const handleYearClick = () => {
2330
- setPickerView(pickerView === "year" ? "calendar" : "year");
2230
+ const fetchPlaceDetails = async (placeId, mainText = "") => {
2231
+ if (!apiKey) {
2232
+ console.warn("Google Places API Key (token) is missing.");
2233
+ return;
2234
+ }
2235
+ setLoading(true);
2236
+ try {
2237
+ const res = await Axios.get(
2238
+ `https://places.googleapis.com/v1/places/${placeId}`,
2239
+ {
2240
+ headers: {
2241
+ "Content-Type": "application/json",
2242
+ "X-Goog-Api-Key": apiKey,
2243
+ "X-Goog-FieldMask": "addressComponents,formattedAddress"
2244
+ }
2245
+ }
2246
+ );
2247
+ const comps = res.data.addressComponents || [];
2248
+ const findComp = (type) => comps.find((c) => c.types.includes(type))?.longText || "";
2249
+ const city = findComp("locality") || findComp("sublocality_level_1");
2250
+ const state = findComp("administrative_area_level_1");
2251
+ const country = findComp("country");
2252
+ const pincode = findComp("postal_code");
2253
+ const updatedData = {
2254
+ ...value,
2255
+ addressLine1: mainText || value.addressLine1,
2256
+ addressLine2: res.data.formattedAddress || value.addressLine2,
2257
+ city,
2258
+ state,
2259
+ country,
2260
+ pincode
2261
+ };
2262
+ onChange(updatedData);
2263
+ setShowSuggestions(false);
2264
+ } catch (err) {
2265
+ console.error("Error fetching place details:", err);
2266
+ } finally {
2267
+ setLoading(false);
2268
+ }
2331
2269
  };
2332
- const handleMonthPick = (month) => {
2333
- onMonthSelect(month);
2334
- setPickerView("calendar");
2270
+ const handleQuerySuggestions = async (query) => {
2271
+ if (!apiKey || !query || query.length < 3) {
2272
+ setSuggestions([]);
2273
+ setShowSuggestions(false);
2274
+ return;
2275
+ }
2276
+ setLoading(true);
2277
+ try {
2278
+ const res = await Axios.post(
2279
+ `https://places.googleapis.com/v1/places:autocomplete`,
2280
+ { input: query },
2281
+ {
2282
+ headers: {
2283
+ "Content-Type": "application/json",
2284
+ "X-Goog-Api-Key": apiKey
2285
+ }
2286
+ }
2287
+ );
2288
+ setSuggestions(res.data.suggestions || []);
2289
+ setShowSuggestions(true);
2290
+ } catch (err) {
2291
+ console.error("Autocomplete Error:", err);
2292
+ } finally {
2293
+ setLoading(false);
2294
+ }
2335
2295
  };
2336
- const handleYearPick = (year) => {
2337
- onYearSelect(year);
2338
- setPickerView("calendar");
2296
+ const handleCountryChange = (newCountry) => {
2297
+ onChange({
2298
+ ...value,
2299
+ country: newCountry,
2300
+ state: "",
2301
+ city: ""
2302
+ });
2339
2303
  };
2340
- const currentYear = todayDate.getFullYear();
2341
- const yearStart = viewYear - 6;
2342
- const years = Array.from({ length: 16 }, (_, i) => yearStart + i);
2343
- return /* @__PURE__ */ React70.createElement(React70.Fragment, null, /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__header" }, /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__header-labels" }, /* @__PURE__ */ React70.createElement(
2344
- "span",
2304
+ const handleStateChange = (newState) => {
2305
+ onChange({
2306
+ ...value,
2307
+ state: newState,
2308
+ city: ""
2309
+ });
2310
+ };
2311
+ return /* @__PURE__ */ React70.createElement("div", { className: "address-lookup-container", style: sx, ref: containerRef }, /* @__PURE__ */ React70.createElement("div", { className: `address-lookup-grid address-lookup-grid-${layout}` }, /* @__PURE__ */ React70.createElement("div", { className: "address-lookup-grid-item col-l1" }, /* @__PURE__ */ React70.createElement(
2312
+ TextField,
2345
2313
  {
2346
- className: `rf-date-picker__month-label ${pickerView === "month" ? "rf-date-picker__month-label--active" : ""}`,
2347
- onClick: handleMonthClick
2348
- },
2349
- MONTHS[viewMonth]
2350
- ), /* @__PURE__ */ React70.createElement(
2351
- "span",
2314
+ label,
2315
+ name: "addressLine1",
2316
+ fullWidth: true,
2317
+ value: value.addressLine1 || "",
2318
+ required,
2319
+ autoComplete: "off",
2320
+ onChange: (e) => {
2321
+ const val = e.target.value;
2322
+ handleChange("addressLine1", val);
2323
+ if (!val) {
2324
+ onChange({
2325
+ ...value,
2326
+ addressLine1: "",
2327
+ city: "",
2328
+ state: "",
2329
+ country: "",
2330
+ pincode: ""
2331
+ });
2332
+ setSuggestions([]);
2333
+ setShowSuggestions(false);
2334
+ } else {
2335
+ if (debounceTimeout.current) clearTimeout(debounceTimeout.current);
2336
+ debounceTimeout.current = setTimeout(() => {
2337
+ handleQuerySuggestions(val);
2338
+ }, 500);
2339
+ }
2340
+ },
2341
+ onFocus: () => suggestions.length > 0 && setShowSuggestions(true)
2342
+ }
2343
+ ), loading && /* @__PURE__ */ React70.createElement("div", { className: "loading-indicator" }, /* @__PURE__ */ React70.createElement(circularProgress_default, { size: 20 })), showSuggestions && suggestions.length > 0 && /* @__PURE__ */ React70.createElement("div", { className: "autocomplete-dropdown" }, suggestions.map((option, idx) => /* @__PURE__ */ React70.createElement(
2344
+ "div",
2352
2345
  {
2353
- className: `rf-date-picker__year-label ${pickerView === "year" ? "rf-date-picker__year-label--active" : ""}`,
2354
- onClick: handleYearClick
2346
+ key: idx,
2347
+ className: "autocomplete-option",
2348
+ onClick: () => {
2349
+ const mainText = option?.placePrediction?.structuredFormat?.mainText?.text || "";
2350
+ handleChange("addressLine1", mainText);
2351
+ fetchPlaceDetails(option.placePrediction.placeId, mainText);
2352
+ }
2355
2353
  },
2356
- viewYear
2357
- )), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__nav" }, pickerView === "year" ? /* @__PURE__ */ React70.createElement(React70.Fragment, null, /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear - 16), "aria-label": "Previous years" }, "\u2039"), /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear + 16), "aria-label": "Next years" }, "\u203A")) : /* @__PURE__ */ React70.createElement(React70.Fragment, null, /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: onPrev, "aria-label": "Previous month" }, "\u2039"), /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: onNext, "aria-label": "Next month" }, "\u203A")))), pickerView === "month" && /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__month-grid" }, MONTHS_SHORT.map((m, idx) => /* @__PURE__ */ React70.createElement(
2358
- "button",
2354
+ /* @__PURE__ */ React70.createElement("div", { className: "autocomplete-main-text" }, option?.placePrediction?.structuredFormat?.mainText?.text),
2355
+ /* @__PURE__ */ React70.createElement("div", { className: "autocomplete-secondary-text" }, option?.placePrediction?.structuredFormat?.secondaryText?.text)
2356
+ ))), error.addressLine1 && /* @__PURE__ */ React70.createElement("div", { className: "field-error-text" }, error.addressLine1)), layout === "compact" && /* @__PURE__ */ React70.createElement("div", { className: "address-lookup-grid-item col-l2" }, /* @__PURE__ */ React70.createElement(
2357
+ TextField,
2359
2358
  {
2360
- key: m,
2361
- type: "button",
2362
- className: [
2363
- "rf-date-picker__month-cell",
2364
- idx === viewMonth ? "rf-date-picker__month-cell--selected" : "",
2365
- idx === todayDate.getMonth() && viewYear === currentYear ? "rf-date-picker__month-cell--current" : ""
2366
- ].filter(Boolean).join(" "),
2367
- onClick: () => handleMonthPick(idx)
2368
- },
2369
- m
2370
- ))), pickerView === "year" && /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__year-grid" }, years.map((y) => /* @__PURE__ */ React70.createElement(
2371
- "button",
2359
+ label: "Address Line 2",
2360
+ name: "addressLine2",
2361
+ fullWidth: true,
2362
+ value: value.addressLine2 || "",
2363
+ onChange: (e) => handleChange("addressLine2", e.target.value)
2364
+ }
2365
+ )), layout !== "compact" && /* @__PURE__ */ React70.createElement("div", { className: "address-lookup-grid-item col-l2" }, /* @__PURE__ */ React70.createElement(
2366
+ TextField,
2372
2367
  {
2373
- key: y,
2374
- type: "button",
2375
- className: [
2376
- "rf-date-picker__year-cell",
2377
- y === viewYear ? "rf-date-picker__year-cell--selected" : "",
2378
- y === currentYear ? "rf-date-picker__year-cell--current" : ""
2379
- ].filter(Boolean).join(" "),
2380
- onClick: () => handleYearPick(y)
2381
- },
2382
- y
2383
- ))), pickerView === "calendar" && /* @__PURE__ */ React70.createElement(React70.Fragment, null, /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__weekdays" }, WEEKDAYS.map((w) => /* @__PURE__ */ React70.createElement("div", { key: w, className: "rf-date-picker__weekday" }, w))), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__grid" }, dayCells.map((day, idx) => {
2384
- if (day === null) return /* @__PURE__ */ React70.createElement("div", { key: `e-${idx}`, className: "rf-date-picker__day rf-date-picker__day--empty" });
2385
- const cellDate = new Date(viewYear, viewMonth, day);
2386
- const isSelected = selectedDate ? isSameDay(cellDate, selectedDate) : false;
2387
- const isToday = isSameDay(cellDate, todayDate);
2388
- return /* @__PURE__ */ React70.createElement(
2389
- "button",
2390
- {
2391
- key: day,
2392
- type: "button",
2393
- className: [
2394
- "rf-date-picker__day",
2395
- isSelected ? "rf-date-picker__day--selected" : "",
2396
- isToday && !isSelected ? "rf-date-picker__day--today" : ""
2397
- ].filter(Boolean).join(" "),
2398
- onClick: () => onDayClick(day)
2399
- },
2400
- day
2401
- );
2402
- }))));
2403
- };
2404
- var DateField = ({
2405
- label,
2406
- value,
2407
- onChange,
2408
- type = "date",
2409
- dateFormat = "MM/DD/YYYY",
2410
- variant = "outlined",
2411
- size = "medium",
2412
- color = "primary",
2413
- error = false,
2414
- helperText,
2415
- fullWidth = false,
2416
- disabled = false,
2417
- required = false,
2418
- placeholder,
2419
- className = "",
2420
- style,
2421
- sx
2422
- }) => {
2423
- const sxClass = useSx(sx);
2424
- const [open, setOpen] = useState5(false);
2425
- const [selectedDate, setSelectedDate] = useState5(() => value ? isoToDate(value) : null);
2426
- const [hour, setHour] = useState5(() => {
2427
- if (value && isDatetimeType(type)) return parseTimeFromISO(value).h;
2428
- return 12;
2429
- });
2430
- const [minute, setMinute] = useState5(() => {
2431
- if (value && isDatetimeType(type)) return parseTimeFromISO(value).m;
2432
- return 0;
2433
- });
2434
- const [ampm, setAmpm] = useState5(() => {
2435
- if (value && isDatetimeType(type)) return parseTimeFromISO(value).ampm;
2436
- return "AM";
2437
- });
2438
- const [viewYear, setViewYear] = useState5(() => {
2439
- const base = value ? isoToDate(value) : null;
2440
- return base ? base.getFullYear() : today().getFullYear();
2441
- });
2442
- const [viewMonth, setViewMonth] = useState5(() => {
2443
- const base = value ? isoToDate(value) : null;
2444
- return base ? base.getMonth() : today().getMonth();
2445
- });
2446
- const [inputStr, setInputStr] = useState5(() => {
2447
- if (!value) return "";
2448
- const d = isoToDate(value);
2449
- if (!d) return "";
2450
- let str = formatDisplay(d, dateFormat);
2451
- if (isDatetimeType(type)) {
2452
- const t = parseTimeFromISO(value);
2453
- str += " " + formatTimeDisplay(t.h, t.m, t.ampm);
2454
- }
2455
- return str;
2456
- });
2457
- const HOURS = Array.from({ length: 12 }, (_, i) => String(i + 1).padStart(2, "0"));
2458
- const MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, "0"));
2459
- const AMPMS = ["AM", "PM"];
2460
- const containerRef = useRef4(null);
2461
- const pickerRef = useRef4(null);
2462
- const [dropUp, setDropUp] = useState5(false);
2463
- const inputId = useRef4(`rf-df-${Math.random().toString(36).substring(2, 11)}`).current;
2464
- useEffect5(() => {
2465
- if (value === void 0) return;
2466
- if (!value) {
2467
- setSelectedDate(null);
2468
- setInputStr("");
2469
- return;
2368
+ label: "Address Line 2",
2369
+ name: "addressLine2",
2370
+ fullWidth: true,
2371
+ value: value.addressLine2 || "",
2372
+ onChange: (e) => handleChange("addressLine2", e.target.value)
2470
2373
  }
2471
- const d = isoToDate(value);
2472
- setSelectedDate(d);
2473
- if (d) {
2474
- setViewYear(d.getFullYear());
2475
- setViewMonth(d.getMonth());
2476
- let str = formatDisplay(d, dateFormat);
2477
- if (isDatetimeType(type)) {
2478
- const t = parseTimeFromISO(value);
2479
- setHour(t.h);
2480
- setMinute(t.m);
2481
- setAmpm(t.ampm);
2482
- str += " " + formatTimeDisplay(t.h, t.m, t.ampm);
2483
- }
2484
- setInputStr(str);
2374
+ )), /* @__PURE__ */ React70.createElement("div", { className: "address-lookup-grid-item col-country" }, /* @__PURE__ */ React70.createElement(
2375
+ Autocomplete,
2376
+ {
2377
+ options: countries.map((c) => c.name),
2378
+ value: value.country || null,
2379
+ onChange: (v) => handleCountryChange(v || ""),
2380
+ label: "Country",
2381
+ fullWidth: true,
2382
+ required,
2383
+ error: !!error.country
2485
2384
  }
2486
- }, [value, type]);
2487
- useEffect5(() => {
2488
- if (!open) return;
2489
- const handler = (e) => {
2490
- const target = e.target;
2491
- if (containerRef.current?.contains(target)) return;
2492
- if (pickerRef.current?.contains(target)) return;
2493
- setOpen(false);
2494
- };
2495
- document.addEventListener("mousedown", handler);
2496
- return () => document.removeEventListener("mousedown", handler);
2497
- }, [open]);
2498
- useEffect5(() => {
2499
- if (!open || !containerRef.current) return;
2500
- const rect = containerRef.current.getBoundingClientRect();
2501
- const spaceBelow = window.innerHeight - rect.bottom;
2502
- const pickerHeight = 400;
2503
- setDropUp(spaceBelow < pickerHeight && rect.top > pickerHeight);
2504
- }, [open]);
2505
- const commitDate = useCallback((d, h, m, ap) => {
2506
- setSelectedDate(d);
2507
- if (!d) {
2508
- setInputStr("");
2509
- onChange?.("");
2510
- return;
2385
+ ), error.country && /* @__PURE__ */ React70.createElement("div", { className: "field-error-text" }, error.country)), /* @__PURE__ */ React70.createElement("div", { className: "address-lookup-grid-item col-state" }, /* @__PURE__ */ React70.createElement(
2386
+ Autocomplete,
2387
+ {
2388
+ options: states.map((s2) => s2.name),
2389
+ value: value.state || null,
2390
+ onChange: (v) => handleStateChange(v || ""),
2391
+ label: "State",
2392
+ fullWidth: true,
2393
+ required,
2394
+ error: !!error.state
2511
2395
  }
2512
- let str = formatDisplay(d, dateFormat);
2513
- if (isDatetimeType(type)) str += " " + formatTimeDisplay(h, m, ap);
2514
- setInputStr(str);
2515
- onChange?.(buildISO(d, type, h, m, ap));
2516
- }, [type, onChange, dateFormat]);
2517
- const handleDayClick = (day) => {
2518
- const d = new Date(viewYear, viewMonth, day);
2519
- setSelectedDate(d);
2520
- let str = formatDisplay(d, dateFormat);
2521
- if (isDatetimeType(type)) str += " " + formatTimeDisplay(hour, minute, ampm);
2522
- setInputStr(str);
2523
- onChange?.(buildISO(d, type, hour, minute, ampm));
2524
- if (type === "date") setOpen(false);
2525
- };
2526
- const handleToday = () => {
2527
- const t = today();
2528
- setViewYear(t.getFullYear());
2529
- setViewMonth(t.getMonth());
2530
- commitDate(t, hour, minute, ampm);
2531
- if (type === "date") setOpen(false);
2532
- };
2533
- const handleClear = () => commitDate(null, hour, minute, ampm);
2534
- const handleInputChange = (e) => {
2535
- const raw = e.target.value;
2536
- setInputStr(raw);
2537
- const parts = raw.split(" ");
2538
- const datePart = parts[0];
2539
- const parsed = parseDisplay(datePart, dateFormat);
2540
- if (parsed) {
2541
- setSelectedDate(parsed);
2542
- setViewYear(parsed.getFullYear());
2543
- setViewMonth(parsed.getMonth());
2544
- let h = hour, m = minute, ap = ampm;
2545
- if (isDatetimeType(type) && parts.length >= 3) {
2546
- const timePart = parts[1];
2547
- const periodPart = parts[2]?.toUpperCase();
2548
- if (timePart?.includes(":")) {
2549
- const [hStr, mStr] = timePart.split(":");
2550
- const parsedH = parseInt(hStr, 10);
2551
- const parsedM = parseInt(mStr, 10);
2552
- if (!isNaN(parsedH) && parsedH >= 1 && parsedH <= 12) {
2553
- h = parsedH;
2554
- setHour(h);
2555
- }
2556
- if (!isNaN(parsedM) && parsedM >= 0 && parsedM <= 59) {
2557
- m = parsedM;
2558
- setMinute(m);
2559
- }
2560
- }
2561
- if (periodPart === "AM" || periodPart === "PM") {
2562
- ap = periodPart;
2563
- setAmpm(ap);
2564
- }
2565
- }
2566
- onChange?.(buildISO(parsed, type, h, m, ap));
2567
- } else if (!raw) {
2568
- setSelectedDate(null);
2569
- onChange?.("");
2396
+ ), error.state && /* @__PURE__ */ React70.createElement("div", { className: "field-error-text" }, error.state)), /* @__PURE__ */ React70.createElement("div", { className: "address-lookup-grid-item col-city" }, /* @__PURE__ */ React70.createElement(
2397
+ Autocomplete,
2398
+ {
2399
+ options: cities.map((c) => c.name),
2400
+ value: value.city || null,
2401
+ onChange: (v) => handleChange("city", v || ""),
2402
+ label: "City",
2403
+ fullWidth: true,
2404
+ required,
2405
+ error: !!error.city
2570
2406
  }
2571
- };
2572
- const handleHourChange = (delta) => {
2573
- const h = (hour - 1 + delta + 12) % 12 + 1;
2574
- setHour(h);
2575
- if (selectedDate) commitDate(selectedDate, h, minute, ampm);
2576
- };
2577
- const handleMinuteChange = (delta) => {
2578
- const m = (minute + delta + 60) % 60;
2579
- setMinute(m);
2580
- if (selectedDate) commitDate(selectedDate, hour, m, ampm);
2581
- };
2582
- const handleAmpmToggle = (val) => {
2583
- setAmpm(val);
2584
- if (selectedDate) commitDate(selectedDate, hour, minute, val);
2585
- };
2586
- const handleHourInput = (e) => {
2587
- let v = parseInt(e.target.value, 10);
2588
- if (isNaN(v)) return;
2589
- v = Math.max(1, Math.min(12, v));
2590
- setHour(v);
2591
- if (selectedDate) commitDate(selectedDate, v, minute, ampm);
2592
- };
2593
- const handleMinuteInput = (e) => {
2594
- let v = parseInt(e.target.value, 10);
2595
- if (isNaN(v)) return;
2596
- v = Math.max(0, Math.min(59, v));
2597
- setMinute(v);
2598
- if (selectedDate) commitDate(selectedDate, hour, v, ampm);
2599
- };
2600
- const handleScrollHour = (idx) => {
2601
- const h = idx + 1;
2602
- setHour(h);
2603
- if (selectedDate) commitDate(selectedDate, h, minute, ampm);
2604
- };
2605
- const handleScrollMinute = (idx) => {
2606
- setMinute(idx);
2607
- if (selectedDate) commitDate(selectedDate, hour, idx, ampm);
2608
- };
2609
- const handleScrollAmpm = (idx) => {
2610
- const ap = AMPMS[idx];
2611
- setAmpm(ap);
2612
- if (selectedDate) commitDate(selectedDate, hour, minute, ap);
2613
- };
2614
- const prevMonth = () => {
2615
- if (viewMonth === 0) {
2616
- setViewMonth(11);
2617
- setViewYear((y) => y - 1);
2618
- } else setViewMonth((m) => m - 1);
2619
- };
2620
- const nextMonth = () => {
2621
- if (viewMonth === 11) {
2622
- setViewMonth(0);
2623
- setViewYear((y) => y + 1);
2624
- } else setViewMonth((m) => m + 1);
2625
- };
2626
- const firstDayOfWeek = new Date(viewYear, viewMonth, 1).getDay();
2627
- const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
2628
- const dayCells = [
2629
- ...Array(firstDayOfWeek).fill(null),
2630
- ...Array.from({ length: daysInMonth }, (_, i) => i + 1)
2631
- ];
2632
- const isFloating = Boolean(inputStr || open);
2633
- const rootClasses = [
2634
- "rf-text-field",
2635
- `rf-text-field--${variant}`,
2636
- `rf-text-field--${size}`,
2637
- `rf-text-field--${color}`,
2638
- error ? "rf-text-field--error" : "",
2639
- fullWidth ? "rf-text-field--full-width" : "",
2640
- disabled ? "rf-text-field--disabled" : "",
2641
- isFloating ? "rf-text-field--floating" : "",
2642
- Boolean(label) ? "rf-text-field--has-label" : "",
2643
- variant !== "compact" ? "rf-text-field--adorned-end" : "",
2644
- "rf-date-field",
2645
- fullWidth ? "rf-date-field--full-width" : "",
2646
- sxClass,
2647
- className
2648
- ].filter(Boolean).join(" ");
2649
- const inputPlaceholder = placeholder || (variant === "outlined" ? " " : void 0);
2650
- const todayDate = today();
2651
- const isSideVariant = type === "datetime-side" || type === "datetime-scroll";
2652
- return /* @__PURE__ */ React70.createElement("div", { ref: containerRef, className: rootClasses, style }, /* @__PURE__ */ React70.createElement("div", { className: "rf-date-field__anchor" }, /* @__PURE__ */ React70.createElement(
2653
- "div",
2407
+ ), error.city && /* @__PURE__ */ React70.createElement("div", { className: "field-error-text" }, error.city)), /* @__PURE__ */ React70.createElement("div", { className: "address-lookup-grid-item col-pin" }, /* @__PURE__ */ React70.createElement(
2408
+ TextField,
2654
2409
  {
2655
- className: "rf-text-field__wrapper",
2656
- onClick: () => {
2657
- if (!disabled) setOpen((o) => !o);
2658
- },
2659
- style: { cursor: disabled ? "default" : "pointer" }
2660
- },
2661
- /* @__PURE__ */ React70.createElement(
2662
- "input",
2663
- {
2664
- id: inputId,
2665
- className: "rf-text-field__input",
2666
- type: "text",
2667
- value: inputStr,
2668
- onChange: handleInputChange,
2669
- placeholder: inputPlaceholder,
2670
- disabled,
2671
- onClick: (e) => e.stopPropagation(),
2672
- onFocus: () => {
2673
- if (!disabled) setOpen(true);
2674
- }
2675
- }
2676
- ),
2677
- /* @__PURE__ */ React70.createElement("div", { className: "rf-text-field__adornment rf-text-field__adornment--end" }, /* @__PURE__ */ React70.createElement(
2678
- "button",
2679
- {
2680
- type: "button",
2681
- className: "rf-date-field__icon-btn",
2682
- tabIndex: -1,
2683
- disabled,
2684
- onClick: (e) => {
2685
- e.stopPropagation();
2686
- if (!disabled) setOpen((o) => !o);
2687
- },
2688
- "aria-label": "Pick date"
2689
- },
2690
- /* @__PURE__ */ React70.createElement(CalendarIcon, null)
2691
- )),
2692
- label && /* @__PURE__ */ React70.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, " ", required && /* @__PURE__ */ React70.createElement("span", { className: "rf-text-field__asterisk" }, "*")),
2693
- variant === "outlined" && /* @__PURE__ */ React70.createElement("fieldset", { className: "rf-text-field__notch" }, label && /* @__PURE__ */ React70.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ React70.createElement("span", null, label, required ? " *" : "")))
2694
- ), open && !disabled && createPortal(
2695
- /* @__PURE__ */ React70.createElement(
2696
- "div",
2697
- {
2698
- ref: pickerRef,
2699
- className: [
2700
- "rf-date-picker",
2701
- "rf-date-picker--portaled",
2702
- isSideVariant ? "rf-date-picker--side" : "",
2703
- dropUp ? "rf-date-picker--drop-up" : ""
2704
- ].filter(Boolean).join(" "),
2705
- style: (() => {
2706
- const rect = containerRef.current?.getBoundingClientRect();
2707
- if (!rect) return {};
2708
- const top = rect.bottom + 6;
2709
- const spaceBelow = window.innerHeight - rect.bottom - 6;
2710
- const useDropUp = spaceBelow < 350 && rect.top > spaceBelow;
2711
- return {
2712
- position: "fixed",
2713
- left: rect.left,
2714
- ...useDropUp ? { bottom: window.innerHeight - rect.top + 6 } : { top },
2715
- zIndex: 99999
2716
- };
2717
- })(),
2718
- onMouseDown: (e) => e.preventDefault()
2719
- },
2720
- /* @__PURE__ */ React70.createElement("div", { className: isSideVariant ? "rf-date-picker__cal-col" : void 0 }, /* @__PURE__ */ React70.createElement(
2721
- CalendarBody,
2722
- {
2723
- viewMonth,
2724
- viewYear,
2725
- selectedDate,
2726
- todayDate,
2727
- dayCells,
2728
- onDayClick: handleDayClick,
2729
- onPrev: prevMonth,
2730
- onNext: nextMonth,
2731
- onMonthSelect: setViewMonth,
2732
- onYearSelect: setViewYear
2733
- }
2734
- ), type === "datetime" && /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__time-section" }, /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__time-label" }, "Time"), /* @__PURE__ */ React70.createElement(
2735
- SpinnerPanel,
2736
- {
2737
- hour,
2738
- minute,
2739
- ampm,
2740
- onHourChange: handleHourChange,
2741
- onMinuteChange: handleMinuteChange,
2742
- onHourInput: handleHourInput,
2743
- onMinuteInput: handleMinuteInput,
2744
- onAmpmToggle: handleAmpmToggle
2745
- }
2746
- )), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__divider" }), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__footer" }, /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__footer-btn", onClick: handleToday }, "Today"), /* @__PURE__ */ React70.createElement("button", { type: "button", className: "rf-date-picker__footer-btn rf-date-picker__footer-btn--clear", onClick: handleClear }, "Clear"))),
2747
- type === "datetime-side" && /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__side-panel" }, /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__side-label" }, "Time"), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__side-spinner" }, /* @__PURE__ */ React70.createElement(
2748
- SpinnerPanel,
2749
- {
2750
- hour,
2751
- minute,
2752
- ampm,
2753
- onHourChange: handleHourChange,
2754
- onMinuteChange: handleMinuteChange,
2755
- onHourInput: handleHourInput,
2756
- onMinuteInput: handleMinuteInput,
2757
- onAmpmToggle: handleAmpmToggle
2758
- }
2759
- )), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__side-time-display" }, String(hour).padStart(2, "0"), ":", String(minute).padStart(2, "0"), " ", ampm)),
2760
- type === "datetime-scroll" && /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__side-panel" }, /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__side-label" }, "Time"), /* @__PURE__ */ React70.createElement("div", { className: "rf-timescroll" }, /* @__PURE__ */ React70.createElement(
2761
- ScrollColumn,
2762
- {
2763
- items: HOURS,
2764
- selected: hour - 1,
2765
- onSelect: handleScrollHour
2766
- }
2767
- ), /* @__PURE__ */ React70.createElement("div", { className: "rf-timescroll__colon" }, ":"), /* @__PURE__ */ React70.createElement(
2768
- ScrollColumn,
2769
- {
2770
- items: MINUTES,
2771
- selected: minute,
2772
- onSelect: handleScrollMinute
2773
- }
2774
- ), /* @__PURE__ */ React70.createElement(
2775
- ScrollColumn,
2776
- {
2777
- items: AMPMS,
2778
- selected: ampm === "AM" ? 0 : 1,
2779
- onSelect: handleScrollAmpm,
2780
- infinite: false
2781
- }
2782
- )), /* @__PURE__ */ React70.createElement("div", { className: "rf-date-picker__side-time-display" }, String(hour).padStart(2, "0"), ":", String(minute).padStart(2, "0"), " ", ampm))
2783
- ),
2784
- document.body
2785
- )), helperText && /* @__PURE__ */ React70.createElement("div", { className: "rf-text-field__helper-text" }, helperText));
2410
+ label: "Pincode",
2411
+ name: "pincode",
2412
+ fullWidth: true,
2413
+ value: value.pincode || "",
2414
+ required,
2415
+ onChange: (e) => handleChange("pincode", e.target.value)
2416
+ }
2417
+ ), error.pincode && /* @__PURE__ */ React70.createElement("div", { className: "field-error-text" }, error.pincode))));
2786
2418
  };
2787
- DateField.displayName = "DateField";
2419
+ var AddressLookup_default = AddressLookup;
2788
2420
 
2789
- // lib/TextFields/DateRangeField.tsx
2421
+ // lib/TextFields/DateField.tsx
2790
2422
  import React71, {
2791
2423
  useState as useState6,
2792
2424
  useRef as useRef5,
2793
- useEffect as useEffect6
2425
+ useEffect as useEffect6,
2426
+ useCallback as useCallback2
2794
2427
  } from "react";
2795
- var WEEKDAYS2 = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"];
2796
- var MONTHS2 = [
2428
+ import { createPortal } from "react-dom";
2429
+ var WEEKDAYS = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"];
2430
+ var MONTHS = [
2797
2431
  "January",
2798
2432
  "February",
2799
2433
  "March",
@@ -2807,7 +2441,7 @@ var MONTHS2 = [
2807
2441
  "November",
2808
2442
  "December"
2809
2443
  ];
2810
- var MONTHS_SHORT2 = [
2444
+ var MONTHS_SHORT = [
2811
2445
  "Jan",
2812
2446
  "Feb",
2813
2447
  "Mar",
@@ -2821,240 +2455,352 @@ var MONTHS_SHORT2 = [
2821
2455
  "Nov",
2822
2456
  "Dec"
2823
2457
  ];
2824
- var PRESETS = [
2825
- { id: "today", label: "Today" },
2826
- { id: "this_week", label: "This week" },
2827
- { id: "this_month", label: "This month" },
2828
- { id: "till_date", label: "Till date" },
2829
- { id: "all", label: "All" }
2830
- ];
2831
- var todayFn = () => {
2832
- const t = /* @__PURE__ */ new Date();
2833
- return new Date(t.getFullYear(), t.getMonth(), t.getDate());
2458
+ var formatDisplay = (d, fmt = "MM/DD/YYYY") => {
2459
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
2460
+ const dd = String(d.getDate()).padStart(2, "0");
2461
+ const yyyy = String(d.getFullYear());
2462
+ const day = d.getDate();
2463
+ switch (fmt) {
2464
+ case "DD/MM/YYYY":
2465
+ return `${dd}/${mm}/${yyyy}`;
2466
+ case "YYYY-MM-DD":
2467
+ return `${yyyy}-${mm}-${dd}`;
2468
+ case "DD-MM-YYYY":
2469
+ return `${dd}-${mm}-${yyyy}`;
2470
+ case "MM-DD-YYYY":
2471
+ return `${mm}-${dd}-${yyyy}`;
2472
+ case "YYYY/MM/DD":
2473
+ return `${yyyy}/${mm}/${dd}`;
2474
+ case "DD MMM YYYY":
2475
+ return `${dd} ${MONTHS_SHORT[d.getMonth()]} ${yyyy}`;
2476
+ case "MMM DD, YYYY":
2477
+ return `${MONTHS_SHORT[d.getMonth()]} ${dd}, ${yyyy}`;
2478
+ case "DD MMMM YYYY":
2479
+ return `${dd} ${MONTHS[d.getMonth()]} ${yyyy}`;
2480
+ case "MMMM DD, YYYY":
2481
+ return `${MONTHS[d.getMonth()]} ${dd}, ${yyyy}`;
2482
+ case "MM/DD/YYYY":
2483
+ default:
2484
+ return `${mm}/${dd}/${yyyy}`;
2485
+ }
2834
2486
  };
2835
- var isoToDate2 = (iso) => {
2836
- if (!iso) return null;
2837
- const parts = iso.split("-").map(Number);
2838
- if (parts.length < 3 || !parts[0] || !parts[1] || !parts[2]) return null;
2839
- return new Date(parts[0], parts[1] - 1, parts[2]);
2487
+ var formatTimeDisplay = (h, m, ampm) => `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")} ${ampm}`;
2488
+ var parseMonthName = (name) => {
2489
+ const lower = name.toLowerCase();
2490
+ let idx = MONTHS.findIndex((m) => m.toLowerCase() === lower);
2491
+ if (idx >= 0) return idx;
2492
+ idx = MONTHS_SHORT.findIndex((m) => m.toLowerCase() === lower);
2493
+ return idx;
2840
2494
  };
2841
- var dateToISO = (d) => {
2842
- const y = d.getFullYear();
2843
- const mo = String(d.getMonth() + 1).padStart(2, "0");
2844
- const dd = String(d.getDate()).padStart(2, "0");
2845
- return `${y}-${mo}-${dd}`;
2495
+ var strictDate = (yyyy, mm0, dd) => {
2496
+ if (dd < 1 || dd > 31 || mm0 < 0 || mm0 > 11) return null;
2497
+ const d = new Date(yyyy, mm0, dd);
2498
+ if (isNaN(d.getTime())) return null;
2499
+ if (d.getMonth() !== mm0 || d.getDate() !== dd) return null;
2500
+ return d;
2846
2501
  };
2847
- var formatShort = (d) => `${String(d.getDate()).padStart(2, "0")} ${MONTHS_SHORT2[d.getMonth()]} ${d.getFullYear()}`;
2848
- var parseInputDate = (str) => {
2849
- const s2 = str.trim();
2850
- if (!s2) return null;
2851
- const shortMatch = s2.match(/^(\d{1,2})\s+([A-Za-z]+)\s+(\d{4})$/);
2852
- if (shortMatch) {
2853
- const day = parseInt(shortMatch[1], 10);
2854
- const monthIdx = MONTHS_SHORT2.findIndex((m) => m.toLowerCase() === shortMatch[2].toLowerCase());
2855
- const year = parseInt(shortMatch[3], 10);
2856
- if (monthIdx !== -1 && day >= 1 && day <= 31 && year >= 1e3) {
2857
- const d = new Date(year, monthIdx, day);
2858
- if (!isNaN(d.getTime())) return d;
2859
- }
2502
+ var parseDisplay = (str, fmt = "MM/DD/YYYY") => {
2503
+ if (fmt === "DD MMM YYYY" || fmt === "DD MMMM YYYY") {
2504
+ const parts2 = str.split(" ");
2505
+ if (parts2.length !== 3) return null;
2506
+ const dd2 = parseInt(parts2[0], 10);
2507
+ const mm2 = parseMonthName(parts2[1]);
2508
+ const yyyy2 = parseInt(parts2[2], 10);
2509
+ if (isNaN(dd2) || isNaN(yyyy2) || yyyy2 < 1e3) return null;
2510
+ return strictDate(yyyy2, mm2, dd2);
2860
2511
  }
2861
- const slashMatch = s2.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
2862
- if (slashMatch) {
2863
- const d = new Date(parseInt(slashMatch[3], 10), parseInt(slashMatch[2], 10) - 1, parseInt(slashMatch[1], 10));
2864
- if (!isNaN(d.getTime())) return d;
2512
+ if (fmt === "MMM DD, YYYY" || fmt === "MMMM DD, YYYY") {
2513
+ const cleaned = str.replace(",", "");
2514
+ const parts2 = cleaned.split(" ").filter(Boolean);
2515
+ if (parts2.length !== 3) return null;
2516
+ const mm2 = parseMonthName(parts2[0]);
2517
+ const dd2 = parseInt(parts2[1], 10);
2518
+ const yyyy2 = parseInt(parts2[2], 10);
2519
+ if (isNaN(dd2) || isNaN(yyyy2) || yyyy2 < 1e3) return null;
2520
+ return strictDate(yyyy2, mm2, dd2);
2865
2521
  }
2866
- const isoMatch = s2.match(/^(\d{4})-(\d{2})-(\d{2})$/);
2867
- if (isoMatch) {
2868
- const d = new Date(parseInt(isoMatch[1], 10), parseInt(isoMatch[2], 10) - 1, parseInt(isoMatch[3], 10));
2869
- if (!isNaN(d.getTime())) return d;
2522
+ const sep = str.includes("/") ? "/" : "-";
2523
+ const parts = str.split(sep);
2524
+ if (parts.length !== 3) return null;
2525
+ const nums = parts.map(Number);
2526
+ let yyyy, mm, dd;
2527
+ switch (fmt) {
2528
+ case "DD/MM/YYYY":
2529
+ case "DD-MM-YYYY":
2530
+ [dd, mm, yyyy] = nums;
2531
+ break;
2532
+ case "YYYY-MM-DD":
2533
+ case "YYYY/MM/DD":
2534
+ [yyyy, mm, dd] = nums;
2535
+ break;
2536
+ case "MM-DD-YYYY":
2537
+ case "MM/DD/YYYY":
2538
+ default:
2539
+ [mm, dd, yyyy] = nums;
2540
+ break;
2870
2541
  }
2871
- return null;
2542
+ if (!yyyy || yyyy < 1e3) return null;
2543
+ return strictDate(yyyy, mm - 1, dd);
2872
2544
  };
2873
- var isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
2874
- var daysBetween = (a, b) => Math.round((b.getTime() - a.getTime()) / (1e3 * 60 * 60 * 24));
2875
- var addDays = (d, n) => {
2876
- const r = new Date(d.getTime());
2877
- r.setDate(r.getDate() + n);
2878
- return r;
2545
+ var isoToDate = (iso) => {
2546
+ if (!iso) return null;
2547
+ const [datePart] = iso.split("T");
2548
+ const [y, mo, d] = datePart.split("-").map(Number);
2549
+ if (!y || !mo || !d) return null;
2550
+ return new Date(y, mo - 1, d);
2879
2551
  };
2880
- var getPresetRange = (preset, currentStart) => {
2881
- const today2 = todayFn();
2882
- switch (preset) {
2883
- case "today":
2884
- return { start: dateToISO(today2), end: dateToISO(today2) };
2885
- case "this_week": {
2886
- const day = today2.getDay();
2887
- const monday = addDays(today2, day === 0 ? -6 : -(day - 1));
2888
- return { start: dateToISO(monday), end: dateToISO(addDays(monday, 6)) };
2889
- }
2890
- case "this_month": {
2891
- const start = new Date(today2.getFullYear(), today2.getMonth(), 1);
2892
- const end = new Date(today2.getFullYear(), today2.getMonth() + 1, 0);
2893
- return { start: dateToISO(start), end: dateToISO(end) };
2894
- }
2895
- case "till_date": {
2896
- const start = currentStart ?? addDays(today2, -30);
2897
- return { start: dateToISO(start), end: dateToISO(today2) };
2898
- }
2899
- case "all":
2900
- return { start: dateToISO(new Date(2e3, 0, 1)), end: dateToISO(today2) };
2552
+ var today = () => {
2553
+ const t = /* @__PURE__ */ new Date();
2554
+ return new Date(t.getFullYear(), t.getMonth(), t.getDate());
2555
+ };
2556
+ var isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
2557
+ var isDatetimeType = (t) => t !== "date";
2558
+ var buildISO = (date, type, hour, minute, ampm) => {
2559
+ const y = date.getFullYear();
2560
+ const mo = String(date.getMonth() + 1).padStart(2, "0");
2561
+ const d = String(date.getDate()).padStart(2, "0");
2562
+ if (type === "date") return `${y}-${mo}-${d}`;
2563
+ let h24 = hour % 12;
2564
+ if (ampm === "PM") h24 += 12;
2565
+ return `${y}-${mo}-${d}T${String(h24).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
2566
+ };
2567
+ var getDateWordCount = (fmt) => {
2568
+ switch (fmt) {
2569
+ case "DD MMM YYYY":
2570
+ case "MMM DD, YYYY":
2571
+ case "DD MMMM YYYY":
2572
+ case "MMMM DD, YYYY":
2573
+ return 3;
2901
2574
  default:
2902
- return { start: "", end: "" };
2575
+ return 1;
2903
2576
  }
2904
2577
  };
2905
- var detectPreset = (start, end) => {
2906
- if (!start || !end) return null;
2907
- const today2 = todayFn();
2908
- if (isSameDay2(start, today2) && isSameDay2(end, today2)) return "today";
2909
- const day = today2.getDay();
2910
- const monday = addDays(today2, day === 0 ? -6 : -(day - 1));
2911
- if (isSameDay2(start, monday) && isSameDay2(end, addDays(monday, 6))) return "this_week";
2912
- const monthStart = new Date(today2.getFullYear(), today2.getMonth(), 1);
2913
- const monthEnd = new Date(today2.getFullYear(), today2.getMonth() + 1, 0);
2914
- if (isSameDay2(start, monthStart) && isSameDay2(end, monthEnd)) return "this_month";
2915
- if (isSameDay2(end, today2)) return "till_date";
2916
- if (isSameDay2(start, new Date(2e3, 0, 1)) && isSameDay2(end, today2)) return "all";
2917
- return null;
2578
+ var parseTimeFromISO = (iso) => {
2579
+ const timePart = iso.split("T")[1] || "";
2580
+ const [hStr, mStr] = timePart.split(":");
2581
+ let h24 = parseInt(hStr, 10) || 0;
2582
+ const m = parseInt(mStr, 10) || 0;
2583
+ const ampm = h24 < 12 ? "AM" : "PM";
2584
+ let h = h24 % 12;
2585
+ if (h === 0) h = 12;
2586
+ return { h, m, ampm };
2918
2587
  };
2919
- var CalendarIcon2 = () => /* @__PURE__ */ React71.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React71.createElement("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2", ry: "2" }), /* @__PURE__ */ React71.createElement("line", { x1: "16", y1: "2", x2: "16", y2: "6" }), /* @__PURE__ */ React71.createElement("line", { x1: "8", y1: "2", x2: "8", y2: "6" }), /* @__PURE__ */ React71.createElement("line", { x1: "3", y1: "10", x2: "21", y2: "10" }));
2920
- var RangeCalendarBody = ({
2921
- viewYear,
2588
+ var CalendarIcon = () => /* @__PURE__ */ React71.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React71.createElement("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2", ry: "2" }), /* @__PURE__ */ React71.createElement("line", { x1: "16", y1: "2", x2: "16", y2: "6" }), /* @__PURE__ */ React71.createElement("line", { x1: "8", y1: "2", x2: "8", y2: "6" }), /* @__PURE__ */ React71.createElement("line", { x1: "3", y1: "10", x2: "21", y2: "10" }));
2589
+ var ChevUp = () => /* @__PURE__ */ React71.createElement("svg", { width: "10", height: "7", viewBox: "0 0 10 7", fill: "currentColor" }, /* @__PURE__ */ React71.createElement("path", { d: "M5 0L10 7H0L5 0Z" }));
2590
+ var ChevDown = () => /* @__PURE__ */ React71.createElement("svg", { width: "10", height: "7", viewBox: "0 0 10 7", fill: "currentColor" }, /* @__PURE__ */ React71.createElement("path", { d: "M5 7L0 0H10L5 7Z" }));
2591
+ var ITEM_H = 36;
2592
+ var ScrollColumn = ({ items, selected, onSelect, infinite = true }) => {
2593
+ const listRef = useRef5(null);
2594
+ const isInternalScroll = useRef5(false);
2595
+ const scrollTimeout = useRef5(null);
2596
+ const MULTIPLIER = infinite ? 100 : 1;
2597
+ const virtualItems = infinite ? Array(MULTIPLIER).fill(items).flat() : items;
2598
+ const centerOffset = infinite ? Math.floor(MULTIPLIER / 2) * items.length : 0;
2599
+ const VISUAL_OFFSET = 54;
2600
+ useEffect6(() => {
2601
+ if (listRef.current) {
2602
+ const targetIndex = centerOffset + selected;
2603
+ listRef.current.scrollTop = targetIndex * ITEM_H - (infinite ? VISUAL_OFFSET : 0);
2604
+ }
2605
+ }, [centerOffset, infinite, selected]);
2606
+ useEffect6(() => {
2607
+ if (listRef.current && !isInternalScroll.current) {
2608
+ const targetIndex = centerOffset + selected;
2609
+ listRef.current.scrollTo({
2610
+ top: targetIndex * ITEM_H - (infinite ? VISUAL_OFFSET : 0),
2611
+ behavior: "smooth"
2612
+ });
2613
+ }
2614
+ isInternalScroll.current = false;
2615
+ }, [selected, centerOffset, infinite]);
2616
+ const handleScroll = () => {
2617
+ if (!listRef.current) return;
2618
+ const scrollTop = listRef.current.scrollTop;
2619
+ const adjustedScrollTop = infinite ? scrollTop + VISUAL_OFFSET : scrollTop;
2620
+ const index = Math.round(adjustedScrollTop / ITEM_H);
2621
+ const actualIndex = infinite ? (index % items.length + items.length) % items.length : Math.max(0, Math.min(items.length - 1, index));
2622
+ if (infinite) {
2623
+ const buffer = items.length * 10;
2624
+ if (index < buffer || index > virtualItems.length - buffer) {
2625
+ const newIndex = centerOffset + actualIndex;
2626
+ listRef.current.scrollTop = newIndex * ITEM_H - VISUAL_OFFSET;
2627
+ return;
2628
+ }
2629
+ }
2630
+ if (scrollTimeout.current) clearTimeout(scrollTimeout.current);
2631
+ scrollTimeout.current = setTimeout(() => {
2632
+ if (actualIndex !== selected) {
2633
+ isInternalScroll.current = true;
2634
+ onSelect(actualIndex);
2635
+ }
2636
+ }, 100);
2637
+ };
2638
+ return /* @__PURE__ */ React71.createElement("div", { className: "rf-timescroll__col-wrapper" }, /* @__PURE__ */ React71.createElement(
2639
+ "div",
2640
+ {
2641
+ className: "rf-timescroll__col",
2642
+ ref: listRef,
2643
+ onScroll: handleScroll
2644
+ },
2645
+ !infinite && /* @__PURE__ */ React71.createElement("div", { className: "rf-timescroll__spacer" }),
2646
+ virtualItems.map((label, idx) => /* @__PURE__ */ React71.createElement(
2647
+ "div",
2648
+ {
2649
+ key: `${label}-${idx}`,
2650
+ className: `rf-timescroll__item ${idx % items.length === selected ? "rf-timescroll__item--active" : ""}`
2651
+ },
2652
+ label
2653
+ )),
2654
+ !infinite && /* @__PURE__ */ React71.createElement("div", { className: "rf-timescroll__spacer" })
2655
+ ), /* @__PURE__ */ React71.createElement("div", { className: "rf-timescroll__mask rf-timescroll__mask--top" }), /* @__PURE__ */ React71.createElement("div", { className: "rf-timescroll__mask rf-timescroll__mask--bottom" }));
2656
+ };
2657
+ var SpinnerPanel = ({
2658
+ hour,
2659
+ minute,
2660
+ ampm,
2661
+ onHourChange,
2662
+ onMinuteChange,
2663
+ onHourInput,
2664
+ onMinuteInput,
2665
+ onAmpmToggle
2666
+ }) => /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__time-row" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__time-input-wrap" }, /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__time-spin-btn", onMouseDown: (e) => e.preventDefault(), onClick: () => onHourChange(1) }, /* @__PURE__ */ React71.createElement(ChevUp, null)), /* @__PURE__ */ React71.createElement(
2667
+ "input",
2668
+ {
2669
+ type: "number",
2670
+ className: "rf-date-picker__time-digit",
2671
+ value: String(hour).padStart(2, "0"),
2672
+ min: 1,
2673
+ max: 12,
2674
+ onChange: onHourInput,
2675
+ onMouseDown: (e) => e.stopPropagation()
2676
+ }
2677
+ ), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__time-spin-btn", onMouseDown: (e) => e.preventDefault(), onClick: () => onHourChange(-1) }, /* @__PURE__ */ React71.createElement(ChevDown, null))), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__time-colon" }, ":"), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__time-input-wrap" }, /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__time-spin-btn", onMouseDown: (e) => e.preventDefault(), onClick: () => onMinuteChange(1) }, /* @__PURE__ */ React71.createElement(ChevUp, null)), /* @__PURE__ */ React71.createElement(
2678
+ "input",
2679
+ {
2680
+ type: "number",
2681
+ className: "rf-date-picker__time-digit",
2682
+ value: String(minute).padStart(2, "0"),
2683
+ min: 0,
2684
+ max: 59,
2685
+ onChange: onMinuteInput,
2686
+ onMouseDown: (e) => e.stopPropagation()
2687
+ }
2688
+ ), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__time-spin-btn", onMouseDown: (e) => e.preventDefault(), onClick: () => onMinuteChange(-1) }, /* @__PURE__ */ React71.createElement(ChevDown, null))), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__ampm" }, /* @__PURE__ */ React71.createElement(
2689
+ "button",
2690
+ {
2691
+ type: "button",
2692
+ className: `rf-date-picker__ampm-btn ${ampm === "AM" ? "rf-date-picker__ampm-btn--active" : ""}`,
2693
+ onMouseDown: (e) => e.preventDefault(),
2694
+ onClick: () => onAmpmToggle("AM")
2695
+ },
2696
+ "AM"
2697
+ ), /* @__PURE__ */ React71.createElement(
2698
+ "button",
2699
+ {
2700
+ type: "button",
2701
+ className: `rf-date-picker__ampm-btn ${ampm === "PM" ? "rf-date-picker__ampm-btn--active" : ""}`,
2702
+ onMouseDown: (e) => e.preventDefault(),
2703
+ onClick: () => onAmpmToggle("PM")
2704
+ },
2705
+ "PM"
2706
+ )));
2707
+ var CalendarBody = ({
2922
2708
  viewMonth,
2923
- startDate,
2924
- endDate,
2925
- hoverDate,
2709
+ viewYear,
2710
+ selectedDate,
2926
2711
  todayDate,
2712
+ dayCells,
2927
2713
  onDayClick,
2928
- onDayHover,
2929
2714
  onPrev,
2930
2715
  onNext,
2931
- showPrev = true,
2932
- showNext = true
2716
+ onMonthSelect,
2717
+ onYearSelect
2933
2718
  }) => {
2934
- const firstDay = new Date(viewYear, viewMonth, 1).getDay();
2935
- const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
2936
- const dayCells = [
2937
- ...Array(firstDay).fill(null),
2938
- ...Array.from({ length: daysInMonth }, (_, i) => i + 1)
2939
- ];
2940
- const effectiveEnd = endDate ?? hoverDate;
2941
- const hasRange = startDate != null && effectiveEnd != null && !isSameDay2(startDate, effectiveEnd);
2942
- const lo = startDate && effectiveEnd ? startDate <= effectiveEnd ? startDate : effectiveEnd : null;
2943
- const hi = startDate && effectiveEnd ? startDate <= effectiveEnd ? effectiveEnd : startDate : null;
2944
- return /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-calendar" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-calendar__header" }, /* @__PURE__ */ React71.createElement(
2719
+ const [pickerView, setPickerView] = useState6("calendar");
2720
+ const handleMonthClick = () => {
2721
+ setPickerView(pickerView === "month" ? "calendar" : "month");
2722
+ };
2723
+ const handleYearClick = () => {
2724
+ setPickerView(pickerView === "year" ? "calendar" : "year");
2725
+ };
2726
+ const handleMonthPick = (month) => {
2727
+ onMonthSelect(month);
2728
+ setPickerView("calendar");
2729
+ };
2730
+ const handleYearPick = (year) => {
2731
+ onYearSelect(year);
2732
+ setPickerView("calendar");
2733
+ };
2734
+ const currentYear = todayDate.getFullYear();
2735
+ const yearStart = viewYear - 6;
2736
+ const years = Array.from({ length: 16 }, (_, i) => yearStart + i);
2737
+ return /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__header" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__header-labels" }, /* @__PURE__ */ React71.createElement(
2738
+ "span",
2739
+ {
2740
+ className: `rf-date-picker__month-label ${pickerView === "month" ? "rf-date-picker__month-label--active" : ""}`,
2741
+ onClick: handleMonthClick
2742
+ },
2743
+ MONTHS[viewMonth]
2744
+ ), /* @__PURE__ */ React71.createElement(
2745
+ "span",
2746
+ {
2747
+ className: `rf-date-picker__year-label ${pickerView === "year" ? "rf-date-picker__year-label--active" : ""}`,
2748
+ onClick: handleYearClick
2749
+ },
2750
+ viewYear
2751
+ )), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__nav" }, pickerView === "year" ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear - 16), "aria-label": "Previous years" }, "\u2039"), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear + 16), "aria-label": "Next years" }, "\u203A")) : /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: onPrev, "aria-label": "Previous month" }, "\u2039"), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: onNext, "aria-label": "Next month" }, "\u203A")))), pickerView === "month" && /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__month-grid" }, MONTHS_SHORT.map((m, idx) => /* @__PURE__ */ React71.createElement(
2945
2752
  "button",
2946
2753
  {
2754
+ key: m,
2947
2755
  type: "button",
2948
- className: "rf-dr-calendar__nav-btn",
2949
- onClick: onPrev,
2950
- style: { visibility: showPrev ? "visible" : "hidden" },
2951
- "aria-label": "Previous month"
2756
+ className: [
2757
+ "rf-date-picker__month-cell",
2758
+ idx === viewMonth ? "rf-date-picker__month-cell--selected" : "",
2759
+ idx === todayDate.getMonth() && viewYear === currentYear ? "rf-date-picker__month-cell--current" : ""
2760
+ ].filter(Boolean).join(" "),
2761
+ onClick: () => handleMonthPick(idx)
2952
2762
  },
2953
- "\u2039"
2954
- ), /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-calendar__month-label" }, MONTHS2[viewMonth], " ", viewYear), /* @__PURE__ */ React71.createElement(
2763
+ m
2764
+ ))), pickerView === "year" && /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__year-grid" }, years.map((y) => /* @__PURE__ */ React71.createElement(
2955
2765
  "button",
2956
2766
  {
2767
+ key: y,
2957
2768
  type: "button",
2958
- className: "rf-dr-calendar__nav-btn",
2959
- onClick: onNext,
2960
- style: { visibility: showNext ? "visible" : "hidden" },
2961
- "aria-label": "Next month"
2769
+ className: [
2770
+ "rf-date-picker__year-cell",
2771
+ y === viewYear ? "rf-date-picker__year-cell--selected" : "",
2772
+ y === currentYear ? "rf-date-picker__year-cell--current" : ""
2773
+ ].filter(Boolean).join(" "),
2774
+ onClick: () => handleYearPick(y)
2962
2775
  },
2963
- "\u203A"
2964
- )), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-calendar__weekdays" }, WEEKDAYS2.map((w) => /* @__PURE__ */ React71.createElement("div", { key: w, className: "rf-dr-calendar__weekday" }, w))), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-calendar__grid" }, dayCells.map((day, idx) => {
2965
- if (day === null) {
2966
- return /* @__PURE__ */ React71.createElement("div", { key: `e-${idx}`, className: "rf-dr-calendar__cell rf-dr-calendar__cell--empty" });
2967
- }
2776
+ y
2777
+ ))), pickerView === "calendar" && /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__weekdays" }, WEEKDAYS.map((w) => /* @__PURE__ */ React71.createElement("div", { key: w, className: "rf-date-picker__weekday" }, w))), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__grid" }, dayCells.map((day, idx) => {
2778
+ if (day === null) return /* @__PURE__ */ React71.createElement("div", { key: `e-${idx}`, className: "rf-date-picker__day rf-date-picker__day--empty" });
2968
2779
  const cellDate = new Date(viewYear, viewMonth, day);
2969
- const isStart = startDate ? isSameDay2(cellDate, startDate) : false;
2970
- const isEnd = endDate ? isSameDay2(cellDate, endDate) : false;
2971
- const isToday = isSameDay2(cellDate, todayDate);
2972
- const isInRange = lo && hi ? cellDate > lo && cellDate < hi : false;
2973
- const isRangeStart = hasRange && lo ? isSameDay2(cellDate, lo) : false;
2974
- const isRangeEnd = hasRange && hi ? isSameDay2(cellDate, hi) : false;
2975
- const cellClasses = [
2976
- "rf-dr-calendar__cell",
2977
- isInRange ? "rf-dr-calendar__cell--in-range" : "",
2978
- isRangeStart ? "rf-dr-calendar__cell--range-start" : "",
2979
- isRangeEnd ? "rf-dr-calendar__cell--range-end" : ""
2980
- ].filter(Boolean).join(" ");
2981
- const dayClasses = [
2982
- "rf-dr-calendar__day",
2983
- isStart || isEnd ? "rf-dr-calendar__day--selected" : "",
2984
- isToday && !isStart && !isEnd ? "rf-dr-calendar__day--today" : ""
2985
- ].filter(Boolean).join(" ");
2780
+ const isSelected = selectedDate ? isSameDay(cellDate, selectedDate) : false;
2781
+ const isToday = isSameDay(cellDate, todayDate);
2986
2782
  return /* @__PURE__ */ React71.createElement(
2987
- "div",
2988
- {
2989
- key: day,
2990
- className: cellClasses,
2991
- onMouseEnter: () => onDayHover(cellDate),
2992
- onMouseLeave: () => onDayHover(null)
2993
- },
2994
- /* @__PURE__ */ React71.createElement(
2995
- "button",
2996
- {
2997
- type: "button",
2998
- className: dayClasses,
2999
- onClick: () => onDayClick(cellDate)
3000
- },
3001
- day
3002
- )
3003
- );
3004
- })));
3005
- };
3006
- var MiniCalendar = ({ selectedDate, todayDate, onSelect, onClose }) => {
3007
- const init = selectedDate ?? todayDate;
3008
- const [viewYear, setViewYear] = useState6(init.getFullYear());
3009
- const [viewMonth, setViewMonth] = useState6(init.getMonth());
3010
- const firstDay = new Date(viewYear, viewMonth, 1).getDay();
3011
- const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
3012
- const dayCells = [
3013
- ...Array(firstDay).fill(null),
3014
- ...Array.from({ length: daysInMonth }, (_, i) => i + 1)
3015
- ];
3016
- const prevMonth = () => {
3017
- if (viewMonth === 0) {
3018
- setViewMonth(11);
3019
- setViewYear((y) => y - 1);
3020
- } else setViewMonth((m) => m - 1);
3021
- };
3022
- const nextMonth = () => {
3023
- if (viewMonth === 11) {
3024
- setViewMonth(0);
3025
- setViewYear((y) => y + 1);
3026
- } else setViewMonth((m) => m + 1);
3027
- };
3028
- return /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-mini-cal" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-mini-cal__header" }, /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-dr-calendar__nav-btn", onClick: prevMonth }, "\u2039"), /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-calendar__month-label", style: { fontSize: "0.88rem" } }, MONTHS2[viewMonth], " ", viewYear), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-dr-calendar__nav-btn", onClick: nextMonth }, "\u203A")), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-calendar__weekdays" }, WEEKDAYS2.map((w) => /* @__PURE__ */ React71.createElement("div", { key: w, className: "rf-dr-calendar__weekday" }, w))), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-calendar__grid" }, dayCells.map((day, idx) => {
3029
- if (day === null) {
3030
- return /* @__PURE__ */ React71.createElement("div", { key: `e-${idx}`, className: "rf-dr-calendar__cell rf-dr-calendar__cell--empty" });
3031
- }
3032
- const cellDate = new Date(viewYear, viewMonth, day);
3033
- const isSel = selectedDate ? isSameDay2(cellDate, selectedDate) : false;
3034
- const isToday = isSameDay2(cellDate, todayDate);
3035
- return /* @__PURE__ */ React71.createElement("div", { key: day, className: "rf-dr-calendar__cell" }, /* @__PURE__ */ React71.createElement(
3036
2783
  "button",
3037
2784
  {
2785
+ key: day,
3038
2786
  type: "button",
3039
2787
  className: [
3040
- "rf-dr-calendar__day",
3041
- isSel ? "rf-dr-calendar__day--selected" : "",
3042
- isToday && !isSel ? "rf-dr-calendar__day--today" : ""
2788
+ "rf-date-picker__day",
2789
+ isSelected ? "rf-date-picker__day--selected" : "",
2790
+ isToday && !isSelected ? "rf-date-picker__day--today" : ""
3043
2791
  ].filter(Boolean).join(" "),
3044
- onClick: () => {
3045
- onSelect(cellDate);
3046
- onClose();
3047
- }
2792
+ onClick: () => onDayClick(day)
3048
2793
  },
3049
2794
  day
3050
- ));
3051
- })));
2795
+ );
2796
+ }))));
3052
2797
  };
3053
- var DateRangeField = ({
2798
+ var DateField = ({
3054
2799
  label,
3055
2800
  value,
3056
2801
  onChange,
3057
- pickerType = "panel",
2802
+ type = "date",
2803
+ dateFormat = "MM/DD/YYYY",
3058
2804
  variant = "outlined",
3059
2805
  size = "medium",
3060
2806
  color = "primary",
@@ -3063,165 +2809,230 @@ var DateRangeField = ({
3063
2809
  fullWidth = false,
3064
2810
  disabled = false,
3065
2811
  required = false,
2812
+ placeholder,
3066
2813
  className = "",
3067
2814
  style,
3068
2815
  sx
3069
2816
  }) => {
3070
2817
  const sxClass = useSx(sx);
3071
- const today2 = todayFn();
3072
- const committedStart = value?.start ? isoToDate2(value.start) : null;
3073
- const committedEnd = value?.end ? isoToDate2(value.end) : null;
3074
2818
  const [open, setOpen] = useState6(false);
3075
- const [draftStart, setDraftStart] = useState6(committedStart);
3076
- const [draftEnd, setDraftEnd] = useState6(committedEnd);
3077
- const [activePreset, setActivePreset] = useState6(
3078
- () => detectPreset(committedStart, committedEnd)
3079
- );
3080
- const [startInputStr, setStartInputStr] = useState6(() => committedStart ? formatShort(committedStart) : "");
3081
- const [endInputStr, setEndInputStr] = useState6(() => committedEnd ? formatShort(committedEnd) : "");
3082
- const [inlineCal, setInlineCal] = useState6(null);
3083
- const [hoverDate, setHoverDate] = useState6(null);
3084
- const [selecting, setSelecting] = useState6("start");
3085
- const [leftViewYear, setLeftViewYear] = useState6(() => today2.getFullYear());
3086
- const [leftViewMonth, setLeftViewMonth] = useState6(() => today2.getMonth());
2819
+ const [selectedDate, setSelectedDate] = useState6(() => value ? isoToDate(value) : null);
2820
+ const [hour, setHour] = useState6(() => {
2821
+ if (value && isDatetimeType(type)) return parseTimeFromISO(value).h;
2822
+ return 12;
2823
+ });
2824
+ const [minute, setMinute] = useState6(() => {
2825
+ if (value && isDatetimeType(type)) return parseTimeFromISO(value).m;
2826
+ return 0;
2827
+ });
2828
+ const [ampm, setAmpm] = useState6(() => {
2829
+ if (value && isDatetimeType(type)) return parseTimeFromISO(value).ampm;
2830
+ return "AM";
2831
+ });
2832
+ const [viewYear, setViewYear] = useState6(() => {
2833
+ const base = value ? isoToDate(value) : null;
2834
+ return base ? base.getFullYear() : today().getFullYear();
2835
+ });
2836
+ const [viewMonth, setViewMonth] = useState6(() => {
2837
+ const base = value ? isoToDate(value) : null;
2838
+ return base ? base.getMonth() : today().getMonth();
2839
+ });
2840
+ const [inputStr, setInputStr] = useState6(() => {
2841
+ if (!value) return "";
2842
+ const d = isoToDate(value);
2843
+ if (!d) return "";
2844
+ let str = formatDisplay(d, dateFormat);
2845
+ if (isDatetimeType(type)) {
2846
+ const t = parseTimeFromISO(value);
2847
+ str += " " + formatTimeDisplay(t.h, t.m, t.ampm);
2848
+ }
2849
+ return str;
2850
+ });
2851
+ const HOURS = Array.from({ length: 12 }, (_, i) => String(i + 1).padStart(2, "0"));
2852
+ const MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, "0"));
2853
+ const AMPMS = ["AM", "PM"];
3087
2854
  const containerRef = useRef5(null);
3088
- const inputId = useRef5(`rf-dr-${Math.random().toString(36).substr(2, 9)}`).current;
3089
- useEffect6(() => {
3090
- const s2 = value?.start ? isoToDate2(value.start) : null;
3091
- const e = value?.end ? isoToDate2(value.end) : null;
3092
- setDraftStart(s2);
3093
- setDraftEnd(e);
3094
- setStartInputStr(s2 ? formatShort(s2) : "");
3095
- setEndInputStr(e ? formatShort(e) : "");
3096
- setActivePreset(detectPreset(s2, e));
3097
- }, [value?.start, value?.end]);
2855
+ const pickerRef = useRef5(null);
2856
+ const [dropUp, setDropUp] = useState6(false);
2857
+ const inputId = useRef5(`rf-df-${Math.random().toString(36).substring(2, 11)}`).current;
2858
+ const isInternalChange = useRef5(false);
3098
2859
  useEffect6(() => {
3099
- setActivePreset(detectPreset(draftStart, draftEnd));
3100
- }, [draftStart?.getTime(), draftEnd?.getTime()]);
2860
+ if (value === void 0) return;
2861
+ if (isInternalChange.current) {
2862
+ isInternalChange.current = false;
2863
+ return;
2864
+ }
2865
+ if (!value) {
2866
+ setSelectedDate(null);
2867
+ setInputStr("");
2868
+ return;
2869
+ }
2870
+ const d = isoToDate(value);
2871
+ setSelectedDate(d);
2872
+ if (d) {
2873
+ setViewYear(d.getFullYear());
2874
+ setViewMonth(d.getMonth());
2875
+ let str = formatDisplay(d, dateFormat);
2876
+ if (isDatetimeType(type)) {
2877
+ const t = parseTimeFromISO(value);
2878
+ setHour(t.h);
2879
+ setMinute(t.m);
2880
+ setAmpm(t.ampm);
2881
+ str += " " + formatTimeDisplay(t.h, t.m, t.ampm);
2882
+ }
2883
+ setInputStr(str);
2884
+ }
2885
+ }, [value, type]);
3101
2886
  useEffect6(() => {
3102
2887
  if (!open) return;
3103
2888
  const handler = (e) => {
3104
- if (containerRef.current && !containerRef.current.contains(e.target)) {
3105
- setOpen(false);
3106
- setInlineCal(null);
3107
- setDraftStart(committedStart);
3108
- setDraftEnd(committedEnd);
3109
- setStartInputStr(committedStart ? formatShort(committedStart) : "");
3110
- setEndInputStr(committedEnd ? formatShort(committedEnd) : "");
3111
- setActivePreset(detectPreset(committedStart, committedEnd));
3112
- setSelecting("start");
3113
- }
2889
+ const target = e.target;
2890
+ if (containerRef.current?.contains(target)) return;
2891
+ if (pickerRef.current?.contains(target)) return;
2892
+ setOpen(false);
3114
2893
  };
3115
2894
  document.addEventListener("mousedown", handler);
3116
2895
  return () => document.removeEventListener("mousedown", handler);
3117
- }, [open, committedStart, committedEnd]);
3118
- const displayStr = (() => {
3119
- if (committedStart && committedEnd) {
3120
- return `${formatShort(committedStart)} \u2013 ${formatShort(committedEnd)}`;
3121
- }
3122
- if (committedStart) return `${formatShort(committedStart)} \u2013`;
3123
- return "";
3124
- })();
3125
- const handleApply = () => {
3126
- if (draftStart && draftEnd) {
3127
- const [s2, e] = draftStart <= draftEnd ? [draftStart, draftEnd] : [draftEnd, draftStart];
3128
- onChange?.({ start: dateToISO(s2), end: dateToISO(e) });
3129
- } else if (draftStart) {
3130
- onChange?.({ start: dateToISO(draftStart), end: dateToISO(draftStart) });
2896
+ }, [open]);
2897
+ useEffect6(() => {
2898
+ if (!open || !containerRef.current) return;
2899
+ const rect = containerRef.current.getBoundingClientRect();
2900
+ const spaceBelow = window.innerHeight - rect.bottom;
2901
+ const pickerHeight = 400;
2902
+ setDropUp(spaceBelow < pickerHeight && rect.top > pickerHeight);
2903
+ }, [open]);
2904
+ const commitDate = useCallback2((d, h, m, ap) => {
2905
+ setSelectedDate(d);
2906
+ if (!d) {
2907
+ setInputStr("");
2908
+ onChange?.("");
2909
+ return;
3131
2910
  }
3132
- setOpen(false);
3133
- setInlineCal(null);
3134
- };
3135
- const handleClose = () => {
3136
- setOpen(false);
3137
- setInlineCal(null);
3138
- setDraftStart(committedStart);
3139
- setDraftEnd(committedEnd);
3140
- setStartInputStr(committedStart ? formatShort(committedStart) : "");
3141
- setEndInputStr(committedEnd ? formatShort(committedEnd) : "");
3142
- setActivePreset(detectPreset(committedStart, committedEnd));
3143
- setSelecting("start");
2911
+ let str = formatDisplay(d, dateFormat);
2912
+ if (isDatetimeType(type)) str += " " + formatTimeDisplay(h, m, ap);
2913
+ setInputStr(str);
2914
+ onChange?.(buildISO(d, type, h, m, ap));
2915
+ }, [type, onChange, dateFormat]);
2916
+ const handleDayClick = (day) => {
2917
+ const d = new Date(viewYear, viewMonth, day);
2918
+ setSelectedDate(d);
2919
+ let str = formatDisplay(d, dateFormat);
2920
+ if (isDatetimeType(type)) str += " " + formatTimeDisplay(hour, minute, ampm);
2921
+ setInputStr(str);
2922
+ onChange?.(buildISO(d, type, hour, minute, ampm));
2923
+ if (type === "date") setOpen(false);
3144
2924
  };
3145
- const handlePreset = (presetId) => {
3146
- const range = getPresetRange(presetId, draftStart);
3147
- const s2 = isoToDate2(range.start);
3148
- const e = isoToDate2(range.end);
3149
- setDraftStart(s2);
3150
- setDraftEnd(e);
3151
- setStartInputStr(s2 ? formatShort(s2) : "");
3152
- setEndInputStr(e ? formatShort(e) : "");
3153
- setInlineCal(null);
2925
+ const handleToday = () => {
2926
+ const t = today();
2927
+ setViewYear(t.getFullYear());
2928
+ setViewMonth(t.getMonth());
2929
+ commitDate(t, hour, minute, ampm);
2930
+ if (type === "date") setOpen(false);
3154
2931
  };
3155
- const handleCalDayClick = (d) => {
3156
- if (selecting === "start") {
3157
- setDraftStart(d);
3158
- setDraftEnd(null);
3159
- setSelecting("end");
3160
- setActivePreset(null);
3161
- } else {
3162
- if (draftStart && d < draftStart) {
3163
- setDraftEnd(draftStart);
3164
- setDraftStart(d);
3165
- } else {
3166
- setDraftEnd(d);
2932
+ const handleClear = () => commitDate(null, hour, minute, ampm);
2933
+ const handleInputChange = (e) => {
2934
+ const raw = e.target.value;
2935
+ setInputStr(raw);
2936
+ const dateWordCount = getDateWordCount(dateFormat);
2937
+ const words = raw.split(" ");
2938
+ const datePart = words.slice(0, dateWordCount).join(" ");
2939
+ const timeParts = words.slice(dateWordCount);
2940
+ const parsed = parseDisplay(datePart, dateFormat);
2941
+ if (parsed) {
2942
+ setSelectedDate(parsed);
2943
+ setViewYear(parsed.getFullYear());
2944
+ setViewMonth(parsed.getMonth());
2945
+ let h = hour, m = minute, ap = ampm;
2946
+ if (isDatetimeType(type) && timeParts.length >= 2) {
2947
+ const timePart = timeParts[0];
2948
+ const periodPart = timeParts[1]?.toUpperCase();
2949
+ if (timePart?.includes(":")) {
2950
+ const [hStr, mStr] = timePart.split(":");
2951
+ const parsedH = parseInt(hStr, 10);
2952
+ const parsedM = parseInt(mStr, 10);
2953
+ if (!isNaN(parsedH) && parsedH >= 1 && parsedH <= 12) {
2954
+ h = parsedH;
2955
+ setHour(h);
2956
+ }
2957
+ if (!isNaN(parsedM) && parsedM >= 0 && parsedM <= 59) {
2958
+ m = parsedM;
2959
+ setMinute(m);
2960
+ }
2961
+ }
2962
+ if (periodPart === "AM" || periodPart === "PM") {
2963
+ ap = periodPart;
2964
+ setAmpm(ap);
2965
+ }
3167
2966
  }
3168
- setSelecting("start");
3169
- setActivePreset(detectPreset(draftStart, d));
2967
+ isInternalChange.current = true;
2968
+ onChange?.(buildISO(parsed, type, h, m, ap));
2969
+ } else if (!raw) {
2970
+ setSelectedDate(null);
2971
+ isInternalChange.current = true;
2972
+ onChange?.("");
3170
2973
  }
3171
2974
  };
3172
- const rightViewMonth = leftViewMonth === 11 ? 0 : leftViewMonth + 1;
3173
- const rightViewYear = leftViewMonth === 11 ? leftViewYear + 1 : leftViewYear;
3174
- const prevMonth = () => {
3175
- if (leftViewMonth === 0) {
3176
- setLeftViewMonth(11);
3177
- setLeftViewYear((y) => y - 1);
3178
- } else setLeftViewMonth((m) => m - 1);
2975
+ const handleHourChange = (delta) => {
2976
+ const h = (hour - 1 + delta + 12) % 12 + 1;
2977
+ setHour(h);
2978
+ if (selectedDate) commitDate(selectedDate, h, minute, ampm);
3179
2979
  };
3180
- const nextMonth = () => {
3181
- if (leftViewMonth === 11) {
3182
- setLeftViewMonth(0);
3183
- setLeftViewYear((y) => y + 1);
3184
- } else setLeftViewMonth((m) => m + 1);
2980
+ const handleMinuteChange = (delta) => {
2981
+ const m = (minute + delta + 60) % 60;
2982
+ setMinute(m);
2983
+ if (selectedDate) commitDate(selectedDate, hour, m, ampm);
3185
2984
  };
3186
- const daysUntilToday = draftStart ? Math.max(0, daysBetween(draftStart, today2)) : 0;
3187
- const daysFromToday = draftEnd ? Math.max(0, daysBetween(today2, draftEnd)) : 0;
3188
- const handleDaysUntilChange = (e) => {
3189
- const n = parseInt(e.target.value, 10);
3190
- if (!isNaN(n) && n >= 0) {
3191
- const d = addDays(today2, -n);
3192
- setDraftStart(d);
3193
- setStartInputStr(formatShort(d));
3194
- }
2985
+ const handleAmpmToggle = (val) => {
2986
+ setAmpm(val);
2987
+ if (selectedDate) commitDate(selectedDate, hour, minute, val);
3195
2988
  };
3196
- const handleDaysFromChange = (e) => {
3197
- const n = parseInt(e.target.value, 10);
3198
- if (!isNaN(n) && n >= 0) {
3199
- const d = addDays(today2, n);
3200
- setDraftEnd(d);
3201
- setEndInputStr(formatShort(d));
3202
- }
2989
+ const handleHourInput = (e) => {
2990
+ let v = parseInt(e.target.value, 10);
2991
+ if (isNaN(v)) return;
2992
+ v = Math.max(1, Math.min(12, v));
2993
+ setHour(v);
2994
+ if (selectedDate) commitDate(selectedDate, v, minute, ampm);
3203
2995
  };
3204
- const handleStartInputChange = (e) => {
3205
- const raw = e.target.value;
3206
- setStartInputStr(raw);
3207
- const parsed = parseInputDate(raw);
3208
- if (parsed) setDraftStart(parsed);
3209
- else if (!raw) setDraftStart(null);
2996
+ const handleMinuteInput = (e) => {
2997
+ let v = parseInt(e.target.value, 10);
2998
+ if (isNaN(v)) return;
2999
+ v = Math.max(0, Math.min(59, v));
3000
+ setMinute(v);
3001
+ if (selectedDate) commitDate(selectedDate, hour, v, ampm);
3210
3002
  };
3211
- const handleStartInputBlur = () => {
3212
- setStartInputStr(draftStart ? formatShort(draftStart) : "");
3003
+ const handleScrollHour = (idx) => {
3004
+ const h = idx + 1;
3005
+ setHour(h);
3006
+ if (selectedDate) commitDate(selectedDate, h, minute, ampm);
3213
3007
  };
3214
- const handleEndInputChange = (e) => {
3215
- const raw = e.target.value;
3216
- setEndInputStr(raw);
3217
- const parsed = parseInputDate(raw);
3218
- if (parsed) setDraftEnd(parsed);
3219
- else if (!raw) setDraftEnd(null);
3008
+ const handleScrollMinute = (idx) => {
3009
+ setMinute(idx);
3010
+ if (selectedDate) commitDate(selectedDate, hour, idx, ampm);
3220
3011
  };
3221
- const handleEndInputBlur = () => {
3222
- setEndInputStr(draftEnd ? formatShort(draftEnd) : "");
3012
+ const handleScrollAmpm = (idx) => {
3013
+ const ap = AMPMS[idx];
3014
+ setAmpm(ap);
3015
+ if (selectedDate) commitDate(selectedDate, hour, minute, ap);
3223
3016
  };
3224
- const isFloating = Boolean(displayStr || open);
3017
+ const prevMonth = () => {
3018
+ if (viewMonth === 0) {
3019
+ setViewMonth(11);
3020
+ setViewYear((y) => y - 1);
3021
+ } else setViewMonth((m) => m - 1);
3022
+ };
3023
+ const nextMonth = () => {
3024
+ if (viewMonth === 11) {
3025
+ setViewMonth(0);
3026
+ setViewYear((y) => y + 1);
3027
+ } else setViewMonth((m) => m + 1);
3028
+ };
3029
+ const firstDayOfWeek = new Date(viewYear, viewMonth, 1).getDay();
3030
+ const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
3031
+ const dayCells = [
3032
+ ...Array(firstDayOfWeek).fill(null),
3033
+ ...Array.from({ length: daysInMonth }, (_, i) => i + 1)
3034
+ ];
3035
+ const isFloating = Boolean(inputStr || open);
3225
3036
  const rootClasses = [
3226
3037
  "rf-text-field",
3227
3038
  `rf-text-field--${variant}`,
@@ -3232,14 +3043,15 @@ var DateRangeField = ({
3232
3043
  disabled ? "rf-text-field--disabled" : "",
3233
3044
  isFloating ? "rf-text-field--floating" : "",
3234
3045
  Boolean(label) ? "rf-text-field--has-label" : "",
3235
- "rf-text-field--adorned-end",
3046
+ variant !== "compact" ? "rf-text-field--adorned-end" : "",
3236
3047
  "rf-date-field",
3237
- "rf-date-range-field",
3238
3048
  fullWidth ? "rf-date-field--full-width" : "",
3239
3049
  sxClass,
3240
3050
  className
3241
3051
  ].filter(Boolean).join(" ");
3242
- const inputPlaceholder = variant === "outlined" ? " " : void 0;
3052
+ const inputPlaceholder = placeholder || (variant === "outlined" ? " " : void 0);
3053
+ const todayDate = today();
3054
+ const isSideVariant = type === "datetime-side" || type === "datetime-scroll";
3243
3055
  return /* @__PURE__ */ React71.createElement("div", { ref: containerRef, className: rootClasses, style }, /* @__PURE__ */ React71.createElement("div", { className: "rf-date-field__anchor" }, /* @__PURE__ */ React71.createElement(
3244
3056
  "div",
3245
3057
  {
@@ -3255,8 +3067,8 @@ var DateRangeField = ({
3255
3067
  id: inputId,
3256
3068
  className: "rf-text-field__input",
3257
3069
  type: "text",
3258
- value: displayStr,
3259
- readOnly: true,
3070
+ value: inputStr,
3071
+ onChange: handleInputChange,
3260
3072
  placeholder: inputPlaceholder,
3261
3073
  disabled,
3262
3074
  onClick: (e) => e.stopPropagation(),
@@ -3276,556 +3088,759 @@ var DateRangeField = ({
3276
3088
  e.stopPropagation();
3277
3089
  if (!disabled) setOpen((o) => !o);
3278
3090
  },
3279
- "aria-label": "Pick date range"
3091
+ "aria-label": "Pick date"
3280
3092
  },
3281
- /* @__PURE__ */ React71.createElement(CalendarIcon2, null)
3093
+ /* @__PURE__ */ React71.createElement(CalendarIcon, null)
3282
3094
  )),
3283
3095
  label && /* @__PURE__ */ React71.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, " ", required && /* @__PURE__ */ React71.createElement("span", { className: "rf-text-field__asterisk" }, "*")),
3284
- variant === "outlined" && /* @__PURE__ */ React71.createElement("fieldset", { className: "rf-text-field__notch" }, label ? /* @__PURE__ */ React71.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ React71.createElement("span", null, label, required ? " *" : "")) : /* @__PURE__ */ React71.createElement("legend", { className: "rf-text-field__legend--empty" }))
3285
- ), open && !disabled && (pickerType === "panel" ? (
3286
- /* ── Panel Mode ── */
3287
- /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker rf-dr-picker--panel", onMouseDown: (e) => e.preventDefault() }, /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__presets" }, PRESETS.map((p, i) => /* @__PURE__ */ React71.createElement(React71.Fragment, { key: p.id }, i > 0 && /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__preset-sep" }), /* @__PURE__ */ React71.createElement(
3288
- "button",
3289
- {
3290
- type: "button",
3291
- className: [
3292
- "rf-dr-picker__preset-btn",
3293
- activePreset === p.id ? "rf-dr-picker__preset-btn--active" : ""
3294
- ].filter(Boolean).join(" "),
3295
- onClick: () => handlePreset(p.id)
3296
- },
3297
- p.label
3298
- )))), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__manual" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__date-field-wrap" }, /* @__PURE__ */ React71.createElement(
3096
+ variant === "outlined" && /* @__PURE__ */ React71.createElement("fieldset", { className: "rf-text-field__notch" }, label && /* @__PURE__ */ React71.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ React71.createElement("span", null, label, required ? " *" : "")))
3097
+ ), open && !disabled && createPortal(
3098
+ /* @__PURE__ */ React71.createElement(
3299
3099
  "div",
3300
3100
  {
3101
+ ref: pickerRef,
3301
3102
  className: [
3302
- "rf-dr-picker__date-field",
3303
- inlineCal === "start" ? "rf-dr-picker__date-field--active" : ""
3304
- ].filter(Boolean).join(" ")
3103
+ "rf-date-picker",
3104
+ "rf-date-picker--portaled",
3105
+ isSideVariant ? "rf-date-picker--side" : "",
3106
+ dropUp ? "rf-date-picker--drop-up" : ""
3107
+ ].filter(Boolean).join(" "),
3108
+ style: (() => {
3109
+ const rect = containerRef.current?.getBoundingClientRect();
3110
+ if (!rect) return {};
3111
+ const top = rect.bottom + 6;
3112
+ const spaceBelow = window.innerHeight - rect.bottom - 6;
3113
+ const useDropUp = spaceBelow < 350 && rect.top > spaceBelow;
3114
+ return {
3115
+ position: "fixed",
3116
+ left: rect.left,
3117
+ ...useDropUp ? { bottom: window.innerHeight - rect.top + 6 } : { top },
3118
+ zIndex: 99999
3119
+ };
3120
+ })(),
3121
+ onMouseDown: (e) => e.preventDefault()
3305
3122
  },
3306
- /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-picker__date-floating-label" }, "Start Date"),
3307
- /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__date-display" }, /* @__PURE__ */ React71.createElement(
3308
- "input",
3123
+ /* @__PURE__ */ React71.createElement("div", { className: isSideVariant ? "rf-date-picker__cal-col" : void 0 }, /* @__PURE__ */ React71.createElement(
3124
+ CalendarBody,
3309
3125
  {
3310
- type: "text",
3311
- className: "rf-dr-picker__date-input",
3312
- value: startInputStr,
3313
- placeholder: "DD Mon YYYY",
3314
- onChange: handleStartInputChange,
3315
- onBlur: handleStartInputBlur,
3316
- onMouseDown: (e) => e.stopPropagation()
3126
+ viewMonth,
3127
+ viewYear,
3128
+ selectedDate,
3129
+ todayDate,
3130
+ dayCells,
3131
+ onDayClick: handleDayClick,
3132
+ onPrev: prevMonth,
3133
+ onNext: nextMonth,
3134
+ onMonthSelect: setViewMonth,
3135
+ onYearSelect: setViewYear
3136
+ }
3137
+ ), type === "datetime" && /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__time-section" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__time-label" }, "Time"), /* @__PURE__ */ React71.createElement(
3138
+ SpinnerPanel,
3139
+ {
3140
+ hour,
3141
+ minute,
3142
+ ampm,
3143
+ onHourChange: handleHourChange,
3144
+ onMinuteChange: handleMinuteChange,
3145
+ onHourInput: handleHourInput,
3146
+ onMinuteInput: handleMinuteInput,
3147
+ onAmpmToggle: handleAmpmToggle
3148
+ }
3149
+ )), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__divider" }), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__footer" }, /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__footer-btn", onClick: handleToday }, "Today"), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-date-picker__footer-btn rf-date-picker__footer-btn--clear", onClick: handleClear }, "Clear"))),
3150
+ type === "datetime-side" && /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__side-panel" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__side-label" }, "Time"), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__side-spinner" }, /* @__PURE__ */ React71.createElement(
3151
+ SpinnerPanel,
3152
+ {
3153
+ hour,
3154
+ minute,
3155
+ ampm,
3156
+ onHourChange: handleHourChange,
3157
+ onMinuteChange: handleMinuteChange,
3158
+ onHourInput: handleHourInput,
3159
+ onMinuteInput: handleMinuteInput,
3160
+ onAmpmToggle: handleAmpmToggle
3161
+ }
3162
+ )), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__side-time-display" }, String(hour).padStart(2, "0"), ":", String(minute).padStart(2, "0"), " ", ampm)),
3163
+ type === "datetime-scroll" && /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__side-panel" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__side-label" }, "Time"), /* @__PURE__ */ React71.createElement("div", { className: "rf-timescroll" }, /* @__PURE__ */ React71.createElement(
3164
+ ScrollColumn,
3165
+ {
3166
+ items: HOURS,
3167
+ selected: hour - 1,
3168
+ onSelect: handleScrollHour
3169
+ }
3170
+ ), /* @__PURE__ */ React71.createElement("div", { className: "rf-timescroll__colon" }, ":"), /* @__PURE__ */ React71.createElement(
3171
+ ScrollColumn,
3172
+ {
3173
+ items: MINUTES,
3174
+ selected: minute,
3175
+ onSelect: handleScrollMinute
3317
3176
  }
3318
3177
  ), /* @__PURE__ */ React71.createElement(
3319
- "button",
3178
+ ScrollColumn,
3320
3179
  {
3321
- type: "button",
3322
- className: "rf-dr-picker__cal-icon-btn",
3323
- onMouseDown: (e) => e.stopPropagation(),
3324
- onClick: () => setInlineCal((v) => v === "start" ? null : "start"),
3325
- "aria-label": "Pick start date"
3326
- },
3327
- /* @__PURE__ */ React71.createElement(CalendarIcon2, null)
3328
- ))
3329
- ), inlineCal === "start" && /* @__PURE__ */ React71.createElement(
3330
- MiniCalendar,
3331
- {
3332
- selectedDate: draftStart,
3333
- todayDate: today2,
3334
- onSelect: (d) => {
3335
- setDraftStart(d);
3336
- setStartInputStr(formatShort(d));
3337
- },
3338
- onClose: () => setInlineCal(null)
3339
- }
3340
- )), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__date-field-wrap" }, /* @__PURE__ */ React71.createElement(
3180
+ items: AMPMS,
3181
+ selected: ampm === "AM" ? 0 : 1,
3182
+ onSelect: handleScrollAmpm,
3183
+ infinite: false
3184
+ }
3185
+ )), /* @__PURE__ */ React71.createElement("div", { className: "rf-date-picker__side-time-display" }, String(hour).padStart(2, "0"), ":", String(minute).padStart(2, "0"), " ", ampm))
3186
+ ),
3187
+ document.body
3188
+ )), helperText && /* @__PURE__ */ React71.createElement("div", { className: "rf-text-field__helper-text" }, helperText));
3189
+ };
3190
+ DateField.displayName = "DateField";
3191
+
3192
+ // lib/TextFields/DateRangeField.tsx
3193
+ import React72, {
3194
+ useState as useState7,
3195
+ useRef as useRef6,
3196
+ useEffect as useEffect7
3197
+ } from "react";
3198
+ var WEEKDAYS2 = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"];
3199
+ var MONTHS2 = [
3200
+ "January",
3201
+ "February",
3202
+ "March",
3203
+ "April",
3204
+ "May",
3205
+ "June",
3206
+ "July",
3207
+ "August",
3208
+ "September",
3209
+ "October",
3210
+ "November",
3211
+ "December"
3212
+ ];
3213
+ var MONTHS_SHORT2 = [
3214
+ "Jan",
3215
+ "Feb",
3216
+ "Mar",
3217
+ "Apr",
3218
+ "May",
3219
+ "Jun",
3220
+ "Jul",
3221
+ "Aug",
3222
+ "Sep",
3223
+ "Oct",
3224
+ "Nov",
3225
+ "Dec"
3226
+ ];
3227
+ var PRESETS = [
3228
+ { id: "today", label: "Today" },
3229
+ { id: "this_week", label: "This week" },
3230
+ { id: "this_month", label: "This month" },
3231
+ { id: "till_date", label: "Till date" },
3232
+ { id: "all", label: "All" }
3233
+ ];
3234
+ var todayFn = () => {
3235
+ const t = /* @__PURE__ */ new Date();
3236
+ return new Date(t.getFullYear(), t.getMonth(), t.getDate());
3237
+ };
3238
+ var isoToDate2 = (iso) => {
3239
+ if (!iso) return null;
3240
+ const parts = iso.split("-").map(Number);
3241
+ if (parts.length < 3 || !parts[0] || !parts[1] || !parts[2]) return null;
3242
+ return new Date(parts[0], parts[1] - 1, parts[2]);
3243
+ };
3244
+ var dateToISO = (d) => {
3245
+ const y = d.getFullYear();
3246
+ const mo = String(d.getMonth() + 1).padStart(2, "0");
3247
+ const dd = String(d.getDate()).padStart(2, "0");
3248
+ return `${y}-${mo}-${dd}`;
3249
+ };
3250
+ var formatShort = (d) => `${String(d.getDate()).padStart(2, "0")} ${MONTHS_SHORT2[d.getMonth()]} ${d.getFullYear()}`;
3251
+ var parseInputDate = (str) => {
3252
+ const s2 = str.trim();
3253
+ if (!s2) return null;
3254
+ const shortMatch = s2.match(/^(\d{1,2})\s+([A-Za-z]+)\s+(\d{4})$/);
3255
+ if (shortMatch) {
3256
+ const day = parseInt(shortMatch[1], 10);
3257
+ const monthIdx = MONTHS_SHORT2.findIndex((m) => m.toLowerCase() === shortMatch[2].toLowerCase());
3258
+ const year = parseInt(shortMatch[3], 10);
3259
+ if (monthIdx !== -1 && day >= 1 && day <= 31 && year >= 1e3) {
3260
+ const d = new Date(year, monthIdx, day);
3261
+ if (!isNaN(d.getTime())) return d;
3262
+ }
3263
+ }
3264
+ const slashMatch = s2.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
3265
+ if (slashMatch) {
3266
+ const d = new Date(parseInt(slashMatch[3], 10), parseInt(slashMatch[2], 10) - 1, parseInt(slashMatch[1], 10));
3267
+ if (!isNaN(d.getTime())) return d;
3268
+ }
3269
+ const isoMatch = s2.match(/^(\d{4})-(\d{2})-(\d{2})$/);
3270
+ if (isoMatch) {
3271
+ const d = new Date(parseInt(isoMatch[1], 10), parseInt(isoMatch[2], 10) - 1, parseInt(isoMatch[3], 10));
3272
+ if (!isNaN(d.getTime())) return d;
3273
+ }
3274
+ return null;
3275
+ };
3276
+ var isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
3277
+ var daysBetween = (a, b) => Math.round((b.getTime() - a.getTime()) / (1e3 * 60 * 60 * 24));
3278
+ var addDays = (d, n) => {
3279
+ const r = new Date(d.getTime());
3280
+ r.setDate(r.getDate() + n);
3281
+ return r;
3282
+ };
3283
+ var getPresetRange = (preset, currentStart) => {
3284
+ const today2 = todayFn();
3285
+ switch (preset) {
3286
+ case "today":
3287
+ return { start: dateToISO(today2), end: dateToISO(today2) };
3288
+ case "this_week": {
3289
+ const day = today2.getDay();
3290
+ const monday = addDays(today2, day === 0 ? -6 : -(day - 1));
3291
+ return { start: dateToISO(monday), end: dateToISO(addDays(monday, 6)) };
3292
+ }
3293
+ case "this_month": {
3294
+ const start = new Date(today2.getFullYear(), today2.getMonth(), 1);
3295
+ const end = new Date(today2.getFullYear(), today2.getMonth() + 1, 0);
3296
+ return { start: dateToISO(start), end: dateToISO(end) };
3297
+ }
3298
+ case "till_date": {
3299
+ const start = currentStart ?? addDays(today2, -30);
3300
+ return { start: dateToISO(start), end: dateToISO(today2) };
3301
+ }
3302
+ case "all":
3303
+ return { start: dateToISO(new Date(2e3, 0, 1)), end: dateToISO(today2) };
3304
+ default:
3305
+ return { start: "", end: "" };
3306
+ }
3307
+ };
3308
+ var detectPreset = (start, end) => {
3309
+ if (!start || !end) return null;
3310
+ const today2 = todayFn();
3311
+ if (isSameDay2(start, today2) && isSameDay2(end, today2)) return "today";
3312
+ const day = today2.getDay();
3313
+ const monday = addDays(today2, day === 0 ? -6 : -(day - 1));
3314
+ if (isSameDay2(start, monday) && isSameDay2(end, addDays(monday, 6))) return "this_week";
3315
+ const monthStart = new Date(today2.getFullYear(), today2.getMonth(), 1);
3316
+ const monthEnd = new Date(today2.getFullYear(), today2.getMonth() + 1, 0);
3317
+ if (isSameDay2(start, monthStart) && isSameDay2(end, monthEnd)) return "this_month";
3318
+ if (isSameDay2(end, today2)) return "till_date";
3319
+ if (isSameDay2(start, new Date(2e3, 0, 1)) && isSameDay2(end, today2)) return "all";
3320
+ return null;
3321
+ };
3322
+ var CalendarIcon2 = () => /* @__PURE__ */ React72.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React72.createElement("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2", ry: "2" }), /* @__PURE__ */ React72.createElement("line", { x1: "16", y1: "2", x2: "16", y2: "6" }), /* @__PURE__ */ React72.createElement("line", { x1: "8", y1: "2", x2: "8", y2: "6" }), /* @__PURE__ */ React72.createElement("line", { x1: "3", y1: "10", x2: "21", y2: "10" }));
3323
+ var RangeCalendarBody = ({
3324
+ viewYear,
3325
+ viewMonth,
3326
+ startDate,
3327
+ endDate,
3328
+ hoverDate,
3329
+ todayDate,
3330
+ onDayClick,
3331
+ onDayHover,
3332
+ onPrev,
3333
+ onNext,
3334
+ showPrev = true,
3335
+ showNext = true
3336
+ }) => {
3337
+ const firstDay = new Date(viewYear, viewMonth, 1).getDay();
3338
+ const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
3339
+ const dayCells = [
3340
+ ...Array(firstDay).fill(null),
3341
+ ...Array.from({ length: daysInMonth }, (_, i) => i + 1)
3342
+ ];
3343
+ const effectiveEnd = endDate ?? hoverDate;
3344
+ const hasRange = startDate != null && effectiveEnd != null && !isSameDay2(startDate, effectiveEnd);
3345
+ const lo = startDate && effectiveEnd ? startDate <= effectiveEnd ? startDate : effectiveEnd : null;
3346
+ const hi = startDate && effectiveEnd ? startDate <= effectiveEnd ? effectiveEnd : startDate : null;
3347
+ return /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-calendar" }, /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-calendar__header" }, /* @__PURE__ */ React72.createElement(
3348
+ "button",
3349
+ {
3350
+ type: "button",
3351
+ className: "rf-dr-calendar__nav-btn",
3352
+ onClick: onPrev,
3353
+ style: { visibility: showPrev ? "visible" : "hidden" },
3354
+ "aria-label": "Previous month"
3355
+ },
3356
+ "\u2039"
3357
+ ), /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-calendar__month-label" }, MONTHS2[viewMonth], " ", viewYear), /* @__PURE__ */ React72.createElement(
3358
+ "button",
3359
+ {
3360
+ type: "button",
3361
+ className: "rf-dr-calendar__nav-btn",
3362
+ onClick: onNext,
3363
+ style: { visibility: showNext ? "visible" : "hidden" },
3364
+ "aria-label": "Next month"
3365
+ },
3366
+ "\u203A"
3367
+ )), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-calendar__weekdays" }, WEEKDAYS2.map((w) => /* @__PURE__ */ React72.createElement("div", { key: w, className: "rf-dr-calendar__weekday" }, w))), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-calendar__grid" }, dayCells.map((day, idx) => {
3368
+ if (day === null) {
3369
+ return /* @__PURE__ */ React72.createElement("div", { key: `e-${idx}`, className: "rf-dr-calendar__cell rf-dr-calendar__cell--empty" });
3370
+ }
3371
+ const cellDate = new Date(viewYear, viewMonth, day);
3372
+ const isStart = startDate ? isSameDay2(cellDate, startDate) : false;
3373
+ const isEnd = endDate ? isSameDay2(cellDate, endDate) : false;
3374
+ const isToday = isSameDay2(cellDate, todayDate);
3375
+ const isInRange = lo && hi ? cellDate > lo && cellDate < hi : false;
3376
+ const isRangeStart = hasRange && lo ? isSameDay2(cellDate, lo) : false;
3377
+ const isRangeEnd = hasRange && hi ? isSameDay2(cellDate, hi) : false;
3378
+ const cellClasses = [
3379
+ "rf-dr-calendar__cell",
3380
+ isInRange ? "rf-dr-calendar__cell--in-range" : "",
3381
+ isRangeStart ? "rf-dr-calendar__cell--range-start" : "",
3382
+ isRangeEnd ? "rf-dr-calendar__cell--range-end" : ""
3383
+ ].filter(Boolean).join(" ");
3384
+ const dayClasses = [
3385
+ "rf-dr-calendar__day",
3386
+ isStart || isEnd ? "rf-dr-calendar__day--selected" : "",
3387
+ isToday && !isStart && !isEnd ? "rf-dr-calendar__day--today" : ""
3388
+ ].filter(Boolean).join(" ");
3389
+ return /* @__PURE__ */ React72.createElement(
3341
3390
  "div",
3342
3391
  {
3343
- className: [
3344
- "rf-dr-picker__date-field",
3345
- inlineCal === "end" ? "rf-dr-picker__date-field--active" : ""
3346
- ].filter(Boolean).join(" ")
3392
+ key: day,
3393
+ className: cellClasses,
3394
+ onMouseEnter: () => onDayHover(cellDate),
3395
+ onMouseLeave: () => onDayHover(null)
3347
3396
  },
3348
- /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-picker__date-floating-label" }, "End Date"),
3349
- /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__date-display" }, /* @__PURE__ */ React71.createElement(
3350
- "input",
3351
- {
3352
- type: "text",
3353
- className: "rf-dr-picker__date-input",
3354
- value: endInputStr,
3355
- placeholder: "DD Mon YYYY",
3356
- onChange: handleEndInputChange,
3357
- onBlur: handleEndInputBlur,
3358
- onMouseDown: (e) => e.stopPropagation()
3359
- }
3360
- ), /* @__PURE__ */ React71.createElement(
3397
+ /* @__PURE__ */ React72.createElement(
3361
3398
  "button",
3362
3399
  {
3363
3400
  type: "button",
3364
- className: "rf-dr-picker__cal-icon-btn",
3365
- onMouseDown: (e) => e.stopPropagation(),
3366
- onClick: () => setInlineCal((v) => v === "end" ? null : "end"),
3367
- "aria-label": "Pick end date"
3368
- },
3369
- /* @__PURE__ */ React71.createElement(CalendarIcon2, null)
3370
- ))
3371
- ), inlineCal === "end" && /* @__PURE__ */ React71.createElement(
3372
- MiniCalendar,
3373
- {
3374
- selectedDate: draftEnd,
3375
- todayDate: today2,
3376
- onSelect: (d) => {
3377
- setDraftEnd(d);
3378
- setEndInputStr(formatShort(d));
3401
+ className: dayClasses,
3402
+ onClick: () => onDayClick(cellDate)
3379
3403
  },
3380
- onClose: () => setInlineCal(null)
3381
- }
3382
- )), !inlineCal && /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__days-section" }, /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__days-row" }, /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-picker__days-label" }, "Days until today"), /* @__PURE__ */ React71.createElement(
3383
- "input",
3384
- {
3385
- type: "number",
3386
- className: "rf-dr-picker__days-input",
3387
- value: draftStart ? daysUntilToday : "",
3388
- min: 0,
3389
- onChange: handleDaysUntilChange,
3390
- onMouseDown: (e) => e.stopPropagation(),
3391
- placeholder: "\u2014"
3392
- }
3393
- )), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__days-row" }, /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-picker__days-label" }, "Days from today"), /* @__PURE__ */ React71.createElement(
3394
- "input",
3395
- {
3396
- type: "number",
3397
- className: "rf-dr-picker__days-input",
3398
- value: draftEnd ? daysFromToday : "",
3399
- min: 0,
3400
- onChange: handleDaysFromChange,
3401
- onMouseDown: (e) => e.stopPropagation(),
3402
- placeholder: "\u2014"
3403
- }
3404
- ))), /* @__PURE__ */ React71.createElement("div", { style: { flex: 1 } }), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__footer" }, /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-dr-picker__close-btn", onClick: handleClose }, "CLOSE"), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-dr-picker__apply-btn", onClick: handleApply }, "APPLY"))))
3405
- ) : (
3406
- /* ── Calendar Mode ── */
3407
- /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker rf-dr-picker--calendar", onMouseDown: (e) => e.preventDefault() }, /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__calendars" }, /* @__PURE__ */ React71.createElement(
3408
- RangeCalendarBody,
3409
- {
3410
- viewYear: leftViewYear,
3411
- viewMonth: leftViewMonth,
3412
- startDate: draftStart,
3413
- endDate: draftEnd,
3414
- hoverDate: selecting === "end" ? hoverDate : null,
3415
- todayDate: today2,
3416
- onDayClick: handleCalDayClick,
3417
- onDayHover: setHoverDate,
3418
- onPrev: prevMonth,
3419
- onNext: nextMonth,
3420
- showNext: false
3421
- }
3422
- ), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__cal-col-divider" }), /* @__PURE__ */ React71.createElement(
3423
- RangeCalendarBody,
3424
- {
3425
- viewYear: rightViewYear,
3426
- viewMonth: rightViewMonth,
3427
- startDate: draftStart,
3428
- endDate: draftEnd,
3429
- hoverDate: selecting === "end" ? hoverDate : null,
3430
- todayDate: today2,
3431
- onDayClick: handleCalDayClick,
3432
- onDayHover: setHoverDate,
3433
- onPrev: prevMonth,
3434
- onNext: nextMonth,
3435
- showPrev: false
3436
- }
3437
- )), selecting === "end" && draftStart && /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__cal-hint" }, /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-picker__cal-hint-dot" }), /* @__PURE__ */ React71.createElement("span", null, "Select end date \xB7 started from ", /* @__PURE__ */ React71.createElement("strong", null, formatShort(draftStart)))), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__divider" }), /* @__PURE__ */ React71.createElement("div", { className: "rf-dr-picker__cal-footer" }, draftStart && draftEnd && /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-picker__cal-range-label" }, formatShort(draftStart <= draftEnd ? draftStart : draftEnd), " \u2013 ", formatShort(draftStart <= draftEnd ? draftEnd : draftStart), /* @__PURE__ */ React71.createElement("span", { className: "rf-dr-picker__cal-range-days" }, " ", "(", Math.abs(daysBetween(draftStart, draftEnd)) + 1, " days)")), /* @__PURE__ */ React71.createElement("div", { style: { flex: 1 } }), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-dr-picker__close-btn", onClick: handleClose }, "CLOSE"), /* @__PURE__ */ React71.createElement("button", { type: "button", className: "rf-dr-picker__apply-btn", onClick: handleApply }, "APPLY")))
3438
- ))), helperText && /* @__PURE__ */ React71.createElement("div", { className: "rf-text-field__helper-text" }, helperText));
3404
+ day
3405
+ )
3406
+ );
3407
+ })));
3439
3408
  };
3440
- DateRangeField.displayName = "DateRangeField";
3441
-
3442
- // lib/TextFields/Autocomplete.tsx
3443
- import React72, {
3444
- useState as useState7,
3445
- useRef as useRef6,
3446
- useEffect as useEffect7,
3447
- useCallback as useCallback2
3448
- } from "react";
3449
- import ReactDOM2 from "react-dom";
3450
- var ChevronDownIcon = () => /* @__PURE__ */ React72.createElement("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React72.createElement("polyline", { points: "6 9 12 15 18 9" }));
3451
- var CloseSmIcon = ({ size = 16 }) => /* @__PURE__ */ React72.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }, /* @__PURE__ */ React72.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), /* @__PURE__ */ React72.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" }));
3452
- var CheckIcon = () => /* @__PURE__ */ React72.createElement("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React72.createElement("polyline", { points: "20 6 9 17 4 12" }));
3453
- function defaultGetLabel(option) {
3454
- if (option === null || option === void 0) return "";
3455
- if (typeof option === "string") return option;
3456
- if (typeof option === "object" && "label" in option)
3457
- return String(option.label);
3458
- return String(option);
3459
- }
3460
- function defaultFilter(options, inputValue, getLabel) {
3461
- if (!inputValue) return options;
3462
- const q = inputValue.toLowerCase();
3463
- return options.filter((o) => getLabel(o).toLowerCase().includes(q));
3464
- }
3465
- function AutocompleteInner(props, _ref) {
3466
- const {
3467
- options,
3468
- value,
3469
- onChange,
3470
- inputValue: controlledInput,
3471
- onInputChange,
3472
- getOptionLabel = defaultGetLabel,
3473
- isOptionEqualToValue,
3474
- groupBy,
3475
- filterOptions,
3476
- renderOption,
3477
- getOptionDisabled,
3478
- multiple = false,
3479
- freeSolo = false,
3480
- clearable = true,
3481
- loading = false,
3482
- loadingText = "Loading\u2026",
3483
- noOptionsText = "No options",
3484
- limitTags,
3485
- label,
3486
- placeholder,
3487
- variant = "outlined",
3488
- size = "medium",
3489
- error = false,
3490
- helperText,
3491
- fullWidth = false,
3492
- disabled = false,
3493
- required = false,
3494
- className = "",
3495
- style,
3496
- sx,
3497
- onOpen,
3498
- onClose
3499
- } = props;
3500
- const [open, setOpen] = useState7(false);
3501
- const [inputStr, setInputStr] = useState7("");
3502
- const [focusedIdx, setFocusedIdx] = useState7(-1);
3503
- const [popupStyle, setPopupStyle] = useState7({});
3504
- const containerRef = useRef6(null);
3505
- const inputRef = useRef6(null);
3506
- const listRef = useRef6(null);
3507
- const inputId = useRef6(`rf-ac-${Math.random().toString(36).slice(2, 9)}`).current;
3508
- const sxClass = useSx(sx);
3509
- const calcPopupStyle = useCallback2(() => {
3510
- if (!containerRef.current) return;
3511
- const rect = containerRef.current.getBoundingClientRect();
3512
- setPopupStyle({
3513
- top: rect.bottom + 4,
3514
- left: rect.left,
3515
- width: rect.width
3516
- });
3517
- }, []);
3518
- const activeInput = controlledInput !== void 0 ? controlledInput : inputStr;
3519
- const selectedValues = multiple ? Array.isArray(value) ? value : [] : value != null ? [value] : [];
3520
- const isEqual = useCallback2(
3521
- (a, b) => isOptionEqualToValue ? isOptionEqualToValue(a, b) : a === b,
3522
- [isOptionEqualToValue]
3523
- );
3524
- const isSelected = useCallback2(
3525
- (opt) => selectedValues.some((v) => isEqual(opt, v)),
3526
- [selectedValues, isEqual]
3527
- );
3528
- const filtered = filterOptions ? filterOptions(options, activeInput) : defaultFilter(options, activeInput, getOptionLabel);
3529
- const flatEntries = [];
3530
- if (groupBy) {
3531
- const groups = {};
3532
- const order = [];
3533
- filtered.forEach((opt) => {
3534
- const g = groupBy(opt);
3535
- if (!groups[g]) {
3536
- groups[g] = [];
3537
- order.push(g);
3538
- }
3539
- groups[g].push(opt);
3540
- });
3541
- order.forEach((g) => {
3542
- flatEntries.push({ kind: "group", label: g });
3543
- groups[g].forEach((opt) => {
3544
- flatEntries.push({ kind: "option", option: opt, flatIdx: flatEntries.filter((e) => e.kind === "option").length });
3545
- });
3546
- });
3547
- } else {
3548
- filtered.forEach((opt, i) => flatEntries.push({ kind: "option", option: opt, flatIdx: i }));
3549
- }
3550
- const selectableOptions = flatEntries.filter((e) => e.kind === "option");
3551
- const openPopup = useCallback2(() => {
3552
- if (disabled) return;
3553
- calcPopupStyle();
3554
- setOpen(true);
3555
- setFocusedIdx(-1);
3556
- onOpen?.();
3557
- }, [disabled, calcPopupStyle, onOpen]);
3558
- const closePopup = useCallback2(() => {
3559
- setOpen(false);
3560
- setFocusedIdx(-1);
3561
- onClose?.();
3562
- if (!freeSolo && !multiple && value == null) {
3563
- setInputStr("");
3564
- onInputChange?.("");
3409
+ var MiniCalendar = ({ selectedDate, todayDate, onSelect, onClose }) => {
3410
+ const init = selectedDate ?? todayDate;
3411
+ const [viewYear, setViewYear] = useState7(init.getFullYear());
3412
+ const [viewMonth, setViewMonth] = useState7(init.getMonth());
3413
+ const firstDay = new Date(viewYear, viewMonth, 1).getDay();
3414
+ const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
3415
+ const dayCells = [
3416
+ ...Array(firstDay).fill(null),
3417
+ ...Array.from({ length: daysInMonth }, (_, i) => i + 1)
3418
+ ];
3419
+ const prevMonth = () => {
3420
+ if (viewMonth === 0) {
3421
+ setViewMonth(11);
3422
+ setViewYear((y) => y - 1);
3423
+ } else setViewMonth((m) => m - 1);
3424
+ };
3425
+ const nextMonth = () => {
3426
+ if (viewMonth === 11) {
3427
+ setViewMonth(0);
3428
+ setViewYear((y) => y + 1);
3429
+ } else setViewMonth((m) => m + 1);
3430
+ };
3431
+ return /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-mini-cal" }, /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-mini-cal__header" }, /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-dr-calendar__nav-btn", onClick: prevMonth }, "\u2039"), /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-calendar__month-label", style: { fontSize: "0.88rem" } }, MONTHS2[viewMonth], " ", viewYear), /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-dr-calendar__nav-btn", onClick: nextMonth }, "\u203A")), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-calendar__weekdays" }, WEEKDAYS2.map((w) => /* @__PURE__ */ React72.createElement("div", { key: w, className: "rf-dr-calendar__weekday" }, w))), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-calendar__grid" }, dayCells.map((day, idx) => {
3432
+ if (day === null) {
3433
+ return /* @__PURE__ */ React72.createElement("div", { key: `e-${idx}`, className: "rf-dr-calendar__cell rf-dr-calendar__cell--empty" });
3565
3434
  }
3566
- }, [freeSolo, multiple, value, onInputChange, onClose]);
3435
+ const cellDate = new Date(viewYear, viewMonth, day);
3436
+ const isSel = selectedDate ? isSameDay2(cellDate, selectedDate) : false;
3437
+ const isToday = isSameDay2(cellDate, todayDate);
3438
+ return /* @__PURE__ */ React72.createElement("div", { key: day, className: "rf-dr-calendar__cell" }, /* @__PURE__ */ React72.createElement(
3439
+ "button",
3440
+ {
3441
+ type: "button",
3442
+ className: [
3443
+ "rf-dr-calendar__day",
3444
+ isSel ? "rf-dr-calendar__day--selected" : "",
3445
+ isToday && !isSel ? "rf-dr-calendar__day--today" : ""
3446
+ ].filter(Boolean).join(" "),
3447
+ onClick: () => {
3448
+ onSelect(cellDate);
3449
+ onClose();
3450
+ }
3451
+ },
3452
+ day
3453
+ ));
3454
+ })));
3455
+ };
3456
+ var DateRangeField = ({
3457
+ label,
3458
+ value,
3459
+ onChange,
3460
+ pickerType = "panel",
3461
+ variant = "outlined",
3462
+ size = "medium",
3463
+ color = "primary",
3464
+ error = false,
3465
+ helperText,
3466
+ fullWidth = false,
3467
+ disabled = false,
3468
+ required = false,
3469
+ className = "",
3470
+ style,
3471
+ sx
3472
+ }) => {
3473
+ const sxClass = useSx(sx);
3474
+ const today2 = todayFn();
3475
+ const committedStart = value?.start ? isoToDate2(value.start) : null;
3476
+ const committedEnd = value?.end ? isoToDate2(value.end) : null;
3477
+ const [open, setOpen] = useState7(false);
3478
+ const [draftStart, setDraftStart] = useState7(committedStart);
3479
+ const [draftEnd, setDraftEnd] = useState7(committedEnd);
3480
+ const [activePreset, setActivePreset] = useState7(
3481
+ () => detectPreset(committedStart, committedEnd)
3482
+ );
3483
+ const [startInputStr, setStartInputStr] = useState7(() => committedStart ? formatShort(committedStart) : "");
3484
+ const [endInputStr, setEndInputStr] = useState7(() => committedEnd ? formatShort(committedEnd) : "");
3485
+ const [inlineCal, setInlineCal] = useState7(null);
3486
+ const [hoverDate, setHoverDate] = useState7(null);
3487
+ const [selecting, setSelecting] = useState7("start");
3488
+ const [leftViewYear, setLeftViewYear] = useState7(() => today2.getFullYear());
3489
+ const [leftViewMonth, setLeftViewMonth] = useState7(() => today2.getMonth());
3490
+ const containerRef = useRef6(null);
3491
+ const inputId = useRef6(`rf-dr-${Math.random().toString(36).substr(2, 9)}`).current;
3492
+ useEffect7(() => {
3493
+ const s2 = value?.start ? isoToDate2(value.start) : null;
3494
+ const e = value?.end ? isoToDate2(value.end) : null;
3495
+ setDraftStart(s2);
3496
+ setDraftEnd(e);
3497
+ setStartInputStr(s2 ? formatShort(s2) : "");
3498
+ setEndInputStr(e ? formatShort(e) : "");
3499
+ setActivePreset(detectPreset(s2, e));
3500
+ }, [value?.start, value?.end]);
3501
+ useEffect7(() => {
3502
+ setActivePreset(detectPreset(draftStart, draftEnd));
3503
+ }, [draftStart?.getTime(), draftEnd?.getTime()]);
3567
3504
  useEffect7(() => {
3568
3505
  if (!open) return;
3569
- const handleOutside = (e) => {
3506
+ const handler = (e) => {
3570
3507
  if (containerRef.current && !containerRef.current.contains(e.target)) {
3571
- closePopup();
3508
+ setOpen(false);
3509
+ setInlineCal(null);
3510
+ setDraftStart(committedStart);
3511
+ setDraftEnd(committedEnd);
3512
+ setStartInputStr(committedStart ? formatShort(committedStart) : "");
3513
+ setEndInputStr(committedEnd ? formatShort(committedEnd) : "");
3514
+ setActivePreset(detectPreset(committedStart, committedEnd));
3515
+ setSelecting("start");
3572
3516
  }
3573
3517
  };
3574
- document.addEventListener("mousedown", handleOutside);
3575
- window.addEventListener("scroll", calcPopupStyle, true);
3576
- window.addEventListener("resize", calcPopupStyle);
3577
- return () => {
3578
- document.removeEventListener("mousedown", handleOutside);
3579
- window.removeEventListener("scroll", calcPopupStyle, true);
3580
- window.removeEventListener("resize", calcPopupStyle);
3581
- };
3582
- }, [open, closePopup, calcPopupStyle]);
3583
- useEffect7(() => {
3584
- if (controlledInput !== void 0) return;
3585
- if (!multiple) {
3586
- const v = value;
3587
- setInputStr(v != null ? getOptionLabel(v) : "");
3518
+ document.addEventListener("mousedown", handler);
3519
+ return () => document.removeEventListener("mousedown", handler);
3520
+ }, [open, committedStart, committedEnd]);
3521
+ const displayStr = (() => {
3522
+ if (committedStart && committedEnd) {
3523
+ return `${formatShort(committedStart)} \u2013 ${formatShort(committedEnd)}`;
3588
3524
  }
3589
- }, [value, multiple, getOptionLabel, controlledInput]);
3590
- const selectOption = (opt) => {
3591
- if (getOptionDisabled?.(opt)) return;
3592
- if (multiple) {
3593
- const already = isSelected(opt);
3594
- const next = already ? selectedValues.filter((v) => !isEqual(v, opt)) : [...selectedValues, opt];
3595
- onChange?.(next);
3596
- setInputStr("");
3597
- onInputChange?.("");
3598
- inputRef.current?.focus();
3525
+ if (committedStart) return `${formatShort(committedStart)} \u2013`;
3526
+ return "";
3527
+ })();
3528
+ const handleApply = () => {
3529
+ if (draftStart && draftEnd) {
3530
+ const [s2, e] = draftStart <= draftEnd ? [draftStart, draftEnd] : [draftEnd, draftStart];
3531
+ onChange?.({ start: dateToISO(s2), end: dateToISO(e) });
3532
+ } else if (draftStart) {
3533
+ onChange?.({ start: dateToISO(draftStart), end: dateToISO(draftStart) });
3534
+ }
3535
+ setOpen(false);
3536
+ setInlineCal(null);
3537
+ };
3538
+ const handleClose = () => {
3539
+ setOpen(false);
3540
+ setInlineCal(null);
3541
+ setDraftStart(committedStart);
3542
+ setDraftEnd(committedEnd);
3543
+ setStartInputStr(committedStart ? formatShort(committedStart) : "");
3544
+ setEndInputStr(committedEnd ? formatShort(committedEnd) : "");
3545
+ setActivePreset(detectPreset(committedStart, committedEnd));
3546
+ setSelecting("start");
3547
+ };
3548
+ const handlePreset = (presetId) => {
3549
+ const range = getPresetRange(presetId, draftStart);
3550
+ const s2 = isoToDate2(range.start);
3551
+ const e = isoToDate2(range.end);
3552
+ setDraftStart(s2);
3553
+ setDraftEnd(e);
3554
+ setStartInputStr(s2 ? formatShort(s2) : "");
3555
+ setEndInputStr(e ? formatShort(e) : "");
3556
+ setInlineCal(null);
3557
+ };
3558
+ const handleCalDayClick = (d) => {
3559
+ if (selecting === "start") {
3560
+ setDraftStart(d);
3561
+ setDraftEnd(null);
3562
+ setSelecting("end");
3563
+ setActivePreset(null);
3599
3564
  } else {
3600
- onChange?.(opt);
3601
- setInputStr(getOptionLabel(opt));
3602
- onInputChange?.(getOptionLabel(opt));
3603
- closePopup();
3565
+ if (draftStart && d < draftStart) {
3566
+ setDraftEnd(draftStart);
3567
+ setDraftStart(d);
3568
+ } else {
3569
+ setDraftEnd(d);
3570
+ }
3571
+ setSelecting("start");
3572
+ setActivePreset(detectPreset(draftStart, d));
3604
3573
  }
3605
- setFocusedIdx(-1);
3606
3574
  };
3607
- const clearAll = (e) => {
3608
- e.stopPropagation();
3609
- onChange?.(multiple ? [] : null);
3610
- setInputStr("");
3611
- onInputChange?.("");
3612
- inputRef.current?.focus();
3575
+ const rightViewMonth = leftViewMonth === 11 ? 0 : leftViewMonth + 1;
3576
+ const rightViewYear = leftViewMonth === 11 ? leftViewYear + 1 : leftViewYear;
3577
+ const prevMonth = () => {
3578
+ if (leftViewMonth === 0) {
3579
+ setLeftViewMonth(11);
3580
+ setLeftViewYear((y) => y - 1);
3581
+ } else setLeftViewMonth((m) => m - 1);
3613
3582
  };
3614
- const removeTag = (opt, e) => {
3615
- e.stopPropagation();
3616
- const next = selectedValues.filter((v) => !isEqual(v, opt));
3617
- onChange?.(next);
3583
+ const nextMonth = () => {
3584
+ if (leftViewMonth === 11) {
3585
+ setLeftViewMonth(0);
3586
+ setLeftViewYear((y) => y + 1);
3587
+ } else setLeftViewMonth((m) => m + 1);
3618
3588
  };
3619
- const handleInputChange = (e) => {
3620
- const v = e.target.value;
3621
- setInputStr(v);
3622
- onInputChange?.(v);
3623
- if (!open) openPopup();
3589
+ const daysUntilToday = draftStart ? Math.max(0, daysBetween(draftStart, today2)) : 0;
3590
+ const daysFromToday = draftEnd ? Math.max(0, daysBetween(today2, draftEnd)) : 0;
3591
+ const handleDaysUntilChange = (e) => {
3592
+ const n = parseInt(e.target.value, 10);
3593
+ if (!isNaN(n) && n >= 0) {
3594
+ const d = addDays(today2, -n);
3595
+ setDraftStart(d);
3596
+ setStartInputStr(formatShort(d));
3597
+ }
3624
3598
  };
3625
- const handleKeyDown = (e) => {
3626
- if (e.key === "ArrowDown") {
3627
- e.preventDefault();
3628
- if (!open) {
3629
- openPopup();
3630
- return;
3631
- }
3632
- setFocusedIdx((i) => {
3633
- const next = (i + 1) % selectableOptions.length;
3634
- scrollOptionIntoView(next);
3635
- return next;
3636
- });
3637
- } else if (e.key === "ArrowUp") {
3638
- e.preventDefault();
3639
- if (!open) {
3640
- openPopup();
3641
- return;
3642
- }
3643
- setFocusedIdx((i) => {
3644
- const next = (i - 1 + selectableOptions.length) % selectableOptions.length;
3645
- scrollOptionIntoView(next);
3646
- return next;
3647
- });
3648
- } else if (e.key === "Enter") {
3649
- e.preventDefault();
3650
- if (!open) {
3651
- openPopup();
3652
- return;
3653
- }
3654
- if (focusedIdx >= 0 && focusedIdx < selectableOptions.length) {
3655
- selectOption(selectableOptions[focusedIdx].option);
3656
- } else if (freeSolo && activeInput) {
3657
- onChange?.(activeInput);
3658
- if (!multiple) closePopup();
3659
- }
3660
- } else if (e.key === "Escape") {
3661
- closePopup();
3662
- } else if (e.key === "Backspace" && multiple && !activeInput && selectedValues.length > 0) {
3663
- removeTag(selectedValues[selectedValues.length - 1], { stopPropagation: () => {
3664
- } });
3599
+ const handleDaysFromChange = (e) => {
3600
+ const n = parseInt(e.target.value, 10);
3601
+ if (!isNaN(n) && n >= 0) {
3602
+ const d = addDays(today2, n);
3603
+ setDraftEnd(d);
3604
+ setEndInputStr(formatShort(d));
3665
3605
  }
3666
3606
  };
3667
- const scrollOptionIntoView = (idx) => {
3668
- requestAnimationFrame(() => {
3669
- const el = listRef.current?.querySelector(`[data-idx="${idx}"]`);
3670
- el?.scrollIntoView({ block: "nearest" });
3671
- });
3607
+ const handleStartInputChange = (e) => {
3608
+ const raw = e.target.value;
3609
+ setStartInputStr(raw);
3610
+ const parsed = parseInputDate(raw);
3611
+ if (parsed) setDraftStart(parsed);
3612
+ else if (!raw) setDraftStart(null);
3613
+ };
3614
+ const handleStartInputBlur = () => {
3615
+ setStartInputStr(draftStart ? formatShort(draftStart) : "");
3616
+ };
3617
+ const handleEndInputChange = (e) => {
3618
+ const raw = e.target.value;
3619
+ setEndInputStr(raw);
3620
+ const parsed = parseInputDate(raw);
3621
+ if (parsed) setDraftEnd(parsed);
3622
+ else if (!raw) setDraftEnd(null);
3623
+ };
3624
+ const handleEndInputBlur = () => {
3625
+ setEndInputStr(draftEnd ? formatShort(draftEnd) : "");
3672
3626
  };
3673
- const hasClearable = clearable && !disabled && (multiple ? selectedValues.length > 0 : value != null);
3674
- const visibleTags = multiple && limitTags != null ? selectedValues.slice(0, limitTags) : selectedValues;
3675
- const hiddenCount = multiple && limitTags != null ? Math.max(0, selectedValues.length - limitTags) : 0;
3676
- const isFloating = Boolean(
3677
- open || activeInput || (multiple ? selectedValues.length > 0 : value != null)
3678
- );
3627
+ const isFloating = Boolean(displayStr || open);
3679
3628
  const rootClasses = [
3680
3629
  "rf-text-field",
3681
3630
  `rf-text-field--${variant}`,
3682
3631
  `rf-text-field--${size}`,
3683
- "rf-text-field--primary",
3632
+ `rf-text-field--${color}`,
3684
3633
  error ? "rf-text-field--error" : "",
3685
3634
  fullWidth ? "rf-text-field--full-width" : "",
3686
3635
  disabled ? "rf-text-field--disabled" : "",
3687
3636
  isFloating ? "rf-text-field--floating" : "",
3688
- label ? "rf-text-field--has-label" : "",
3637
+ Boolean(label) ? "rf-text-field--has-label" : "",
3689
3638
  "rf-text-field--adorned-end",
3690
- "rf-autocomplete",
3639
+ "rf-date-field",
3640
+ "rf-date-range-field",
3641
+ fullWidth ? "rf-date-field--full-width" : "",
3691
3642
  sxClass,
3692
3643
  className
3693
3644
  ].filter(Boolean).join(" ");
3694
- const inputPlaceholder = placeholder || (variant === "outlined" ? " " : void 0);
3695
- return /* @__PURE__ */ React72.createElement("div", { ref: containerRef, className: rootClasses, style }, /* @__PURE__ */ React72.createElement(
3645
+ const inputPlaceholder = variant === "outlined" ? " " : void 0;
3646
+ return /* @__PURE__ */ React72.createElement("div", { ref: containerRef, className: rootClasses, style }, /* @__PURE__ */ React72.createElement("div", { className: "rf-date-field__anchor" }, /* @__PURE__ */ React72.createElement(
3696
3647
  "div",
3697
3648
  {
3698
3649
  className: "rf-text-field__wrapper",
3699
3650
  onClick: () => {
3700
- if (!disabled) {
3701
- inputRef.current?.focus();
3702
- if (!open) openPopup();
3703
- }
3704
- }
3705
- },
3706
- multiple && visibleTags.map((opt, i) => /* @__PURE__ */ React72.createElement("span", { key: i, className: "rf-autocomplete__tag" }, /* @__PURE__ */ React72.createElement("span", { style: { overflow: "hidden", textOverflow: "ellipsis" } }, getOptionLabel(opt)), /* @__PURE__ */ React72.createElement(
3707
- "button",
3708
- {
3709
- type: "button",
3710
- className: "rf-autocomplete__tag-delete",
3711
- onMouseDown: (e) => e.preventDefault(),
3712
- onClick: (e) => removeTag(opt, e),
3713
- tabIndex: -1
3651
+ if (!disabled) setOpen((o) => !o);
3714
3652
  },
3715
- /* @__PURE__ */ React72.createElement(CloseSmIcon, { size: 12 })
3716
- ))),
3717
- hiddenCount > 0 && /* @__PURE__ */ React72.createElement("span", { className: "rf-autocomplete__tag-more" }, "+", hiddenCount, " more"),
3653
+ style: { cursor: disabled ? "default" : "pointer" }
3654
+ },
3718
3655
  /* @__PURE__ */ React72.createElement(
3719
3656
  "input",
3720
3657
  {
3721
- ref: inputRef,
3722
3658
  id: inputId,
3723
3659
  className: "rf-text-field__input",
3724
3660
  type: "text",
3725
- value: activeInput,
3726
- onChange: handleInputChange,
3727
- onFocus: () => {
3728
- if (!open) openPopup();
3729
- },
3730
- onKeyDown: handleKeyDown,
3731
- placeholder: !multiple || selectedValues.length === 0 ? inputPlaceholder : void 0,
3661
+ value: displayStr,
3662
+ readOnly: true,
3663
+ placeholder: inputPlaceholder,
3732
3664
  disabled,
3733
- autoComplete: "off",
3734
- role: "combobox",
3735
- "aria-expanded": open,
3736
- "aria-haspopup": "listbox",
3737
- "aria-autocomplete": "list"
3665
+ onClick: (e) => e.stopPropagation(),
3666
+ onFocus: () => {
3667
+ if (!disabled) setOpen(true);
3668
+ }
3738
3669
  }
3739
3670
  ),
3740
- label && /* @__PURE__ */ React72.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, required && /* @__PURE__ */ React72.createElement("span", { className: "rf-text-field__asterisk" }, " *")),
3741
- variant === "outlined" && /* @__PURE__ */ React72.createElement("fieldset", { className: "rf-text-field__notch" }, label ? /* @__PURE__ */ React72.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ React72.createElement("span", null, label, required ? " *" : "")) : /* @__PURE__ */ React72.createElement("legend", { className: "rf-text-field__legend--empty" })),
3742
- /* @__PURE__ */ React72.createElement("div", { className: "rf-autocomplete__endgroup" }, hasClearable && /* @__PURE__ */ React72.createElement(
3671
+ /* @__PURE__ */ React72.createElement("div", { className: "rf-text-field__adornment rf-text-field__adornment--end" }, /* @__PURE__ */ React72.createElement(
3743
3672
  "button",
3744
3673
  {
3745
3674
  type: "button",
3746
- className: "rf-autocomplete__icon-btn",
3747
- onMouseDown: (e) => e.preventDefault(),
3748
- onClick: clearAll,
3675
+ className: "rf-date-field__icon-btn",
3749
3676
  tabIndex: -1,
3750
- "aria-label": "Clear"
3677
+ disabled,
3678
+ onClick: (e) => {
3679
+ e.stopPropagation();
3680
+ if (!disabled) setOpen((o) => !o);
3681
+ },
3682
+ "aria-label": "Pick date range"
3751
3683
  },
3752
- /* @__PURE__ */ React72.createElement(CloseSmIcon, { size: 16 })
3753
- ), !freeSolo && /* @__PURE__ */ React72.createElement(
3684
+ /* @__PURE__ */ React72.createElement(CalendarIcon2, null)
3685
+ )),
3686
+ label && /* @__PURE__ */ React72.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, " ", required && /* @__PURE__ */ React72.createElement("span", { className: "rf-text-field__asterisk" }, "*")),
3687
+ variant === "outlined" && /* @__PURE__ */ React72.createElement("fieldset", { className: "rf-text-field__notch" }, label ? /* @__PURE__ */ React72.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ React72.createElement("span", null, label, required ? " *" : "")) : /* @__PURE__ */ React72.createElement("legend", { className: "rf-text-field__legend--empty" }))
3688
+ ), open && !disabled && (pickerType === "panel" ? (
3689
+ /* ── Panel Mode ── */
3690
+ /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker rf-dr-picker--panel", onMouseDown: (e) => e.preventDefault() }, /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__presets" }, PRESETS.map((p, i) => /* @__PURE__ */ React72.createElement(React72.Fragment, { key: p.id }, i > 0 && /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__preset-sep" }), /* @__PURE__ */ React72.createElement(
3754
3691
  "button",
3755
3692
  {
3756
3693
  type: "button",
3757
- className: `rf-autocomplete__icon-btn rf-autocomplete__icon-btn--popup ${open ? "rf-autocomplete__icon-btn--open" : ""}`,
3758
- onMouseDown: (e) => {
3759
- e.preventDefault();
3760
- open ? closePopup() : openPopup();
3761
- },
3762
- tabIndex: -1,
3763
- "aria-label": open ? "Close" : "Open"
3694
+ className: [
3695
+ "rf-dr-picker__preset-btn",
3696
+ activePreset === p.id ? "rf-dr-picker__preset-btn--active" : ""
3697
+ ].filter(Boolean).join(" "),
3698
+ onClick: () => handlePreset(p.id)
3764
3699
  },
3765
- /* @__PURE__ */ React72.createElement(ChevronDownIcon, null)
3766
- ))
3767
- ), helperText && /* @__PURE__ */ React72.createElement("div", { className: `rf-text-field__helper-text${error ? " rf-text-field__helper-text--error" : ""}` }, helperText), open && !disabled && ReactDOM2.createPortal(
3768
- /* @__PURE__ */ React72.createElement("div", { className: "rf-autocomplete__popup", role: "presentation", style: popupStyle }, loading ? /* @__PURE__ */ React72.createElement("div", { className: "rf-autocomplete__loading" }, /* @__PURE__ */ React72.createElement("span", { className: "rf-ac-spinner" }), loadingText) : flatEntries.length === 0 ? /* @__PURE__ */ React72.createElement("div", { className: "rf-autocomplete__no-options" }, noOptionsText) : /* @__PURE__ */ React72.createElement("ul", { ref: listRef, className: "rf-autocomplete__listbox", role: "listbox" }, groupBy ? (
3769
- // Grouped render
3770
- (() => {
3771
- const rendered = [];
3772
- let groupItems = [];
3773
- let currentGroup = "";
3774
- flatEntries.forEach((entry, ei) => {
3775
- if (entry.kind === "group") {
3776
- if (groupItems.length > 0) {
3777
- rendered.push(
3778
- /* @__PURE__ */ React72.createElement("li", { key: `g-${currentGroup}`, role: "presentation" }, /* @__PURE__ */ React72.createElement("div", { className: "rf-autocomplete__group-header" }, currentGroup), /* @__PURE__ */ React72.createElement("ul", { className: "rf-autocomplete__group-items", role: "group" }, groupItems))
3779
- );
3780
- groupItems = [];
3781
- }
3782
- currentGroup = entry.label;
3783
- } else {
3784
- const { option, flatIdx } = entry;
3785
- groupItems.push(renderOptionItem(option, flatIdx));
3786
- }
3787
- if (ei === flatEntries.length - 1 && groupItems.length > 0) {
3788
- rendered.push(
3789
- /* @__PURE__ */ React72.createElement("li", { key: `g-${currentGroup}`, role: "presentation" }, /* @__PURE__ */ React72.createElement("div", { className: "rf-autocomplete__group-header" }, currentGroup), /* @__PURE__ */ React72.createElement("ul", { className: "rf-autocomplete__group-items", role: "group" }, groupItems))
3790
- );
3791
- }
3792
- });
3793
- return rendered;
3794
- })()
3795
- ) : selectableOptions.map(({ option, flatIdx }) => renderOptionItem(option, flatIdx)))),
3796
- document.body
3797
- ));
3798
- function renderOptionItem(option, flatIdx) {
3799
- const selected = isSelected(option);
3800
- const focused = focusedIdx === flatIdx;
3801
- const optDisabled = getOptionDisabled?.(option) ?? false;
3802
- const label2 = getOptionLabel(option);
3803
- return /* @__PURE__ */ React72.createElement(
3804
- "li",
3700
+ p.label
3701
+ )))), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__manual" }, /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__date-field-wrap" }, /* @__PURE__ */ React72.createElement(
3702
+ "div",
3805
3703
  {
3806
- key: label2 + flatIdx,
3807
- "data-idx": flatIdx,
3808
- role: "option",
3809
- "aria-selected": selected,
3810
- "aria-disabled": optDisabled,
3811
3704
  className: [
3812
- "rf-autocomplete__option",
3813
- selected ? "rf-autocomplete__option--selected" : "",
3814
- focused ? "rf-autocomplete__option--focused" : "",
3815
- optDisabled ? "rf-autocomplete__option--disabled" : ""
3816
- ].filter(Boolean).join(" "),
3817
- onMouseEnter: () => setFocusedIdx(flatIdx),
3818
- onMouseLeave: () => setFocusedIdx(-1),
3819
- onMouseDown: (e) => e.preventDefault(),
3820
- onClick: () => selectOption(option)
3705
+ "rf-dr-picker__date-field",
3706
+ inlineCal === "start" ? "rf-dr-picker__date-field--active" : ""
3707
+ ].filter(Boolean).join(" ")
3821
3708
  },
3822
- renderOption ? renderOption(option, { selected, focused, index: flatIdx }) : /* @__PURE__ */ React72.createElement("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, label2),
3823
- !renderOption && /* @__PURE__ */ React72.createElement("span", { className: "rf-autocomplete__option-check" }, /* @__PURE__ */ React72.createElement(CheckIcon, null))
3824
- );
3825
- }
3826
- }
3827
- var Autocomplete = React72.forwardRef(AutocompleteInner);
3828
- Autocomplete.displayName = "Autocomplete";
3709
+ /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-picker__date-floating-label" }, "Start Date"),
3710
+ /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__date-display" }, /* @__PURE__ */ React72.createElement(
3711
+ "input",
3712
+ {
3713
+ type: "text",
3714
+ className: "rf-dr-picker__date-input",
3715
+ value: startInputStr,
3716
+ placeholder: "DD Mon YYYY",
3717
+ onChange: handleStartInputChange,
3718
+ onBlur: handleStartInputBlur,
3719
+ onMouseDown: (e) => e.stopPropagation()
3720
+ }
3721
+ ), /* @__PURE__ */ React72.createElement(
3722
+ "button",
3723
+ {
3724
+ type: "button",
3725
+ className: "rf-dr-picker__cal-icon-btn",
3726
+ onMouseDown: (e) => e.stopPropagation(),
3727
+ onClick: () => setInlineCal((v) => v === "start" ? null : "start"),
3728
+ "aria-label": "Pick start date"
3729
+ },
3730
+ /* @__PURE__ */ React72.createElement(CalendarIcon2, null)
3731
+ ))
3732
+ ), inlineCal === "start" && /* @__PURE__ */ React72.createElement(
3733
+ MiniCalendar,
3734
+ {
3735
+ selectedDate: draftStart,
3736
+ todayDate: today2,
3737
+ onSelect: (d) => {
3738
+ setDraftStart(d);
3739
+ setStartInputStr(formatShort(d));
3740
+ },
3741
+ onClose: () => setInlineCal(null)
3742
+ }
3743
+ )), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__date-field-wrap" }, /* @__PURE__ */ React72.createElement(
3744
+ "div",
3745
+ {
3746
+ className: [
3747
+ "rf-dr-picker__date-field",
3748
+ inlineCal === "end" ? "rf-dr-picker__date-field--active" : ""
3749
+ ].filter(Boolean).join(" ")
3750
+ },
3751
+ /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-picker__date-floating-label" }, "End Date"),
3752
+ /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__date-display" }, /* @__PURE__ */ React72.createElement(
3753
+ "input",
3754
+ {
3755
+ type: "text",
3756
+ className: "rf-dr-picker__date-input",
3757
+ value: endInputStr,
3758
+ placeholder: "DD Mon YYYY",
3759
+ onChange: handleEndInputChange,
3760
+ onBlur: handleEndInputBlur,
3761
+ onMouseDown: (e) => e.stopPropagation()
3762
+ }
3763
+ ), /* @__PURE__ */ React72.createElement(
3764
+ "button",
3765
+ {
3766
+ type: "button",
3767
+ className: "rf-dr-picker__cal-icon-btn",
3768
+ onMouseDown: (e) => e.stopPropagation(),
3769
+ onClick: () => setInlineCal((v) => v === "end" ? null : "end"),
3770
+ "aria-label": "Pick end date"
3771
+ },
3772
+ /* @__PURE__ */ React72.createElement(CalendarIcon2, null)
3773
+ ))
3774
+ ), inlineCal === "end" && /* @__PURE__ */ React72.createElement(
3775
+ MiniCalendar,
3776
+ {
3777
+ selectedDate: draftEnd,
3778
+ todayDate: today2,
3779
+ onSelect: (d) => {
3780
+ setDraftEnd(d);
3781
+ setEndInputStr(formatShort(d));
3782
+ },
3783
+ onClose: () => setInlineCal(null)
3784
+ }
3785
+ )), !inlineCal && /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__days-section" }, /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__days-row" }, /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-picker__days-label" }, "Days until today"), /* @__PURE__ */ React72.createElement(
3786
+ "input",
3787
+ {
3788
+ type: "number",
3789
+ className: "rf-dr-picker__days-input",
3790
+ value: draftStart ? daysUntilToday : "",
3791
+ min: 0,
3792
+ onChange: handleDaysUntilChange,
3793
+ onMouseDown: (e) => e.stopPropagation(),
3794
+ placeholder: "\u2014"
3795
+ }
3796
+ )), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__days-row" }, /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-picker__days-label" }, "Days from today"), /* @__PURE__ */ React72.createElement(
3797
+ "input",
3798
+ {
3799
+ type: "number",
3800
+ className: "rf-dr-picker__days-input",
3801
+ value: draftEnd ? daysFromToday : "",
3802
+ min: 0,
3803
+ onChange: handleDaysFromChange,
3804
+ onMouseDown: (e) => e.stopPropagation(),
3805
+ placeholder: "\u2014"
3806
+ }
3807
+ ))), /* @__PURE__ */ React72.createElement("div", { style: { flex: 1 } }), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__footer" }, /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-dr-picker__close-btn", onClick: handleClose }, "CLOSE"), /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-dr-picker__apply-btn", onClick: handleApply }, "APPLY"))))
3808
+ ) : (
3809
+ /* ── Calendar Mode ── */
3810
+ /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker rf-dr-picker--calendar", onMouseDown: (e) => e.preventDefault() }, /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__calendars" }, /* @__PURE__ */ React72.createElement(
3811
+ RangeCalendarBody,
3812
+ {
3813
+ viewYear: leftViewYear,
3814
+ viewMonth: leftViewMonth,
3815
+ startDate: draftStart,
3816
+ endDate: draftEnd,
3817
+ hoverDate: selecting === "end" ? hoverDate : null,
3818
+ todayDate: today2,
3819
+ onDayClick: handleCalDayClick,
3820
+ onDayHover: setHoverDate,
3821
+ onPrev: prevMonth,
3822
+ onNext: nextMonth,
3823
+ showNext: false
3824
+ }
3825
+ ), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__cal-col-divider" }), /* @__PURE__ */ React72.createElement(
3826
+ RangeCalendarBody,
3827
+ {
3828
+ viewYear: rightViewYear,
3829
+ viewMonth: rightViewMonth,
3830
+ startDate: draftStart,
3831
+ endDate: draftEnd,
3832
+ hoverDate: selecting === "end" ? hoverDate : null,
3833
+ todayDate: today2,
3834
+ onDayClick: handleCalDayClick,
3835
+ onDayHover: setHoverDate,
3836
+ onPrev: prevMonth,
3837
+ onNext: nextMonth,
3838
+ showPrev: false
3839
+ }
3840
+ )), selecting === "end" && draftStart && /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__cal-hint" }, /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-picker__cal-hint-dot" }), /* @__PURE__ */ React72.createElement("span", null, "Select end date \xB7 started from ", /* @__PURE__ */ React72.createElement("strong", null, formatShort(draftStart)))), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__divider" }), /* @__PURE__ */ React72.createElement("div", { className: "rf-dr-picker__cal-footer" }, draftStart && draftEnd && /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-picker__cal-range-label" }, formatShort(draftStart <= draftEnd ? draftStart : draftEnd), " \u2013 ", formatShort(draftStart <= draftEnd ? draftEnd : draftStart), /* @__PURE__ */ React72.createElement("span", { className: "rf-dr-picker__cal-range-days" }, " ", "(", Math.abs(daysBetween(draftStart, draftEnd)) + 1, " days)")), /* @__PURE__ */ React72.createElement("div", { style: { flex: 1 } }), /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-dr-picker__close-btn", onClick: handleClose }, "CLOSE"), /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-dr-picker__apply-btn", onClick: handleApply }, "APPLY")))
3841
+ ))), helperText && /* @__PURE__ */ React72.createElement("div", { className: "rf-text-field__helper-text" }, helperText));
3842
+ };
3843
+ DateRangeField.displayName = "DateRangeField";
3829
3844
 
3830
3845
  // lib/Progress/RufousLogoLoader.tsx
3831
3846
  import * as React73 from "react";