klun-ui 0.1.0 → 0.1.2

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.
@@ -6681,193 +6681,578 @@ var CounterInput = react.forwardRef(function CounterInput2({
6681
6681
  );
6682
6682
  });
6683
6683
  CounterInput.displayName = "CounterInput";
6684
+ var Input = react.forwardRef(function Input2({
6685
+ size: sizeProp,
6686
+ leadingIcon,
6687
+ trailingIcon,
6688
+ leadingNode,
6689
+ trailingNode,
6690
+ error = false,
6691
+ disabled = false,
6692
+ readOnly = false,
6693
+ loading = false,
6694
+ clearable = false,
6695
+ onClear,
6696
+ className,
6697
+ style,
6698
+ ...props
6699
+ }, ref) {
6700
+ const size = useSize(sizeProp);
6701
+ const { input } = useLocale();
6702
+ const innerRef = react.useRef(null);
6703
+ const [hasValue, setHasValue] = react.useState(() => !!(props.value ?? props.defaultValue));
6704
+ react.useEffect(() => {
6705
+ if (props.value !== void 0) setHasValue(!!props.value);
6706
+ }, [props.value]);
6707
+ const setRef = (node) => {
6708
+ innerRef.current = node;
6709
+ if (typeof ref === "function") ref(node);
6710
+ else if (ref) ref.current = node;
6711
+ };
6712
+ const showClear = clearable && hasValue && !disabled && !readOnly && !loading;
6713
+ const clear = () => {
6714
+ const node = innerRef.current;
6715
+ if (node) {
6716
+ node.value = "";
6717
+ node.focus();
6718
+ }
6719
+ setHasValue(false);
6720
+ onClear?.();
6721
+ if (node) {
6722
+ props.onChange?.({
6723
+ ...{},
6724
+ target: node,
6725
+ currentTarget: node
6726
+ });
6727
+ }
6728
+ };
6729
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6730
+ "div",
6731
+ {
6732
+ className: chunkTPGAXYFU_cjs.cx(
6733
+ "klun-input",
6734
+ `klun-input--${size}`,
6735
+ error && "klun-input--error",
6736
+ disabled && "klun-input--disabled",
6737
+ readOnly && "klun-input--readonly",
6738
+ className
6739
+ ),
6740
+ style,
6741
+ children: [
6742
+ leadingIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-input__icon", children: leadingIcon }) : null,
6743
+ leadingNode,
6744
+ /* @__PURE__ */ jsxRuntime.jsx(
6745
+ "input",
6746
+ {
6747
+ ref: setRef,
6748
+ className: "klun-input__field",
6749
+ disabled,
6750
+ readOnly,
6751
+ ...props,
6752
+ onChange: (e) => {
6753
+ setHasValue(!!e.target.value);
6754
+ props.onChange?.(e);
6755
+ }
6756
+ }
6757
+ ),
6758
+ showClear ? /* @__PURE__ */ jsxRuntime.jsx(
6759
+ "button",
6760
+ {
6761
+ type: "button",
6762
+ className: "klun-input__clear",
6763
+ onClick: clear,
6764
+ "aria-label": input.clear,
6765
+ children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-close-circle-fill" })
6766
+ }
6767
+ ) : null,
6768
+ trailingNode,
6769
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-input__spinner", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "klun-input__spinner-svg", width: 18, height: 18, viewBox: "0 0 20 20", fill: "none", children: [
6770
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "7", stroke: "currentColor", strokeOpacity: "0.25", strokeWidth: "2.5" }),
6771
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "7", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeDasharray: "44", strokeDashoffset: "31" })
6772
+ ] }) }) : trailingIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-input__icon", children: trailingIcon }) : null
6773
+ ]
6774
+ }
6775
+ );
6776
+ });
6777
+ Input.displayName = "Input";
6778
+ var Popover = react.forwardRef(function Popover2({ trigger, children, align = "left", width = 280, className, ...props }, ref) {
6779
+ const [open, setOpen] = react.useState(false);
6780
+ const innerRef = react.useRef(null);
6781
+ react.useEffect(() => {
6782
+ if (!open) return;
6783
+ const h = (e) => {
6784
+ if (innerRef.current && !innerRef.current.contains(e.target)) setOpen(false);
6785
+ };
6786
+ document.addEventListener("mousedown", h);
6787
+ return () => document.removeEventListener("mousedown", h);
6788
+ }, [open]);
6789
+ const setRefs = (node) => {
6790
+ innerRef.current = node;
6791
+ if (typeof ref === "function") ref(node);
6792
+ else if (ref) ref.current = node;
6793
+ };
6794
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { ref: setRefs, className: chunkTPGAXYFU_cjs.cx("klun-popover", className), ...props, children: [
6795
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-popover__trigger", onClick: () => setOpen((o) => !o), children: trigger }),
6796
+ open ? /* @__PURE__ */ jsxRuntime.jsx(
6797
+ "div",
6798
+ {
6799
+ role: "dialog",
6800
+ className: chunkTPGAXYFU_cjs.cx("klun-popover__panel", `klun-popover__panel--${align}`),
6801
+ style: { width },
6802
+ children: typeof children === "function" ? children(() => setOpen(false)) : children
6803
+ }
6804
+ ) : null
6805
+ ] });
6806
+ });
6807
+ Popover.displayName = "Popover";
6684
6808
  var same = (a, b) => !!a && !!b && a.toDateString() === b.toDateString();
