@rovula/ui 0.0.60 → 0.0.62

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.
@@ -15,3 +15,4 @@ export declare const MaximumLevel: StoryObj<typeof Tree>;
15
15
  export declare const Leaf: StoryObj<typeof Tree>;
16
16
  export declare const HideCheckboxMode: StoryObj<typeof Tree>;
17
17
  export declare const RadioMode: StoryObj<typeof Tree>;
18
+ export declare const CheckAll: StoryObj<typeof Tree>;
@@ -94,4 +94,5 @@ export interface TreeProps extends Pick<TreeItemProps, "renderIcon" | "renderRig
94
94
  maxLevel?: number;
95
95
  mode?: "checkbox" | "radio";
96
96
  autoDisabled?: boolean;
97
+ checkedAll?: boolean;
97
98
  }
@@ -0,0 +1 @@
1
+ export { default as usePrevious } from "./usePrevious";
@@ -0,0 +1,2 @@
1
+ declare function usePrevious<T>(value: T): T | undefined;
2
+ export default usePrevious;
@@ -40,4 +40,5 @@ export type { NavbarProps } from "./components/Navbar/Navbar";
40
40
  export type { AvatarProps } from "./components/Avatar/Avatar";
41
41
  export type { AvatarGroupProps } from "./components/Avatar/AvatarGroup";
42
42
  export { resloveTimestamp, getStartDateOfDay, getEndDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, } from "./utils/datetime";
43
+ export * from "./hooks";
43
44
  export { cn } from "./utils/cn";
@@ -17,11 +17,11 @@ import { Calendar } from "../Calendar";
17
17
  import { Popover, PopoverContent, PopoverTrigger } from "../Popover/Popover";
18
18
  import { TextInput } from "../TextInput/TextInput";
19
19
  import { format } from "date-fns/format";
