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.
@@ -6888,8 +6888,264 @@ var DatePicker = forwardRef(
6888
6888
  }
6889
6889
  );
6890
6890
  DatePicker.displayName = "DatePicker";
6891
+ var pad = (n) => String(n).padStart(2, "0");
6892
+ var TimePicker = forwardRef(
6893
+ function TimePicker2({ value = "09:00", onChange, className, style, ...props }, ref) {
6894
+ const t = useLocale();
6895
+ const [h, m] = value.split(":").map(Number);
6896
+ const mer = h >= 12 ? "PM" : "AM";
6897
+ const h12 = (h + 11) % 12 + 1;
6898
+ const set = (nh, nm, nmer) => {
6899
+ let hh = nh % 12;
6900
+ if (nmer === "PM") hh += 12;
6901
+ onChange?.(`${pad(hh)}:${pad(nm)}`);
6902
+ };
6903
+ const [open, setOpen] = useState(null);
6904
+ const rootRef = useRef(null);
6905
+ const setRoot = (node) => {
6906
+ rootRef.current = node;
6907
+ if (typeof ref === "function") ref(node);
6908
+ else if (ref) ref.current = node;
6909
+ };
6910
+ useEffect(() => {
6911
+ if (!open) return;
6912
+ const onDown = (e) => {
6913
+ if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(null);
6914
+ };
6915
+ document.addEventListener("mousedown", onDown);
6916
+ return () => document.removeEventListener("mousedown", onDown);
6917
+ }, [open]);
6918
+ const hourOpts = Array.from({ length: 12 }, (_, i) => ({
6919
+ value: String(i + 1),
6920
+ label: pad(i + 1)
6921
+ }));
6922
+ const minOpts = Array.from({ length: 60 }, (_, i) => ({
6923
+ value: String(i),
6924
+ label: pad(i)
6925
+ }));
6926
+ const merOpts = [
6927
+ { value: "AM", label: t.timePicker.am },
6928
+ { value: "PM", label: t.timePicker.pm }
6929
+ ];
6930
+ return /* @__PURE__ */ jsxs(
6931
+ "div",
6932
+ {
6933
+ ref: setRoot,
6934
+ className: cx("klun-time-picker", className),
6935
+ style,
6936
+ ...props,
6937
+ children: [
6938
+ /* @__PURE__ */ jsx("i", { className: "ri-time-line klun-time-picker__icon" }),
6939
+ /* @__PURE__ */ jsx(
6940
+ TimeColumn,
6941
+ {
6942
+ options: hourOpts,
6943
+ current: String(h12),
6944
+ open: open === "h",
6945
+ onOpen: () => setOpen("h"),
6946
+ onClose: () => setOpen(null),
6947
+ onPick: (v) => {
6948
+ set(Number(v), m, mer);
6949
+ setOpen(null);
6950
+ }
6951
+ }
6952
+ ),
6953
+ /* @__PURE__ */ jsx("span", { className: "klun-time-picker__sep", children: ":" }),
6954
+ /* @__PURE__ */ jsx(
6955
+ TimeColumn,
6956
+ {
6957
+ options: minOpts,
6958
+ current: String(m),
6959
+ open: open === "m",
6960
+ onOpen: () => setOpen("m"),
6961
+ onClose: () => setOpen(null),
6962
+ onPick: (v) => {
6963
+ set(h12, Number(v), mer);
6964
+ setOpen(null);
6965
+ }
6966
+ }
6967
+ ),
6968
+ /* @__PURE__ */ jsx(
6969
+ TimeColumn,
6970
+ {
6971
+ className: "klun-time-picker__col--meridiem",
6972
+ options: merOpts,
6973
+ current: mer,
6974
+ open: open === "mer",
6975
+ onOpen: () => setOpen("mer"),
6976
+ onClose: () => setOpen(null),
6977
+ onPick: (v) => {
6978
+ set(h12, m, v);
6979
+ setOpen(null);
6980
+ }
6981
+ }
6982
+ )
6983
+ ]
6984
+ }
6985
+ );
6986
+ }
6987
+ );
6988
+ function TimeColumn({
6989
+ options,
6990
+ current,
6991
+ open,
6992
+ onOpen,
6993
+ onClose,
6994
+ onPick,
6995
+ className
6996
+ }) {
6997
+ const colRef = useRef(null);
6998
+ const [active, setActive] = useState(-1);
6999
+ const selected = options.find((o) => o.value === current);
7000
+ const panel = () => colRef.current?.querySelector(".klun-select-listbox") ?? null;
7001
+ const scrollTo = (i, center) => {
7002
+ requestAnimationFrame(() => {
7003
+ const p = panel();
7004
+ const el = p?.children[i];
7005
+ if (!p || !el) return;
7006
+ if (center) {
7007
+ p.scrollTop = el.offsetTop - p.clientHeight / 2 + el.offsetHeight / 2;
7008
+ } else if (el.offsetTop < p.scrollTop) {
7009
+ p.scrollTop = el.offsetTop - 4;
7010
+ } else if (el.offsetTop + el.offsetHeight > p.scrollTop + p.clientHeight) {
7011
+ p.scrollTop = el.offsetTop + el.offsetHeight - p.clientHeight + 4;
7012
+ }
7013
+ });
7014
+ };
7015
+ useEffect(() => {
7016
+ if (!open) return;
7017
+ const idx = options.findIndex((o) => o.value === current);
7018
+ setActive(idx);
7019
+ scrollTo(idx >= 0 ? idx : 0, true);
7020
+ }, [open]);
7021
+ const step = (dir) => {
7022
+ if (!options.length) return;
7023
+ let i = active;
7024
+ for (let n = 0; n < options.length; n++) {
7025
+ i = (i + dir + options.length) % options.length;
7026
+ if (!options[i].disabled) break;
7027
+ }
7028
+ setActive(i);
7029
+ scrollTo(i, false);
7030
+ };
7031
+ const onKeyDown = (e) => {
7032
+ if (!open) {
7033
+ if (["ArrowDown", "ArrowUp", "Enter", " "].includes(e.key)) {
7034
+ e.preventDefault();
7035
+ onOpen();
7036
+ }
7037
+ return;
7038
+ }
7039
+ switch (e.key) {
7040
+ case "ArrowDown":
7041
+ e.preventDefault();
7042
+ step(1);
7043
+ break;
7044
+ case "ArrowUp":
7045
+ e.preventDefault();
7046
+ step(-1);
7047
+ break;
7048
+ case "Enter":
7049
+ case " ":
7050
+ e.preventDefault();
7051
+ if (options[active]) onPick(options[active].value);
7052
+ break;
7053
+ case "Escape":
7054
+ e.preventDefault();
7055
+ onClose();
7056
+ break;
7057
+ case "Tab":
7058
+ onClose();
7059
+ break;
7060
+ }
7061
+ };
7062
+ return /* @__PURE__ */ jsxs("div", { ref: colRef, className: cx("klun-time-picker__col", className), children: [
7063
+ /* @__PURE__ */ jsx(
7064
+ "button",
7065
+ {
7066
+ type: "button",
7067
+ className: "klun-time-picker__trigger",
7068
+ "aria-haspopup": "listbox",
7069
+ "aria-expanded": open,
7070
+ "data-open": open || void 0,
7071
+ onClick: () => open ? onClose() : onOpen(),
7072
+ onKeyDown,
7073
+ children: selected ? selected.label : ""
7074
+ }
7075
+ ),
7076
+ open ? /* @__PURE__ */ jsx(
7077
+ SelectListbox,
7078
+ {
7079
+ className: "klun-time-picker__listbox",
7080
+ options,
7081
+ current,
7082
+ active,
7083
+ onActivate: setActive,
7084
+ onPick: (o) => onPick(o.value)
7085
+ }
7086
+ ) : null
7087
+ ] });
7088
+ }
7089
+ TimePicker.displayName = "TimePicker";
7090
+ var pad2 = (n) => String(n).padStart(2, "0");
7091
+ var DEFAULT_FORMAT2 = {
7092
+ year: "numeric",
7093
+ month: "short",
7094
+ day: "numeric",
7095
+ hour: "2-digit",
7096
+ minute: "2-digit"
7097
+ };
7098
+ function DateTimePanel({ value, onChange }) {
7099
+ const hhmm = value ? `${pad2(value.getHours())}:${pad2(value.getMinutes())}` : "09:00";
7100
+ const setDate = (d) => {
7101
+ const next = new Date(d);
7102
+ if (value) next.setHours(value.getHours(), value.getMinutes(), 0, 0);
7103
+ else next.setHours(9, 0, 0, 0);
7104
+ onChange(next);
7105
+ };
7106
+ const setTime = (t) => {
7107
+ const [h, m] = t.split(":").map(Number);
7108
+ const next = value ? new Date(value) : /* @__PURE__ */ new Date();
7109
+ next.setHours(h, m, 0, 0);
7110
+ onChange(next);
7111
+ };
7112
+ return /* @__PURE__ */ jsxs("div", { className: "klun-date-time-picker__panel", children: [
7113
+ /* @__PURE__ */ jsx(DatePicker, { inline: true, className: "klun-date-picker--bare", value, onChange: setDate }),
7114
+ /* @__PURE__ */ jsx("div", { className: "klun-date-time-picker__time", children: /* @__PURE__ */ jsx(TimePicker, { value: hhmm, onChange: setTime }) })
7115
+ ] });
7116
+ }
7117
+ var DateTimePicker = forwardRef(
7118
+ function DateTimePicker2({ value, onChange, inline, placeholder, format = DEFAULT_FORMAT2, align = "left", disabled, className, style, ...props }, ref) {
7119
+ const date = value ? new Date(value) : null;
7120
+ if (inline) {
7121
+ return /* @__PURE__ */ jsx("div", { ref, className: cx("klun-date-time-picker", className), style, ...props, children: /* @__PURE__ */ jsx(DateTimePanel, { value: date, onChange: (d) => onChange?.(d) }) });
7122
+ }
7123
+ const label = date ? date.toLocaleString(void 0, format) : "";
7124
+ return /* @__PURE__ */ jsx("div", { ref, className: cx("klun-date-time-field", className), style, ...props, children: /* @__PURE__ */ jsx(
7125
+ Popover,
7126
+ {
7127
+ align,
7128
+ width: 300,
7129
+ trigger: /* @__PURE__ */ jsx(
7130
+ Input,
7131
+ {
7132
+ readOnly: true,
7133
+ disabled,
7134
+ value: label,
7135
+ placeholder: placeholder ?? "Select date & time",
7136
+ leadingIcon: /* @__PURE__ */ jsx("i", { className: "ri-calendar-2-line" }),
7137
+ trailingIcon: /* @__PURE__ */ jsx("i", { className: "ri-arrow-down-s-line" }),
7138
+ style: { width: "100%", cursor: "pointer" }
7139
+ }
7140
+ ),
7141
+ children: /* @__PURE__ */ jsx(DateTimePanel, { value: date, onChange: (d) => onChange?.(d) })
7142
+ }
7143
+ ) });
7144
+ }
7145
+ );
7146
+ DateTimePicker.displayName = "DateTimePicker";
6891
7147
  var norm = (d) => d && new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