6809
+ var DEFAULT_FORMAT = {
6810
+ year: "numeric",
6811
+ month: "short",
6812
+ day: "numeric"
6813
+ };
6814
+ var Calendar = react.forwardRef(function Calendar2({ value, onPick, className, style }, ref) {
6815
+ const { datePicker } = useLocale();
6816
+ const initial = value ? new Date(value) : /* @__PURE__ */ new Date();
6817
+ const [view, setView] = react.useState(new Date(initial.getFullYear(), initial.getMonth(), 1));
6818
+ const sel = value ? new Date(value) : null;
6819
+ const y = view.getFullYear();
6820
+ const m = view.getMonth();
6821
+ const firstDay = (new Date(y, m, 1).getDay() + 6) % 7;
6822
+ const daysInMonth = new Date(y, m + 1, 0).getDate();
6823
+ const today = /* @__PURE__ */ new Date();
6824
+ today.setHours(0, 0, 0, 0);
6825
+ const cells = [];
6826
+ for (let i = 0; i < firstDay; i++) cells.push(null);
6827
+ for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(y, m, d));
6828
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: chunkTPGAXYFU_cjs.cx("klun-date-picker", className), style, children: [
6829
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-picker__header", children: [
6830
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "klun-date-picker__nav", onClick: () => setView(new Date(y, m - 1, 1)), children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 6l-4 4 4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
6831
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-date-picker__title", children: fmt(datePicker.title, { month: datePicker.months[m], year: y }) }),
6832
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "klun-date-picker__nav", onClick: () => setView(new Date(y, m + 1, 1)), children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 6l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
6833
+ ] }),
6834
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-picker__grid", children: [
6835
+ datePicker.weekdaysShort.map((d, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-date-picker__weekday", children: d }, i)),
6836
+ cells.map((date, i) => {
6837
+ if (!date) return /* @__PURE__ */ jsxRuntime.jsx("span", {}, i);
6838
+ return /* @__PURE__ */ jsxRuntime.jsx(
6839
+ "button",
6840
+ {
6841
+ type: "button",
6842
+ className: "klun-date-picker__day",
6843
+ "data-selected": same(date, sel) || void 0,
6844
+ "data-today": same(date, today) || void 0,
6845
+ onClick: () => onPick(date),
6846
+ children: date.getDate()
6847
+ },
6848
+ i
6849
+ );
6850
+ })
6851
+ ] })
6852
+ ] });
6853
+ });
6685
6854
  var DatePicker = react.forwardRef(
6686
- function DatePicker2({ value, onChange, className, style, ...props }, ref) {
6687
- const { datePicker } = useLocale();
6688
- const initial = value ? new Date(value) : /* @__PURE__ */ new Date();
6689
- const [view, setView] = react.useState(
6690
- new Date(initial.getFullYear(), initial.getMonth(), 1)
6691
- );
6855
+ function DatePicker2({ value, onChange, inline, placeholder, format = DEFAULT_FORMAT, align = "left", disabled, className, style, ...props }, ref) {
6856
+ if (inline) {
6857
+ return /* @__PURE__ */ jsxRuntime.jsx(Calendar, { ref, value, onPick: (d) => onChange?.(d), className, style });
6858
+ }
6692
6859
  const sel = value ? new Date(value) : null;
6693
- const y = view.getFullYear();
6694
- const m = view.getMonth();
6695
- const firstDay = (new Date(y, m, 1).getDay() + 6) % 7;
6696
- const daysInMonth = new Date(y, m + 1, 0).getDate();
6697
- const today = /* @__PURE__ */ new Date();
6698
- today.setHours(0, 0, 0, 0);
6699
- const cells = [];
6700
- for (let i = 0; i < firstDay; i++) cells.push(null);
6701
- for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(y, m, d));
6702
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: chunkTPGAXYFU_cjs.cx("klun-date-picker", className), style, ...props, children: [
6703
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-picker__header", children: [
6704
- /* @__PURE__ */ jsxRuntime.jsx(
6705
- "button",
6860
+ const label = sel ? sel.toLocaleDateString(void 0, format) : "";
6861
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: chunkTPGAXYFU_cjs.cx("klun-date-field", className), style, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
6862
+ Popover,
6863
+ {
6864
+ align,
6865
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(
6866
+ Input,
6867
+ {
6868
+ readOnly: true,
6869
+ disabled,
6870
+ value: label,
6871
+ placeholder: placeholder ?? "Select date",
6872
+ leadingIcon: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-calendar-line" }),
6873
+ trailingIcon: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-arrow-down-s-line" }),
6874
+ style: { width: "100%", cursor: "pointer" }
6875
+ }
6876
+ ),
6877
+ children: (close) => /* @__PURE__ */ jsxRuntime.jsx(
6878
+ Calendar,
6879
+ {
6880
+ className: "klun-date-picker--bare",
6881
+ value,
6882
+ onPick: (d) => {
6883
+ onChange?.(d);
6884
+ close();
6885
+ }
6886
+ }
6887
+ )
6888
+ }
6889
+ ) });
6890
+ }
6891
+ );
6892
+ DatePicker.displayName = "DatePicker";
6893
+ var pad = (n) => String(n).padStart(2, "0");
6894
+ var TimePicker = react.forwardRef(
6895
+ function TimePicker2({ value = "09:00", onChange, className, style, ...props }, ref) {
6896
+ const t = useLocale();
6897
+ const [h, m] = value.split(":").map(Number);
6898
+ const mer = h >= 12 ? "PM" : "AM";
6899
+ const h12 = (h + 11) % 12 + 1;
6900
+ const set = (nh, nm, nmer) => {
6901
+ let hh = nh % 12;
6902
+ if (nmer === "PM") hh += 12;
6903
+ onChange?.(`${pad(hh)}:${pad(nm)}`);
6904
+ };
6905
+ const [open, setOpen] = react.useState(null);
6906
+ const rootRef = react.useRef(null);
6907
+ const setRoot = (node) => {
6908
+ rootRef.current = node;
6909
+ if (typeof ref === "function") ref(node);
6910
+ else if (ref) ref.current = node;
6911
+ };
6912
+ react.useEffect(() => {
6913
+ if (!open) return;
6914
+ const onDown = (e) => {
6915
+ if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(null);
6916
+ };
6917
+ document.addEventListener("mousedown", onDown);
6918
+ return () => document.removeEventListener("mousedown", onDown);
6919
+ }, [open]);
6920
+ const hourOpts = Array.from({ length: 12 }, (_, i) => ({
6921
+ value: String(i + 1),
6922
+ label: pad(i + 1)
6923
+ }));
6924
+ const minOpts = Array.from({ length: 60 }, (_, i) => ({
6925
+ value: String(i),
6926
+ label: pad(i)
6927
+ }));
6928
+ const merOpts = [
6929
+ { value: "AM", label: t.timePicker.am },
6930
+ { value: "PM", label: t.timePicker.pm }
6931
+ ];
6932
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6933
+ "div",
6934
+ {
6935
+ ref: setRoot,
6936
+ className: chunkTPGAXYFU_cjs.cx("klun-time-picker", className),
6937
+ style,
6938
+ ...props,
6939
+ children: [
6940
+ /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-time-line klun-time-picker__icon" }),
6941
+ /* @__PURE__ */ jsxRuntime.jsx(
6942
+ TimeColumn,
6943
+ {
6944
+ options: hourOpts,
6945
+ current: String(h12),
6946
+ open: open === "h",
6947
+ onOpen: () => setOpen("h"),
6948
+ onClose: () => setOpen(null),
6949
+ onPick: (v) => {
6950
+ set(Number(v), m, mer);
6951
+ setOpen(null);
6952
+ }
6953
+ }
6954
+ ),
6955
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-time-picker__sep", children: ":" }),
6956
+ /* @__PURE__ */ jsxRuntime.jsx(
6957
+ TimeColumn,
6958
+ {
6959
+ options: minOpts,
6960
+ current: String(m),
6961
+ open: open === "m",
6962
+ onOpen: () => setOpen("m"),
6963
+ onClose: () => setOpen(null),
6964
+ onPick: (v) => {
6965
+ set(h12, Number(v), mer);
6966
+ setOpen(null);
6967
+ }
6968
+ }
6969
+ ),
6970
+ /* @__PURE__ */ jsxRuntime.jsx(
6971
+ TimeColumn,
6972
+ {
6973
+ className: "klun-time-picker__col--meridiem",
6974
+ options: merOpts,
6975
+ current: mer,
6976
+ open: open === "mer",
6977
+ onOpen: () => setOpen("mer"),
6978
+ onClose: () => setOpen(null),
6979
+ onPick: (v) => {
6980
+ set(h12, m, v);
6981
+ setOpen(null);
6982
+ }
6983
+ }
6984
+ )
6985
+ ]
6986
+ }
6987
+ );
6988
+ }
6989
+ );
6990
+ function TimeColumn({
6991
+ options,
6992
+ current,
6993
+ open,
6994
+ onOpen,
6995
+ onClose,
6996
+ onPick,
6997
+ className
6998
+ }) {
6999
+ const colRef = react.useRef(null);
7000
+ const [active, setActive] = react.useState(-1);
7001
+ const selected = options.find((o) => o.value === current);
7002
+ const panel = () => colRef.current?.querySelector(".klun-select-listbox") ?? null;
7003
+ const scrollTo = (i, center) => {
7004
+ requestAnimationFrame(() => {
7005
+ const p = panel();
7006
+ const el = p?.children[i];
7007
+ if (!p || !el) return;
7008
+ if (center) {
7009
+ p.scrollTop = el.offsetTop - p.clientHeight / 2 + el.offsetHeight / 2;
7010
+ } else if (el.offsetTop < p.scrollTop) {
7011
+ p.scrollTop = el.offsetTop - 4;
7012
+ } else if (el.offsetTop + el.offsetHeight > p.scrollTop + p.clientHeight) {
7013
+ p.scrollTop = el.offsetTop + el.offsetHeight - p.clientHeight + 4;
7014
+ }
7015
+ });
7016
+ };
7017
+ react.useEffect(() => {
7018
+ if (!open) return;
7019
+ const idx = options.findIndex((o) => o.value === current);
7020
+ setActive(idx);
7021
+ scrollTo(idx >= 0 ? idx : 0, true);
7022
+ }, [open]);
7023
+ const step = (dir) => {
7024
+ if (!options.length) return;
7025
+ let i = active;
7026
+ for (let n = 0; n < options.length; n++) {
7027
+ i = (i + dir + options.length) % options.length;
7028
+ if (!options[i].disabled) break;
7029
+ }
7030
+ setActive(i);
7031
+ scrollTo(i, false);
7032
+ };
7033
+ const onKeyDown = (e) => {
7034
+ if (!open) {
7035
+ if (["ArrowDown", "ArrowUp", "Enter", " "].includes(e.key)) {
7036
+ e.preventDefault();
7037
+ onOpen();
7038
+ }
7039
+ return;
7040
+ }
7041
+ switch (e.key) {
7042
+ case "ArrowDown":
7043
+ e.preventDefault();
7044
+ step(1);
7045
+ break;
7046
+ case "ArrowUp":
7047
+ e.preventDefault();
7048
+ step(-1);
7049
+ break;
7050
+ case "Enter":
7051
+ case " ":
7052
+ e.preventDefault();
7053
+ if (options[active]) onPick(options[active].value);
7054
+ break;
7055
+ case "Escape":
7056
+ e.preventDefault();
7057
+ onClose();
7058
+ break;
7059
+ case "Tab":
7060
+ onClose();
7061
+ break;
7062
+ }
7063
+ };
7064
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: colRef, className: chunkTPGAXYFU_cjs.cx("klun-time-picker__col", className), children: [
7065
+ /* @__PURE__ */ jsxRuntime.jsx(
7066
+ "button",
7067
+ {
7068
+ type: "button",
7069
+ className: "klun-time-picker__trigger",
7070
+ "aria-haspopup": "listbox",
7071
+ "aria-expanded": open,
7072
+ "data-open": open || void 0,
7073
+ onClick: () => open ? onClose() : onOpen(),
7074
+ onKeyDown,
7075
+ children: selected ? selected.label : ""
7076
+ }
7077
+ ),
7078
+ open ? /* @__PURE__ */ jsxRuntime.jsx(
7079
+ SelectListbox,
7080
+ {
7081
+ className: "klun-time-picker__listbox",
7082
+ options,
7083
+ current,
7084
+ active,
7085
+ onActivate: setActive,
7086
+ onPick: (o) => onPick(o.value)
7087
+ }
7088
+ ) : null
7089
+ ] });
7090
+ }
7091
+ TimePicker.displayName = "TimePicker";
7092
+ var pad2 = (n) => String(n).padStart(2, "0");
7093
+ var DEFAULT_FORMAT2 = {
7094
+ year: "numeric",
7095
+ month: "short",
7096
+ day: "numeric",
7097
+ hour: "2-digit",
7098
+ minute: "2-digit"
7099
+ };
7100
+ function DateTimePanel({ value, onChange }) {
7101
+ const hhmm = value ? `${pad2(value.getHours())}:${pad2(value.getMinutes())}` : "09:00";
7102
+ const setDate = (d) => {
7103
+ const next = new Date(d);
7104
+ if (value) next.setHours(value.getHours(), value.getMinutes(), 0, 0);
7105
+ else next.setHours(9, 0, 0, 0);
7106
+ onChange(next);
7107
+ };
7108
+ const setTime = (t) => {
7109
+ const [h, m] = t.split(":").map(Number);
7110
+ const next = value ? new Date(value) : /* @__PURE__ */ new Date();
7111
+ next.setHours(h, m, 0, 0);
7112
+ onChange(next);
7113
+ };
7114
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-time-picker__panel", children: [
7115
+ /* @__PURE__ */ jsxRuntime.jsx(DatePicker, { inline: true, className: "klun-date-picker--bare", value, onChange: setDate }),
7116
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-date-time-picker__time", children: /* @__PURE__ */ jsxRuntime.jsx(TimePicker, { value: hhmm, onChange: setTime }) })
7117
+ ] });
7118
+ }
7119
+ var DateTimePicker = react.forwardRef(
7120
+ function DateTimePicker2({ value, onChange, inline, placeholder, format = DEFAULT_FORMAT2, align = "left", disabled, className, style, ...props }, ref) {
7121
+ const date = value ? new Date(value) : null;
7122
+ if (inline) {
7123
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: chunkTPGAXYFU_cjs.cx("klun-date-time-picker", className), style, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(DateTimePanel, { value: date, onChange: (d) => onChange?.(d) }) });
7124
+ }
7125
+ const label = date ? date.toLocaleString(void 0, format) : "";
7126
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: chunkTPGAXYFU_cjs.cx("klun-date-time-field", className), style, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
7127
+ Popover,
7128
+ {
7129
+ align,
7130
+ width: 300,
7131
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(
7132
+ Input,
6706
7133
  {
6707
- type: "button",
6708
- className: "klun-date-picker__nav",
6709
- onClick: () => setView(new Date(y, m - 1, 1)),
6710
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
6711
- "path",
6712
- {
6713
- d: "M12 6l-4 4 4 4",
6714
- stroke: "currentColor",
6715
- strokeWidth: "1.5",
6716
- strokeLinecap: "round",
6717
- strokeLinejoin: "round"
6718
- }
6719
- ) })
7134
+ readOnly: true,
7135
+ disabled,
7136
+ value: label,
7137
+ placeholder: placeholder ?? "Select date & time",
7138
+ leadingIcon: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-calendar-2-line" }),
7139
+ trailingIcon: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-arrow-down-s-line" }),
7140
+ style: { width: "100%", cursor: "pointer" }
6720
7141
  }