20
+ import { cn } from "@/utils/cn";
20
21
  const DatePicker = (_a) => {
21
22
  var { date, onSelect, textInputProps, popoverContentProps } = _a, props = __rest(_a, ["date", "onSelect", "textInputProps", "popoverContentProps"]);
22
23
  const [isOpen, setIsOpen] = useState(false);
23
- return (_jsx("div", { children: _jsxs(Popover, { modal: true, open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("div", { className: "flex", children: _jsx(TextInput, Object.assign({ fullwidth: true, id: "2" // TODO
24
- , readOnly: true, label: "Date", size: "md", value: date ? format(date, "dd MMM yyyy") : isOpen ? " " : "", hasClearIcon: false, endIcon: _jsx(CalendarIcon, { fill: "inherit", className: "cursor-pointer" }) }, textInputProps)) }) }), _jsx(PopoverContent, Object.assign({ className: "w-auto p-0 z-[100]" }, popoverContentProps, { children: _jsx(Calendar, Object.assign({ defaultMonth: date }, props, { mode: "single", selected: date, onSelect: (...value) => {
24
+ return (_jsx("div", { children: _jsxs(Popover, { modal: true, open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("div", { className: "flex", children: _jsx(TextInput, Object.assign({ fullwidth: true, id: "date-picker", readOnly: true, label: "Date", size: "md", value: date ? format(date, "dd MMM yyyy") : isOpen ? " " : "", hasClearIcon: false, endIcon: _jsx(CalendarIcon, { fill: "inherit", className: "cursor-pointer" }) }, textInputProps, { labelClassName: cn("pointer-events-none", textInputProps === null || textInputProps === void 0 ? void 0 : textInputProps.labelClassName) })) }) }), _jsx(PopoverContent, Object.assign({ className: "w-auto p-0 z-[100]" }, popoverContentProps, { children: _jsx(Calendar, Object.assign({ defaultMonth: date }, props, { mode: "single", selected: date, onSelect: (...value) => {
25
25
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(...value);
26
26
  setIsOpen(false);
27
27
  } })) }))] }) }));
@@ -2,7 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useState } from "react";
3
3
  import TreeItem from "./TreeItem";
4
4
  import { cn } from "@/utils/cn";
5
- const Tree = ({ classes, data, defaultExpandedId, defaultCheckedId, checkedId, loadingId, lineSize, horizontalLineWidth, expandButtonSize, spacing, renderIcon, renderRightSection, renderElement, renderTitle, onExpandChange, onCheckedChange, onClickItem, onCheckedItem, defaultExpandAll = false, defaultCheckAll = false, hierarchicalCheck = false, showIcon = true, disabled, enableSeparatorLine = true, checkable = true, maxLevel, mode = "checkbox", autoDisabled = false, }) => {
5
+ import { usePrevious } from "@/hooks";
6
+ const Tree = ({ classes, data, defaultExpandedId, defaultCheckedId, checkedId, loadingId, lineSize, horizontalLineWidth, expandButtonSize, spacing, renderIcon, renderRightSection, renderElement, renderTitle, onExpandChange, onCheckedChange, onClickItem, onCheckedItem, defaultExpandAll = false, defaultCheckAll = false, hierarchicalCheck = false, showIcon = true, disabled, enableSeparatorLine = true, checkable = true, maxLevel, mode = "checkbox", autoDisabled = false, checkedAll = false, }) => {
6
7
  const [checkedState, setCheckedState] = useState({});
7
8
  const [expandedState, setExpandedState] = useState({});
8
9
  const traverseTree = (nodes, callback) => {
@@ -52,6 +53,7 @@ const Tree = ({ classes, data, defaultExpandedId, defaultCheckedId, checkedId, l
52
53
  setCheckedState(checkedId.reduce((prev, cur) => (Object.assign(Object.assign({}, prev), { [cur]: true })), {}));
53
54
  }
54
55
  }, [checkedId]);
56
+ // For usecase loaded data a children coming after.
55
57
  useEffect(() => {
56
58
  if (!hierarchicalCheck) {
57
59
  return;
@@ -76,6 +78,29 @@ const Tree = ({ classes, data, defaultExpandedId, defaultCheckedId, checkedId, l
76
78
  return Object.assign(Object.assign({}, prev), state);
77
79
  });
78
80
  }, [data, hierarchicalCheck]);
81
+ const prevCheckedAll = usePrevious(checkedAll);
82
+ useEffect(() => {
83
+ if (prevCheckedAll === undefined || prevCheckedAll === checkedAll)
84
+ return;
85
+ if (checkedAll) {
86
+ const newState = {};
87
+ traverseTree(data, (node) => {
88
+ if (node.id) {
89
+ newState[node.id] = true;
90
+ }
91
+ });
92
+ setCheckedState(newState);
93
+ onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(newState, undefined, null);
94
+ }
95
+ else {
96
+ let newState = {};
97
+ setCheckedState((prev) => {
98
+ newState = Object.keys(prev).reduce((p, key) => (Object.assign(Object.assign({}, p), { [key]: false })), {});
99
+ return newState;
100
+ });
101
+ onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(newState, undefined, null);
102
+ }
103
+ }, [data, checkedAll, prevCheckedAll]);
79
104
  const handleExpandChange = useCallback((id, expanded, itemData) => {
80
105
  onExpandChange === null || onExpandChange === void 0 ? void 0 : onExpandChange(id, expanded, itemData);
81
106
  setExpandedState((prev) => (Object.assign(Object.assign({}, prev), { [id]: expanded })));
@@ -210,3 +210,15 @@ export const RadioMode = {
210
210
  } }))] }));
211
211
  },
212
212
  };
213
+ export const CheckAll = {
214
+ args: {
215
+ data: exampleData,
216
+ },
217
+ render: (args) => {
218
+ const [isCheckedAll, setIsCheckedAll] = useState(false);
219
+ const [checkedId, onCheckedId] = useState([]);
220
+ return (_jsxs("div", { className: "flex flex-col gap-4 w-full", children: [_jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", onClick: () => setIsCheckedAll(!isCheckedAll), children: [isCheckedAll ? "Unchecked" : "Checked", " All"] }), _jsx(Button, { variant: "outline", onClick: () => onCheckedId([]), children: "Clear" })] }), _jsx(Tree, Object.assign({}, args, { hierarchicalCheck: true, checkedAll: isCheckedAll, checkedId: checkedId, onCheckedChange: (state) => {
221
+ onCheckedId(Object.keys(state).filter((key) => state === null || state === void 0 ? void 0 : state[key]));
222
+ } }))] }));
223
+ },
224
+ };