6892
- var DEFAULT_FORMAT2 = { month: "short", day: "numeric" };
7148
+ var DEFAULT_FORMAT3 = { month: "short", day: "numeric" };
6893
7149
  var RangeCalendar = forwardRef(function RangeCalendar2({ start, end, onPick, className, style }, ref) {
6894
7150
  const { datePicker } = useLocale();
6895
7151
  const base = start ? new Date(start) : /* @__PURE__ */ new Date();
@@ -6948,7 +7204,7 @@ var RangeCalendar = forwardRef(function RangeCalendar2({ start, end, onPick, cla
6948
7204
  ] });
6949
7205
  });
6950
7206
  var DateRangePicker = forwardRef(
6951
- function DateRangePicker2({ start, end, onChange, inline, placeholder, format = DEFAULT_FORMAT2, align = "left", disabled, className, style, ...props }, ref) {
7207
+ function DateRangePicker2({ start, end, onChange, inline, placeholder, format = DEFAULT_FORMAT3, align = "left", disabled, className, style, ...props }, ref) {
6952
7208
  if (inline) {
6953
7209
  return /* @__PURE__ */ jsx(
6954
7210
  RangeCalendar,
@@ -8239,205 +8495,6 @@ var Textarea = forwardRef(function Textarea2({ error = false, disabled = false,
8239
8495
  );
8240
8496
  });
8241
8497
  Textarea.displayName = "Textarea";
8242
- var pad = (n) => String(n).padStart(2, "0");
8243
- var TimePicker = forwardRef(
8244
- function TimePicker2({ value = "09:00", onChange, className, style, ...props }, ref) {
8245
- const t = useLocale();
8246
- const [h, m] = value.split(":").map(Number);
8247
- const mer = h >= 12 ? "PM" : "AM";
8248
- const h12 = (h + 11) % 12 + 1;
8249
- const set = (nh, nm, nmer) => {
8250
- let hh = nh % 12;
8251
- if (nmer === "PM") hh += 12;
8252
- onChange?.(`${pad(hh)}:${pad(nm)}`);
8253
- };
8254
- const [open, setOpen] = useState(null);
8255
- const rootRef = useRef(null);
8256
- const setRoot = (node) => {
8257
- rootRef.current = node;
8258
- if (typeof ref === "function") ref(node);
8259
- else if (ref) ref.current = node;
8260
- };
8261
- useEffect(() => {
8262
- if (!open) return;
8263
- const onDown = (e) => {
8264
- if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(null);
8265
- };
8266
- document.addEventListener("mousedown", onDown);
8267
- return () => document.removeEventListener("mousedown", onDown);
8268
- }, [open]);
8269
- const hourOpts = Array.from({ length: 12 }, (_, i) => ({
8270
- value: String(i + 1),
8271
- label: pad(i + 1)
8272
- }));
8273
- const minOpts = Array.from({ length: 60 }, (_, i) => ({
8274
- value: String(i),
8275
- label: pad(i)
8276
- }));
8277
- const merOpts = [
8278
- { value: "AM", label: t.timePicker.am },
8279
- { value: "PM", label: t.timePicker.pm }
8280
- ];
8281
- return /* @__PURE__ */ jsxs(
8282
- "div",
8283
- {
8284
- ref: setRoot,
8285
- className: cx("klun-time-picker", className),
8286
- style,
8287
- ...props,
8288
- children: [
8289
- /* @__PURE__ */ jsx("i", { className: "ri-time-line klun-time-picker__icon" }),
8290
- /* @__PURE__ */ jsx(
8291
- TimeColumn,
8292
- {
8293
- options: hourOpts,
8294
- current: String(h12),
8295
- open: open === "h",
8296
- onOpen: () => setOpen("h"),
8297
- onClose: () => setOpen(null),
8298
- onPick: (v) => {
8299
- set(Number(v), m, mer);
8300
- setOpen(null);
8301
- }
8302
- }
8303
- ),
8304
- /* @__PURE__ */ jsx("span", { className: "klun-time-picker__sep", children: ":" }),
8305
- /* @__PURE__ */ jsx(
8306
- TimeColumn,
8307
- {
8308
- options: minOpts,
8309
- current: String(m),
8310
- open: open === "m",
8311
- onOpen: () => setOpen("m"),
8312
- onClose: () => setOpen(null),
8313
- onPick: (v) => {
8314
- set(h12, Number(v), mer);
8315
- setOpen(null);
8316
- }
8317
- }
8318
- ),
8319
- /* @__PURE__ */ jsx(
8320
- TimeColumn,
8321
- {
8322
- className: "klun-time-picker__col--meridiem",
8323
- options: merOpts,
8324
- current: mer,
8325
- open: open === "mer",
8326
- onOpen: () => setOpen("mer"),
8327
- onClose: () => setOpen(null),
8328
- onPick: (v) => {
8329
- set(h12, m, v);
8330
- setOpen(null);
8331
- }
8332
- }
8333
- )
8334
- ]
8335
- }
8336
- );
8337
- }
8338
- );
8339
- function TimeColumn({
8340
- options,
8341
- current,
8342
- open,
8343
- onOpen,
8344
- onClose,
8345
- onPick,
8346
- className
8347
- }) {
8348
- const colRef = useRef(null);
8349
- const [active, setActive] = useState(-1);
8350
- const selected = options.find((o) => o.value === current);
8351
- const panel = () => colRef.current?.querySelector(".klun-select-listbox") ?? null;
8352
- const scrollTo = (i, center) => {
8353
- requestAnimationFrame(() => {
8354
- const p = panel();
8355
- const el = p?.children[i];
8356
- if (!p || !el) return;
8357
- if (center) {
8358
- p.scrollTop = el.offsetTop - p.clientHeight / 2 + el.offsetHeight / 2;
8359
- } else if (el.offsetTop < p.scrollTop) {
8360
- p.scrollTop = el.offsetTop - 4;
8361
- } else if (el.offsetTop + el.offsetHeight > p.scrollTop + p.clientHeight) {
8362
- p.scrollTop = el.offsetTop + el.offsetHeight - p.clientHeight + 4;
8363
- }
8364
- });
8365
- };
8366
- useEffect(() => {
8367
- if (!open) return;
8368
- const idx = options.findIndex((o) => o.value === current);
8369
- setActive(idx);
8370
- scrollTo(idx >= 0 ? idx : 0, true);
8371
- }, [open]);
8372
- const step = (dir) => {
8373
- if (!options.length) return;
8374
- let i = active;
8375
- for (let n = 0; n < options.length; n++) {
8376
- i = (i + dir + options.length) % options.length;
8377
- if (!options[i].disabled) break;
8378
- }
8379
- setActive(i);
8380
- scrollTo(i, false);
8381
- };
8382
- const onKeyDown = (e) => {
8383
- if (!open) {
8384
- if (["ArrowDown", "ArrowUp", "Enter", " "].includes(e.key)) {
8385
- e.preventDefault();
8386
- onOpen();
8387
- }
8388
- return;
8389
- }
8390
- switch (e.key) {
8391
- case "ArrowDown":
8392
- e.preventDefault();
8393
- step(1);
8394
- break;
8395
- case "ArrowUp":
8396
- e.preventDefault();
8397
- step(-1);
8398
- break;
8399
- case "Enter":
8400
- case " ":
8401
- e.preventDefault();
8402
- if (options[active]) onPick(options[active].value);
8403
- break;
8404
- case "Escape":
8405
- e.preventDefault();
8406
- onClose();
8407
- break;
8408
- case "Tab":
8409
- onClose();
8410
- break;
8411
- }
8412
- };
8413
- return /* @__PURE__ */ jsxs("div", { ref: colRef, className: cx("klun-time-picker__col", className), children: [
8414
- /* @__PURE__ */ jsx(
8415
- "button",
8416
- {
8417
- type: "button",
8418
- className: "klun-time-picker__trigger",
8419
- "aria-haspopup": "listbox",
8420
- "aria-expanded": open,
8421
- "data-open": open || void 0,
8422
- onClick: () => open ? onClose() : onOpen(),
8423
- onKeyDown,
8424
- children: selected ? selected.label : ""
8425
- }
8426
- ),
8427
- open ? /* @__PURE__ */ jsx(
8428
- SelectListbox,
8429
- {
8430
- className: "klun-time-picker__listbox",
8431
- options,
8432
- current,
8433
- active,
8434
- onActivate: setActive,
8435
- onPick: (o) => onPick(o.value)
8436
- }
8437
- ) : null
8438
- ] });
8439
- }
8440
- TimePicker.displayName = "TimePicker";
8441
8498
  var Card = forwardRef(function Card2({ variant = "stroke", padding, className, style, children, ...props }, ref) {
8442
8499
  return /* @__PURE__ */ jsx(
8443
8500
  "div",
@@ -10009,6 +10066,6 @@ var Popconfirm = forwardRef(function Popconfirm2({
10009
10066
  });
10010
10067
  Popconfirm.displayName = "Popconfirm";
10011
10068
 
10012
- export { Accordion, Alert, AutoComplete, Avatar, AvatarGroup, Badge, Banner, Breadcrumb, BulkAction, BulkActionBar, Button, ButtonGroup, Card, Carousel, Cascader, CharacterCounter, ChartLegend, ChartTooltip, Checkbox, CheckboxCard, Chip, CircularProgress, CodeViewer, Col, ColorDot, ColorPicker, ColorSlider, CommandMenu, CompactSelect, CompactSelectForInput, ConfigProvider, Confirm, ContentLabel, CopyButton, CounterInput, DatePicker, DateRangePicker, Descriptions, DigitInput, Divider, Drawer, Dropdown, ExpiryCountdown, FileUpload, Flex, Form, FormItem, FormList, Format, GaugeBar, Grid, Hint, HorizontalFilter, ImageUpload, InlineInput, InlineSelect, Input, Kbd, KeyIcon, Label, Layout, LayoutContent, LayoutFooter, LayoutHeader, LayoutSider, List, ListItem, LiveDot, LogViewer, Masonry, Menu, Message, Modal, Money, Notification, Pagination, PasswordStrength, Popconfirm, Popover, ProgressBar, Radio, RadioCard, RangeSlider, Rating, RelativeTime, RichEditorToolbar, Row, SegmentedControl, SegmentedProgress, Select, SelectMenu, Skeleton, Slider, Space, Spinner2 as Spinner, Splitter2 as Splitter, SplitterPanel, Statistic, StatusBadge, StatusDot, StepIndicator, Switch, Table, Tabs, Tag, Textarea, TimePicker, Timeline, Toast, Toaster, Tooltip, Tree, Wizard, arSA, deDE, enUS, esES, fmt, frFR, idID, itIT, jaJP, koKR, locales, nlNL, plPL, primaryColorVars, ptBR, ruRU, toast, trTR, useBreakpoint, useConfig, useForm, useLocale, useMappedSize, useMessage, useNotification, useSize, viVN, zhCN, zhTW };
10013
- //# sourceMappingURL=chunk-DVPY6FDU.js.map
10014
- //# sourceMappingURL=chunk-DVPY6FDU.js.map
10069
+ export { Accordion, Alert, AutoComplete, Avatar, AvatarGroup, Badge, Banner, Breadcrumb, BulkAction, BulkActionBar, Button, ButtonGroup, Card, Carousel, Cascader, CharacterCounter, ChartLegend, ChartTooltip, Checkbox, CheckboxCard, Chip, CircularProgress, CodeViewer, Col, ColorDot, ColorPicker, ColorSlider, CommandMenu, CompactSelect, CompactSelectForInput, ConfigProvider, Confirm, ContentLabel, CopyButton, CounterInput, DatePicker, DateRangePicker, DateTimePicker, Descriptions, DigitInput, Divider, Drawer, Dropdown, ExpiryCountdown, FileUpload, Flex, Form, FormItem, FormList, Format, GaugeBar, Grid, Hint, HorizontalFilter, ImageUpload, InlineInput, InlineSelect, Input, Kbd, KeyIcon, Label, Layout, LayoutContent, LayoutFooter, LayoutHeader, LayoutSider, List, ListItem, LiveDot, LogViewer, Masonry, Menu, Message, Modal, Money, Notification, Pagination, PasswordStrength, Popconfirm, Popover, ProgressBar, Radio, RadioCard, RangeSlider, Rating, RelativeTime, RichEditorToolbar, Row, SegmentedControl, SegmentedProgress, Select, SelectMenu, Skeleton, Slider, Space, Spinner2 as Spinner, Splitter2 as Splitter, SplitterPanel, Statistic, StatusBadge, StatusDot, StepIndicator, Switch, Table, Tabs, Tag, Textarea, TimePicker, Timeline, Toast, Toaster, Tooltip, Tree, Wizard, arSA, deDE, enUS, esES, fmt, frFR, idID, itIT, jaJP, koKR, locales, nlNL, plPL, primaryColorVars, ptBR, ruRU, toast, trTR, useBreakpoint, useConfig, useForm, useLocale, useMappedSize, useMessage, useNotification, useSize, viVN, zhCN, zhTW };
10070
+ //# sourceMappingURL=chunk-RRE3PQLX.js.map
10071
+ //# sourceMappingURL=chunk-RRE3PQLX.js.map