6721
7142
  ),
6722
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-date-picker__title", children: fmt(datePicker.title, { month: datePicker.months[m], year: y }) }),
6723
- /* @__PURE__ */ jsxRuntime.jsx(
6724
- "button",
6725
- {
6726
- type: "button",
6727
- className: "klun-date-picker__nav",
6728
- onClick: () => setView(new Date(y, m + 1, 1)),
6729
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
6730
- "path",
6731
- {
6732
- d: "M8 6l4 4-4 4",
6733
- stroke: "currentColor",
6734
- strokeWidth: "1.5",
6735
- strokeLinecap: "round",
6736
- strokeLinejoin: "round"
6737
- }
6738
- ) })
6739
- }
6740
- )
6741
- ] }),
6742
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-picker__grid", children: [
6743
- datePicker.weekdaysShort.map((d, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-date-picker__weekday", children: d }, i)),
6744
- cells.map((date, i) => {
6745
- if (!date) return /* @__PURE__ */ jsxRuntime.jsx("span", {}, i);
6746
- const isSel = same(date, sel);
6747
- const isToday = same(date, today);
6748
- return /* @__PURE__ */ jsxRuntime.jsx(
6749
- "button",
6750
- {
6751
- type: "button",
6752
- className: "klun-date-picker__day",
6753
- "data-selected": isSel || void 0,
6754
- "data-today": isToday || void 0,
6755
- onClick: () => onChange?.(date),
6756
- children: date.getDate()
6757
- },
6758
- i
6759
- );
6760
- })
6761
- ] })
6762
- ] });
7143
+ children: /* @__PURE__ */ jsxRuntime.jsx(DateTimePanel, { value: date, onChange: (d) => onChange?.(d) })
7144
+ }
7145
+ ) });
6763
7146
  }
