klun-ui 0.1.1 → 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.
- package/CHANGELOG.md +45 -0
- package/dist/{chunk-2MTDM5CL.cjs → chunk-OPAZ7GAU.cjs} +261 -203
- package/dist/chunk-OPAZ7GAU.cjs.map +1 -0
- package/dist/{chunk-DVPY6FDU.js → chunk-RRE3PQLX.js} +261 -204
- package/dist/chunk-RRE3PQLX.js.map +1 -0
- package/dist/index.cjs +147 -143
- package/dist/index.d.cts +22 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +1 -1
- package/dist/styles.css +25 -0
- package/dist/templates/index.cjs +82 -82
- package/dist/templates/index.js +1 -1
- package/package.json +2 -1
- package/dist/chunk-2MTDM5CL.cjs.map +0 -1
- package/dist/chunk-DVPY6FDU.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to **klun-ui** are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/), and the project adheres to
|
|
5
|
+
[Semantic Versioning](https://semver.org/) (pre-1.0: minor/patch bumps may carry
|
|
6
|
+
small breaking changes).
|
|
7
|
+
|
|
8
|
+
## [0.1.2] — 2026-06-20
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`DateTimePicker`** — a single input that selects both a date and a time. It
|
|
12
|
+
opens a popover containing the month calendar plus a time selector, sharing one
|
|
13
|
+
`Date` (changing the date keeps the time and vice-versa). Supports `inline`,
|
|
14
|
+
`placeholder`, `format`, `align` and `disabled`, mirroring the other pickers.
|
|
15
|
+
|
|
16
|
+
## [0.1.1] — 2026-06-20
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- **`DatePicker` / `DateRangePicker` now default to an input trigger.** They
|
|
20
|
+
render a read-only input that opens the calendar in a popover, instead of an
|
|
21
|
+
always-visible inline calendar. New props on both:
|
|
22
|
+
- `inline` — render the bare calendar (the previous behaviour).
|
|
23
|
+
- `placeholder` — trigger text when nothing is selected.
|
|
24
|
+
- `format` — `Intl.DateTimeFormatOptions` for the trigger label.
|
|
25
|
+
- `align` — popover alignment (`"left"` | `"right"`).
|
|
26
|
+
- `disabled` — disable the trigger.
|
|
27
|
+
- Corrected the package `description` (6 accent themes; dropped the stale
|
|
28
|
+
component count).
|
|
29
|
+
|
|
30
|
+
### Migration
|
|
31
|
+
- Replace `<DatePicker … />` used as an inline calendar with
|
|
32
|
+
`<DatePicker inline … />` to keep the old always-open behaviour. The default
|
|
33
|
+
(no `inline`) is now the input-triggered popover.
|
|
34
|
+
|
|
35
|
+
## [0.1.0] — 2026-06-20
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- Initial public release: a themeable React + TypeScript component library and
|
|
39
|
+
design system — light/dark, multiple accent themes, a global radius axis,
|
|
40
|
+
`ConfigProvider`, i18n locales, and the full component set (layout, forms,
|
|
41
|
+
navigation, data display, feedback, overlays, charts).
|
|
42
|
+
|
|
43
|
+
[0.1.2]: https://www.npmjs.com/package/klun-ui/v/0.1.2
|
|
44
|
+
[0.1.1]: https://www.npmjs.com/package/klun-ui/v/0.1.1
|
|
45
|
+
[0.1.0]: https://www.npmjs.com/package/klun-ui/v/0.1.0
|
|
@@ -6890,8 +6890,264 @@ var DatePicker = react.forwardRef(
|
|
|
6890
6890
|
}
|
|
6891
6891
|
);
|
|
6892
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,
|
|
7133
|
+
{
|
|
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" }
|
|
7141
|
+
}
|
|
7142
|
+
),
|
|
7143
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DateTimePanel, { value: date, onChange: (d) => onChange?.(d) })
|
|
7144
|
+
}
|
|
7145
|
+
) });
|
|
7146
|
+
}
|
|
7147
|
+
);
|
|
7148
|
+
DateTimePicker.displayName = "DateTimePicker";
|
|
6893
7149
|
var norm = (d) => d && new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
|
|
6894
|
-
var
|
|
7150
|
+
var DEFAULT_FORMAT3 = { month: "short", day: "numeric" };
|
|
6895
7151
|
var RangeCalendar = react.forwardRef(function RangeCalendar2({ start, end, onPick, className, style }, ref) {
|
|
6896
7152
|
const { datePicker } = useLocale();
|
|
6897
7153
|
const base = start ? new Date(start) : /* @__PURE__ */ new Date();
|
|
@@ -6950,7 +7206,7 @@ var RangeCalendar = react.forwardRef(function RangeCalendar2({ start, end, onPic
|
|
|
6950
7206
|
] });
|
|
6951
7207
|
});
|
|
6952
7208
|
var DateRangePicker = react.forwardRef(
|
|
6953
|
-
function DateRangePicker2({ start, end, onChange, inline, placeholder, format =
|
|
7209
|
+
function DateRangePicker2({ start, end, onChange, inline, placeholder, format = DEFAULT_FORMAT3, align = "left", disabled, className, style, ...props }, ref) {
|
|
6954
7210
|
if (inline) {
|
|
6955
7211
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6956
7212
|
RangeCalendar,
|
|
@@ -8241,205 +8497,6 @@ var Textarea = react.forwardRef(function Textarea2({ error = false, disabled = f
|
|
|
8241
8497
|
);
|
|
8242
8498
|
});
|
|
8243
8499
|
Textarea.displayName = "Textarea";
|
|
8244
|
-
var pad = (n) => String(n).padStart(2, "0");
|
|
8245
|
-
var TimePicker = react.forwardRef(
|
|
8246
|
-
function TimePicker2({ value = "09:00", onChange, className, style, ...props }, ref) {
|
|
8247
|
-
const t = useLocale();
|
|
8248
|
-
const [h, m] = value.split(":").map(Number);
|
|
8249
|
-
const mer = h >= 12 ? "PM" : "AM";
|
|
8250
|
-
const h12 = (h + 11) % 12 + 1;
|
|
8251
|
-
const set = (nh, nm, nmer) => {
|
|
8252
|
-
let hh = nh % 12;
|
|
8253
|
-
if (nmer === "PM") hh += 12;
|
|
8254
|
-
onChange?.(`${pad(hh)}:${pad(nm)}`);
|
|
8255
|
-
};
|
|
8256
|
-
const [open, setOpen] = react.useState(null);
|
|
8257
|
-
const rootRef = react.useRef(null);
|
|
8258
|
-
const setRoot = (node) => {
|
|
8259
|
-
rootRef.current = node;
|
|
8260
|
-
if (typeof ref === "function") ref(node);
|
|
8261
|
-
else if (ref) ref.current = node;
|
|
8262
|
-
};
|
|
8263
|
-
react.useEffect(() => {
|
|
8264
|
-
if (!open) return;
|
|
8265
|
-
const onDown = (e) => {
|
|
8266
|
-
if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(null);
|
|
8267
|
-
};
|
|
8268
|
-
document.addEventListener("mousedown", onDown);
|
|
8269
|
-
return () => document.removeEventListener("mousedown", onDown);
|
|
8270
|
-
}, [open]);
|
|
8271
|
-
const hourOpts = Array.from({ length: 12 }, (_, i) => ({
|
|
8272
|
-
value: String(i + 1),
|
|
8273
|
-
label: pad(i + 1)
|
|
8274
|
-
}));
|
|
8275
|
-
const minOpts = Array.from({ length: 60 }, (_, i) => ({
|
|
8276
|
-
value: String(i),
|
|
8277
|
-
label: pad(i)
|
|
8278
|
-
}));
|
|
8279
|
-
const merOpts = [
|
|
8280
|
-
{ value: "AM", label: t.timePicker.am },
|
|
8281
|
-
{ value: "PM", label: t.timePicker.pm }
|
|
8282
|
-
];
|
|
8283
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8284
|
-
"div",
|
|
8285
|
-
{
|
|
8286
|
-
ref: setRoot,
|
|
8287
|
-
className: chunkTPGAXYFU_cjs.cx("klun-time-picker", className),
|
|
8288
|
-
style,
|
|
8289
|
-
...props,
|
|
8290
|
-
children: [
|
|
8291
|
-
/* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-time-line klun-time-picker__icon" }),
|
|
8292
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8293
|
-
TimeColumn,
|
|
8294
|
-
{
|
|
8295
|
-
options: hourOpts,
|
|
8296
|
-
current: String(h12),
|
|
8297
|
-
open: open === "h",
|
|
8298
|
-
onOpen: () => setOpen("h"),
|
|
8299
|
-
onClose: () => setOpen(null),
|
|
8300
|
-
onPick: (v) => {
|
|
8301
|
-
set(Number(v), m, mer);
|
|
8302
|
-
setOpen(null);
|
|
8303
|
-
}
|
|
8304
|
-
}
|
|
8305
|
-
),
|
|
8306
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-time-picker__sep", children: ":" }),
|
|
8307
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8308
|
-
TimeColumn,
|
|
8309
|
-
{
|
|
8310
|
-
options: minOpts,
|
|
8311
|
-
current: String(m),
|
|
8312
|
-
open: open === "m",
|
|
8313
|
-
onOpen: () => setOpen("m"),
|
|
8314
|
-
onClose: () => setOpen(null),
|
|
8315
|
-
onPick: (v) => {
|
|
8316
|
-
set(h12, Number(v), mer);
|
|
8317
|
-
setOpen(null);
|
|
8318
|
-
}
|
|
8319
|
-
}
|
|
8320
|
-
),
|
|
8321
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8322
|
-
TimeColumn,
|
|
8323
|
-
{
|
|
8324
|
-
className: "klun-time-picker__col--meridiem",
|
|
8325
|
-
options: merOpts,
|
|
8326
|
-
current: mer,
|
|
8327
|
-
open: open === "mer",
|
|
8328
|
-
onOpen: () => setOpen("mer"),
|
|
8329
|
-
onClose: () => setOpen(null),
|
|
8330
|
-
onPick: (v) => {
|
|
8331
|
-
set(h12, m, v);
|
|
8332
|
-
setOpen(null);
|
|
8333
|
-
}
|
|
8334
|
-
}
|
|
8335
|
-
)
|
|
8336
|
-
]
|
|
8337
|
-
}
|
|
8338
|
-
);
|
|
8339
|
-
}
|
|
8340
|
-
);
|
|
8341
|
-
function TimeColumn({
|
|
8342
|
-
options,
|
|
8343
|
-
current,
|
|
8344
|
-
open,
|
|
8345
|
-
onOpen,
|
|
8346
|
-
onClose,
|
|
8347
|
-
onPick,
|
|
8348
|
-
className
|
|
8349
|
-
}) {
|
|
8350
|
-
const colRef = react.useRef(null);
|
|
8351
|
-
const [active, setActive] = react.useState(-1);
|
|
8352
|
-
const selected = options.find((o) => o.value === current);
|
|
8353
|
-
const panel = () => colRef.current?.querySelector(".klun-select-listbox") ?? null;
|
|
8354
|
-
const scrollTo = (i, center) => {
|
|
8355
|
-
requestAnimationFrame(() => {
|
|
8356
|
-
const p = panel();
|
|
8357
|
-
const el = p?.children[i];
|
|
8358
|
-
if (!p || !el) return;
|
|
8359
|
-
if (center) {
|
|
8360
|
-
p.scrollTop = el.offsetTop - p.clientHeight / 2 + el.offsetHeight / 2;
|
|
8361
|
-
} else if (el.offsetTop < p.scrollTop) {
|
|
8362
|
-
p.scrollTop = el.offsetTop - 4;
|
|
8363
|
-
} else if (el.offsetTop + el.offsetHeight > p.scrollTop + p.clientHeight) {
|
|
8364
|
-
p.scrollTop = el.offsetTop + el.offsetHeight - p.clientHeight + 4;
|
|
8365
|
-
}
|
|
8366
|
-
});
|
|
8367
|
-
};
|
|
8368
|
-
react.useEffect(() => {
|
|
8369
|
-
if (!open) return;
|
|
8370
|
-
const idx = options.findIndex((o) => o.value === current);
|
|
8371
|
-
setActive(idx);
|
|
8372
|
-
scrollTo(idx >= 0 ? idx : 0, true);
|
|
8373
|
-
}, [open]);
|
|
8374
|
-
const step = (dir) => {
|
|
8375
|
-
if (!options.length) return;
|
|
8376
|
-
let i = active;
|
|
8377
|
-
for (let n = 0; n < options.length; n++) {
|
|
8378
|
-
i = (i + dir + options.length) % options.length;
|
|
8379
|
-
if (!options[i].disabled) break;
|
|
8380
|
-
}
|
|
8381
|
-
setActive(i);
|
|
8382
|
-
scrollTo(i, false);
|
|
8383
|
-
};
|
|
8384
|
-
const onKeyDown = (e) => {
|
|
8385
|
-
if (!open) {
|
|
8386
|
-
if (["ArrowDown", "ArrowUp", "Enter", " "].includes(e.key)) {
|
|
8387
|
-
e.preventDefault();
|
|
8388
|
-
onOpen();
|
|
8389
|
-
}
|
|
8390
|
-
return;
|
|
8391
|
-
}
|
|
8392
|
-
switch (e.key) {
|
|
8393
|
-
case "ArrowDown":
|
|
8394
|
-
e.preventDefault();
|
|
8395
|
-
step(1);
|
|
8396
|
-
break;
|
|
8397
|
-
case "ArrowUp":
|
|
8398
|
-
e.preventDefault();
|
|
8399
|
-
step(-1);
|
|
8400
|
-
break;
|
|
8401
|
-
case "Enter":
|
|
8402
|
-
case " ":
|
|
8403
|
-
e.preventDefault();
|
|
8404
|
-
if (options[active]) onPick(options[active].value);
|
|
8405
|
-
break;
|
|
8406
|
-
case "Escape":
|
|
8407
|
-
e.preventDefault();
|
|
8408
|
-
onClose();
|
|
8409
|
-
break;
|
|
8410
|
-
case "Tab":
|
|
8411
|
-
onClose();
|
|
8412
|
-
break;
|
|
8413
|
-
}
|
|
8414
|
-
};
|
|
8415
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: colRef, className: chunkTPGAXYFU_cjs.cx("klun-time-picker__col", className), children: [
|
|
8416
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8417
|
-
"button",
|
|
8418
|
-
{
|
|
8419
|
-
type: "button",
|
|
8420
|
-
className: "klun-time-picker__trigger",
|
|
8421
|
-
"aria-haspopup": "listbox",
|
|
8422
|
-
"aria-expanded": open,
|
|
8423
|
-
"data-open": open || void 0,
|
|
8424
|
-
onClick: () => open ? onClose() : onOpen(),
|
|
8425
|
-
onKeyDown,
|
|
8426
|
-
children: selected ? selected.label : ""
|
|
8427
|
-
}
|
|
8428
|
-
),
|
|
8429
|
-
open ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
8430
|
-
SelectListbox,
|
|
8431
|
-
{
|
|
8432
|
-
className: "klun-time-picker__listbox",
|
|
8433
|
-
options,
|
|
8434
|
-
current,
|
|
8435
|
-
active,
|
|
8436
|
-
onActivate: setActive,
|
|
8437
|
-
onPick: (o) => onPick(o.value)
|
|
8438
|
-
}
|
|
8439
|
-
) : null
|
|
8440
|
-
] });
|
|
8441
|
-
}
|
|
8442
|
-
TimePicker.displayName = "TimePicker";
|
|
8443
8500
|
var Card = react.forwardRef(function Card2({ variant = "stroke", padding, className, style, children, ...props }, ref) {
|
|
8444
8501
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8445
8502
|
"div",
|
|
@@ -10048,6 +10105,7 @@ exports.CopyButton = CopyButton;
|
|
|
10048
10105
|
exports.CounterInput = CounterInput;
|
|
10049
10106
|
exports.DatePicker = DatePicker;
|
|
10050
10107
|
exports.DateRangePicker = DateRangePicker;
|
|
10108
|
+
exports.DateTimePicker = DateTimePicker;
|
|
10051
10109
|
exports.Descriptions = Descriptions;
|
|
10052
10110
|
exports.DigitInput = DigitInput;
|
|
10053
10111
|
exports.Divider = Divider;
|
|
@@ -10153,5 +10211,5 @@ exports.useSize = useSize;
|
|
|
10153
10211
|
exports.viVN = viVN;
|
|
10154
10212
|
exports.zhCN = zhCN;
|
|
10155
10213
|
exports.zhTW = zhTW;
|
|
10156
|
-
//# sourceMappingURL=chunk-
|
|
10157
|
-
//# sourceMappingURL=chunk-
|
|
10214
|
+
//# sourceMappingURL=chunk-OPAZ7GAU.cjs.map
|
|
10215
|
+
//# sourceMappingURL=chunk-OPAZ7GAU.cjs.map
|