6764
7147
  );
6765
- DatePicker.displayName = "DatePicker";
7148
+ DateTimePicker.displayName = "DateTimePicker";
6766
7149
  var norm = (d) => d && new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
6767
- var DateRangePicker = react.forwardRef(
6768
- function DateRangePicker2({ start, end, onChange, className, style, ...props }, ref) {
6769
- const { datePicker } = useLocale();
6770
- const base = start ? new Date(start) : /* @__PURE__ */ new Date();
6771
- const [view, setView] = react.useState(
6772
- new Date(base.getFullYear(), base.getMonth(), 1)
6773
- );
6774
- const s = start ? new Date(start) : null;
6775
- const e = end ? new Date(end) : null;
6776
- const y = view.getFullYear();
6777
- const m = view.getMonth();
6778
- const firstDay = (new Date(y, m, 1).getDay() + 6) % 7;
6779
- const daysInMonth = new Date(y, m + 1, 0).getDate();
6780
- const cells = [];
6781
- for (let i = 0; i < firstDay; i++) cells.push(null);
6782
- for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(y, m, d));
6783
- const pick = (d) => {
6784
- if (!s || s && e) return onChange?.({ start: d, end: null });
6785
- if (norm(d) < norm(s)) return onChange?.({ start: d, end: s });
6786
- onChange?.({ start: s, end: d });
6787
- };
6788
- const inRange = (d) => !!s && !!e && norm(d) > norm(s) && norm(d) < norm(e);
6789
- const isStart = (d) => !!s && norm(d) === norm(s);
6790
- const isEnd = (d) => !!e && norm(d) === norm(e);
6791
- const isEdge = (d) => isStart(d) || isEnd(d);
6792
- return /* @__PURE__ */ jsxRuntime.jsxs(
6793
- "div",
6794
- {
6795
- ref,
6796
- className: chunkTPGAXYFU_cjs.cx("klun-date-range-picker", className),
6797
- style,
6798
- ...props,
6799
- children: [
6800
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-range-picker__header", children: [
6801
- /* @__PURE__ */ jsxRuntime.jsx(
6802
- "button",
6803
- {
6804
- type: "button",
6805
- className: "klun-date-range-picker__nav",
6806
- onClick: () => setView(new Date(y, m - 1, 1)),
6807
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
6808
- "path",
6809
- {
6810
- d: "M12 6l-4 4 4 4",
6811
- stroke: "currentColor",
6812
- strokeWidth: "1.5",
6813
- strokeLinecap: "round",
6814
- strokeLinejoin: "round"
6815
- }
6816
- ) })
6817
- }
6818
- ),
6819
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-date-range-picker__title", children: fmt(datePicker.title, { month: datePicker.months[m], year: y }) }),
6820
- /* @__PURE__ */ jsxRuntime.jsx(
7150
+ var DEFAULT_FORMAT3 = { month: "short", day: "numeric" };
7151
+ var RangeCalendar = react.forwardRef(function RangeCalendar2({ start, end, onPick, className, style }, ref) {
7152
+ const { datePicker } = useLocale();
7153
+ const base = start ? new Date(start) : /* @__PURE__ */ new Date();
7154
+ const [view, setView] = react.useState(new Date(base.getFullYear(), base.getMonth(), 1));
7155
+ const s = start ? new Date(start) : null;
7156
+ const e = end ? new Date(end) : null;
7157
+ const y = view.getFullYear();
7158
+ const m = view.getMonth();
7159
+ const firstDay = (new Date(y, m, 1).getDay() + 6) % 7;
7160
+ const daysInMonth = new Date(y, m + 1, 0).getDate();
7161
+ const cells = [];
7162
+ for (let i = 0; i < firstDay; i++) cells.push(null);
7163
+ for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(y, m, d));
7164
+ const pick = (d) => {
7165
+ if (!s || s && e) return onPick({ start: d, end: null });
7166
+ if (norm(d) < norm(s)) return onPick({ start: d, end: s });
7167
+ onPick({ start: s, end: d });
7168
+ };
7169
+ const inRange = (d) => !!s && !!e && norm(d) > norm(s) && norm(d) < norm(e);
7170
+ const isStart = (d) => !!s && norm(d) === norm(s);
7171
+ const isEnd = (d) => !!e && norm(d) === norm(e);
7172
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: chunkTPGAXYFU_cjs.cx("klun-date-range-picker", className), style, children: [
7173
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-range-picker__header", children: [
7174
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "klun-date-range-picker__nav", onClick: () => setView(new Date(y, m - 1, 1)), children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 6l-4 4 4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
7175
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-date-range-picker__title", children: fmt(datePicker.title, { month: datePicker.months[m], year: y }) }),
7176
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "klun-date-range-picker__nav", onClick: () => setView(new Date(y, m + 1, 1)), children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 6l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
7177
+ ] }),
7178
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-range-picker__grid", children: [
7179
+ datePicker.weekdaysShort.map((d, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-date-range-picker__weekday", children: d }, i)),
7180
+ cells.map((date, i) => {
7181
+ if (!date) return /* @__PURE__ */ jsxRuntime.jsx("span", {}, i);
7182
+ const mid = inRange(date);
7183
+ return /* @__PURE__ */ jsxRuntime.jsx(
7184
+ "div",
7185
+ {
7186
+ className: "klun-date-range-picker__cell",
7187
+ "data-in-range": mid || void 0,
7188
+ "data-range-edge": isStart(date) || isEnd(date) || void 0,
7189
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6821
7190
  "button",
6822
7191
  {
6823
7192
  type: "button",
6824
- className: "klun-date-range-picker__nav",
6825
- onClick: () => setView(new Date(y, m + 1, 1)),
6826
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
6827
- "path",
6828
- {
6829
- d: "M8 6l4 4-4 4",
6830
- stroke: "currentColor",
6831
- strokeWidth: "1.5",
6832
- strokeLinecap: "round",
6833
- strokeLinejoin: "round"
6834
- }
6835
- ) })
7193
+ className: "klun-date-range-picker__day",
7194
+ "data-range-start": isStart(date) || void 0,
7195
+ "data-range-end": isEnd(date) || void 0,
7196
+ "data-in-range": mid || void 0,
7197
+ onClick: () => pick(date),
7198
+ children: date.getDate()
6836
7199
  }
6837
7200
  )
6838
- ] }),
6839
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-date-range-picker__grid", children: [
6840
- datePicker.weekdaysShort.map((d, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-date-range-picker__weekday", children: d }, i)),
6841
- cells.map((date, i) => {
6842
- if (!date) return /* @__PURE__ */ jsxRuntime.jsx("span", {}, i);
6843
- const edge = isEdge(date);
6844
- const mid = inRange(date);
6845
- return /* @__PURE__ */ jsxRuntime.jsx(
6846
- "div",
6847
- {
6848
- className: "klun-date-range-picker__cell",
6849
- "data-in-range": mid || void 0,
6850
- "data-range-edge": edge || void 0,
6851
- children: /* @__PURE__ */ jsxRuntime.jsx(
6852
- "button",
6853
- {
6854
- type: "button",
6855
- className: "klun-date-range-picker__day",
6856
- "data-range-start": isStart(date) || void 0,
6857
- "data-range-end": isEnd(date) || void 0,
6858
- "data-in-range": mid || void 0,
6859
- onClick: () => pick(date),
6860
- children: date.getDate()
6861
- }
6862
- )
6863
- },
6864
- i
6865
- );
6866
- })
6867
- ] })
6868
- ]
7201
+ },
7202
+ i
7203
+ );
7204
+ })
7205
+ ] })
7206
+ ] });
7207
+ });
7208
+ var DateRangePicker = react.forwardRef(
7209
+ function DateRangePicker2({ start, end, onChange, inline, placeholder, format = DEFAULT_FORMAT3, align = "left", disabled, className, style, ...props }, ref) {
7210
+ if (inline) {
7211
+ return /* @__PURE__ */ jsxRuntime.jsx(
7212
+ RangeCalendar,
7213
+ {
7214
+ ref,
7215
+ start,
7216
+ end,
7217
+ onPick: (r) => onChange?.(r),
7218
+ className,
7219
+ style
7220
+ }
7221
+ );
7222
+ }
7223
+ const f = (d) => d ? new Date(d).toLocaleDateString(void 0, format) : "";
7224
+ const label = start || end ? `${f(start)} \u2013 ${f(end)}` : "";
7225
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: chunkTPGAXYFU_cjs.cx("klun-date-range-field", className), style, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
7226
+ Popover,
7227
+ {
7228
+ align,
7229
+ width: 300,
7230
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(
7231
+ Input,
7232
+ {
7233
+ readOnly: true,
7234
+ disabled,
7235
+ value: label,
7236
+ placeholder: placeholder ?? "Select range",
7237
+ leadingIcon: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-calendar-2-line" }),
7238
+ trailingIcon: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-arrow-down-s-line" }),
7239
+ style: { width: "100%", cursor: "pointer" }
7240
+ }
7241
+ ),
7242
+ children: (close) => /* @__PURE__ */ jsxRuntime.jsx(
7243
+ RangeCalendar,
7244
+ {
7245
+ className: "klun-date-range-picker--bare",
7246
+ start,
7247
+ end,
7248
+ onPick: (r) => {
7249
+ onChange?.(r);
7250
+ if (r.start && r.end) close();
7251
+ }
7252
+ }
7253
+ )
6869
7254
  }
6870
- );
7255
+ ) });
6871
7256
  }
6872
7257
  );
6873
7258
  DateRangePicker.displayName = "DateRangePicker";
@@ -7511,127 +7896,33 @@ var InlineSelect = react.forwardRef(
7511
7896
  /* @__PURE__ */ jsxRuntime.jsx(
7512
7897
  "select",
7513
7898
  {
7514
- ref: s.mergeSelectRef(ref),
7515
- className: "klun-inline-select__native",
7516
- "aria-hidden": true,
7517
- tabIndex: -1,
7518
- defaultValue: String(value ?? defaultValue ?? ""),
7519
- onChange,
7520
- disabled,
7521
- ...props,
7522
- children
7523
- }
7524
- ),
7525
- s.open ? /* @__PURE__ */ jsxRuntime.jsx(
7526
- SelectListbox,
7527
- {
7528
- options: s.options,
7529
- current: s.current,
7530
- active: s.active,
7531
- onActivate: s.setActive,
7532
- onPick: s.pick
7533
- }
7534
- ) : null
7535
- ]
7536
- }
7537
- );
7538
- }
7539
- );
7540
- InlineSelect.displayName = "InlineSelect";
7541
- var Input = react.forwardRef(function Input2({
7542
- size: sizeProp,
7543
- leadingIcon,
7544
- trailingIcon,
7545
- leadingNode,
7546
- trailingNode,
7547
- error = false,
7548
- disabled = false,
7549
- readOnly = false,
7550
- loading = false,
7551
- clearable = false,
7552
- onClear,
7553
- className,
7554
- style,
7555
- ...props
7556
- }, ref) {
7557
- const size = useSize(sizeProp);
7558
- const { input } = useLocale();
7559
- const innerRef = react.useRef(null);
7560
- const [hasValue, setHasValue] = react.useState(() => !!(props.value ?? props.defaultValue));
7561
- react.useEffect(() => {
7562
- if (props.value !== void 0) setHasValue(!!props.value);
7563
- }, [props.value]);
7564
- const setRef = (node) => {
7565
- innerRef.current = node;
7566
- if (typeof ref === "function") ref(node);
7567
- else if (ref) ref.current = node;
7568
- };
7569
- const showClear = clearable && hasValue && !disabled && !readOnly && !loading;
7570
- const clear = () => {
7571
- const node = innerRef.current;
7572
- if (node) {
7573
- node.value = "";
7574
- node.focus();
7575
- }
7576
- setHasValue(false);
7577
- onClear?.();
7578
- if (node) {
7579
- props.onChange?.({
7580
- ...{},
7581
- target: node,
7582
- currentTarget: node
7583
- });
7584
- }
7585
- };
7586
- return /* @__PURE__ */ jsxRuntime.jsxs(
7587
- "div",
7588
- {
7589
- className: chunkTPGAXYFU_cjs.cx(
7590
- "klun-input",
7591
- `klun-input--${size}`,
7592
- error && "klun-input--error",
7593
- disabled && "klun-input--disabled",
7594
- readOnly && "klun-input--readonly",
7595
- className
7596
- ),
7597
- style,
7598
- children: [
7599
- leadingIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-input__icon", children: leadingIcon }) : null,
7600
- leadingNode,
7601
- /* @__PURE__ */ jsxRuntime.jsx(
7602
- "input",
7603
- {
7604
- ref: setRef,
7605
- className: "klun-input__field",
7606
- disabled,
7607
- readOnly,
7608
- ...props,
7609
- onChange: (e) => {
7610
- setHasValue(!!e.target.value);
7611
- props.onChange?.(e);
7612
- }
7613
- }
7614
- ),
7615
- showClear ? /* @__PURE__ */ jsxRuntime.jsx(
7616
- "button",
7617
- {
7618
- type: "button",
7619
- className: "klun-input__clear",
7620
- onClick: clear,
7621
- "aria-label": input.clear,
7622
- children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-close-circle-fill" })
7623
- }
7624
- ) : null,
7625
- trailingNode,
7626
- loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-input__spinner", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "klun-input__spinner-svg", width: 18, height: 18, viewBox: "0 0 20 20", fill: "none", children: [
7627
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "7", stroke: "currentColor", strokeOpacity: "0.25", strokeWidth: "2.5" }),
7628
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "7", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeDasharray: "44", strokeDashoffset: "31" })
7629
- ] }) }) : trailingIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-input__icon", children: trailingIcon }) : null
7630
- ]
7631
- }
7632
- );
7633
- });
7634
- Input.displayName = "Input";
7899
+ ref: s.mergeSelectRef(ref),
7900
+ className: "klun-inline-select__native",
7901
+ "aria-hidden": true,
7902
+ tabIndex: -1,
7903
+ defaultValue: String(value ?? defaultValue ?? ""),
7904
+ onChange,
7905
+ disabled,
7906
+ ...props,
7907
+ children
7908
+ }
7909
+ ),
7910
+ s.open ? /* @__PURE__ */ jsxRuntime.jsx(
7911
+ SelectListbox,
7912
+ {
7913
+ options: s.options,
7914
+ current: s.current,
7915
+ active: s.active,
7916
+ onActivate: s.setActive,
7917
+ onPick: s.pick
7918
+ }
7919
+ ) : null
7920
+ ]
7921
+ }
7922
+ );
7923
+ }
7924
+ );
7925
+ InlineSelect.displayName = "InlineSelect";
7635
7926
  var Label = react.forwardRef(function Label2({ children, required = false, sublabel, disabled = false, className, ...props }, ref) {
7636
7927
  return /* @__PURE__ */ jsxRuntime.jsxs(
7637
7928
  "label",
@@ -8206,205 +8497,6 @@ var Textarea = react.forwardRef(function Textarea2({ error = false, disabled = f
8206
8497
  );
8207
8498
  });
8208
8499
  Textarea.displayName = "Textarea";
8209
- var pad = (n) => String(n).padStart(2, "0");
8210
- var TimePicker = react.forwardRef(
8211
- function TimePicker2({ value = "09:00", onChange, className, style, ...props }, ref) {
8212
- const t = useLocale();
8213
- const [h, m] = value.split(":").map(Number);
8214
- const mer = h >= 12 ? "PM" : "AM";
8215
- const h12 = (h + 11) % 12 + 1;
8216
- const set = (nh, nm, nmer) => {
8217
- let hh = nh % 12;
8218
- if (nmer === "PM") hh += 12;
8219
- onChange?.(`${pad(hh)}:${pad(nm)}`);
8220
- };
8221
- const [open, setOpen] = react.useState(null);
8222
- const rootRef = react.useRef(null);
8223
- const setRoot = (node) => {
8224
- rootRef.current = node;
8225
- if (typeof ref === "function") ref(node);
8226
- else if (ref) ref.current = node;
8227
- };
8228
- react.useEffect(() => {
8229
- if (!open) return;
8230
- const onDown = (e) => {
8231
- if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(null);
8232
- };
8233
- document.addEventListener("mousedown", onDown);
8234
- return () => document.removeEventListener("mousedown", onDown);
8235
- }, [open]);
8236
- const hourOpts = Array.from({ length: 12 }, (_, i) => ({
8237
- value: String(i + 1),
8238
- label: pad(i + 1)
8239
- }));
8240
- const minOpts = Array.from({ length: 60 }, (_, i) => ({
8241
- value: String(i),
8242
- label: pad(i)
8243
- }));
8244
- const merOpts = [
8245
- { value: "AM", label: t.timePicker.am },
8246
- { value: "PM", label: t.timePicker.pm }
8247
- ];
8248
- return /* @__PURE__ */ jsxRuntime.jsxs(
8249
- "div",
8250
- {
8251
- ref: setRoot,
8252
- className: chunkTPGAXYFU_cjs.cx("klun-time-picker", className),
8253
- style,
8254
- ...props,
8255
- children: [
8256
- /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-time-line klun-time-picker__icon" }),
8257
- /* @__PURE__ */ jsxRuntime.jsx(
8258
- TimeColumn,
8259
- {
8260
- options: hourOpts,
8261
- current: String(h12),
8262
- open: open === "h",
8263
- onOpen: () => setOpen("h"),
8264
- onClose: () => setOpen(null),
8265
- onPick: (v) => {
8266
- set(Number(v), m, mer);
8267
- setOpen(null);
8268
- }
8269
- }
8270
- ),
8271
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-time-picker__sep", children: ":" }),
8272
- /* @__PURE__ */ jsxRuntime.jsx(
8273
- TimeColumn,
8274
- {
8275
- options: minOpts,
8276
- current: String(m),
8277
- open: open === "m",
8278
- onOpen: () => setOpen("m"),
8279
- onClose: () => setOpen(null),
8280
- onPick: (v) => {
8281
- set(h12, Number(v), mer);
8282
- setOpen(null);
8283
- }
8284
- }
8285
- ),
8286
- /* @__PURE__ */ jsxRuntime.jsx(
8287
- TimeColumn,
8288
- {
8289
- className: "klun-time-picker__col--meridiem",
8290
- options: merOpts,
8291
- current: mer,
8292
- open: open === "mer",
8293
- onOpen: () => setOpen("mer"),
8294
- onClose: () => setOpen(null),
8295
- onPick: (v) => {
8296
- set(h12, m, v);
8297
- setOpen(null);
8298
- }
8299
- }
8300
- )
8301
- ]
8302
- }
8303
- );
8304
- }
8305
- );
8306
- function TimeColumn({
8307
- options,
8308
- current,
8309
- open,
8310
- onOpen,
8311
- onClose,
8312
- onPick,
8313
- className
8314
- }) {
8315
- const colRef = react.useRef(null);
8316
- const [active, setActive] = react.useState(-1);
8317
- const selected = options.find((o) => o.value === current);
8318
- const panel = () => colRef.current?.querySelector(".klun-select-listbox") ?? null;
8319
- const scrollTo = (i, center) => {
8320
- requestAnimationFrame(() => {
8321
- const p = panel();
8322
- const el = p?.children[i];
8323
- if (!p || !el) return;
8324
- if (center) {
8325
- p.scrollTop = el.offsetTop - p.clientHeight / 2 + el.offsetHeight / 2;
8326
- } else if (el.offsetTop < p.scrollTop) {
8327
- p.scrollTop = el.offsetTop - 4;
8328
- } else if (el.offsetTop + el.offsetHeight > p.scrollTop + p.clientHeight) {
8329
- p.scrollTop = el.offsetTop + el.offsetHeight - p.clientHeight + 4;
8330
- }
8331
- });
8332
- };
8333
- react.useEffect(() => {
8334
- if (!open) return;
8335
- const idx = options.findIndex((o) => o.value === current);
8336
- setActive(idx);
8337
- scrollTo(idx >= 0 ? idx : 0, true);
8338
- }, [open]);
8339
- const step = (dir) => {
8340
- if (!options.length) return;
8341
- let i = active;
8342
- for (let n = 0; n < options.length; n++) {
8343
- i = (i + dir + options.length) % options.length;
8344
- if (!options[i].disabled) break;
8345
- }
8346
- setActive(i);
8347
- scrollTo(i, false);
8348
- };
8349
- const onKeyDown = (e) => {
8350
- if (!open) {
8351
- if (["ArrowDown", "ArrowUp", "Enter", " "].includes(e.key)) {
8352
- e.preventDefault();
8353
- onOpen();
8354
- }
8355
- return;
8356
- }
8357
- switch (e.key) {
8358
- case "ArrowDown":
8359
- e.preventDefault();
8360
- step(1);
8361
- break;
8362
- case "ArrowUp":
8363
- e.preventDefault();
8364
- step(-1);
8365
- break;
8366
- case "Enter":
8367
- case " ":
8368
- e.preventDefault();
8369
- if (options[active]) onPick(options[active].value);
8370
- break;
8371
- case "Escape":
8372
- e.preventDefault();
8373
- onClose();
8374
- break;
8375
- case "Tab":
8376
- onClose();
8377
- break;
8378
- }
8379
- };
8380
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: colRef, className: chunkTPGAXYFU_cjs.cx("klun-time-picker__col", className), children: [
8381
- /* @__PURE__ */ jsxRuntime.jsx(
8382
- "button",
8383
- {
8384
- type: "button",
8385
- className: "klun-time-picker__trigger",
8386
- "aria-haspopup": "listbox",
8387
- "aria-expanded": open,
8388
- "data-open": open || void 0,
8389
- onClick: () => open ? onClose() : onOpen(),
8390
- onKeyDown,
8391
- children: selected ? selected.label : ""
8392
- }
8393
- ),
8394
- open ? /* @__PURE__ */ jsxRuntime.jsx(
8395
- SelectListbox,
8396
- {
8397
- className: "klun-time-picker__listbox",
8398
- options,
8399
- current,
8400
- active,
8401
- onActivate: setActive,
8402
- onPick: (o) => onPick(o.value)
8403
- }
8404
- ) : null
8405
- ] });
8406
- }
8407
- TimePicker.displayName = "TimePicker";
8408
8500
  var Card = react.forwardRef(function Card2({ variant = "stroke", padding, className, style, children, ...props }, ref) {
8409
8501
  return /* @__PURE__ */ jsxRuntime.jsx(
8410
8502
  "div",
@@ -9975,36 +10067,6 @@ var Popconfirm = react.forwardRef(function Popconfirm2({
9975
10067
  ] });
9976
10068
  });
9977
10069
  Popconfirm.displayName = "Popconfirm";
9978
- var Popover = react.forwardRef(function Popover2({ trigger, children, align = "left", width = 280, className, ...props }, ref) {
9979
- const [open, setOpen] = react.useState(false);
9980
- const innerRef = react.useRef(null);
9981
- react.useEffect(() => {
9982
- if (!open) return;
9983
- const h = (e) => {
9984
- if (innerRef.current && !innerRef.current.contains(e.target)) setOpen(false);
9985
- };
9986
- document.addEventListener("mousedown", h);
9987
- return () => document.removeEventListener("mousedown", h);
9988
- }, [open]);
9989
- const setRefs = (node) => {
9990
- innerRef.current = node;
9991
- if (typeof ref === "function") ref(node);
9992
- else if (ref) ref.current = node;
9993
- };
9994
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { ref: setRefs, className: chunkTPGAXYFU_cjs.cx("klun-popover", className), ...props, children: [
9995
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-popover__trigger", onClick: () => setOpen((o) => !o), children: trigger }),
9996
- open ? /* @__PURE__ */ jsxRuntime.jsx(
9997
- "div",
9998
- {
9999
- role: "dialog",
10000
- className: chunkTPGAXYFU_cjs.cx("klun-popover__panel", `klun-popover__panel--${align}`),
10001
- style: { width },
10002
- children: typeof children === "function" ? children(() => setOpen(false)) : children
10003
- }
10004
- ) : null
10005
- ] });
10006
- });
10007
- Popover.displayName = "Popover";
10008
10070
 
10009
10071
  exports.Accordion = Accordion;
10010
10072
  exports.Alert = Alert;
@@ -10043,6 +10105,7 @@ exports.CopyButton = CopyButton;
10043
10105
  exports.CounterInput = CounterInput;
10044
10106
  exports.DatePicker = DatePicker;
10045
10107
  exports.DateRangePicker = DateRangePicker;
10108
+ exports.DateTimePicker = DateTimePicker;
10046
10109
  exports.Descriptions = Descriptions;
10047
10110
  exports.DigitInput = DigitInput;
10048
10111
  exports.Divider = Divider;
@@ -10148,5 +10211,5 @@ exports.useSize = useSize;
10148
10211
  exports.viVN = viVN;
10149
10212
  exports.zhCN = zhCN;
10150
10213
  exports.zhTW = zhTW;
10151
- //# sourceMappingURL=chunk-FTYQRXS5.cjs.map
10152
- //# sourceMappingURL=chunk-FTYQRXS5.cjs.map
10214
+ //# sourceMappingURL=chunk-OPAZ7GAU.cjs.map
10215
+ //# sourceMappingURL=chunk-OPAZ7GAU.cjs.map