@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";
@@ -0,0 +1 @@
1
+ export { default as usePrevious } from "./usePrevious";
@@ -0,0 +1,9 @@
1
+ import { useEffect, useRef } from "react";
2
+ function usePrevious(value) {
3
+ const ref = useRef();
4
+ useEffect(() => {
5
+ ref.current = value;
6
+ });
7
+ return ref.current;
8
+ }
9
+ export default usePrevious;
package/dist/index.d.ts CHANGED
@@ -710,6 +710,7 @@ interface TreeProps extends Pick<TreeItemProps, "renderIcon" | "renderRightSecti
710
710
  maxLevel?: number;
711
711
  mode?: "checkbox" | "radio";
712
712
  autoDisabled?: boolean;
713
+ checkedAll?: boolean;
713
714
  }
714
715
 
715
716
  declare const Tree: FC<TreeProps>;
@@ -725,6 +726,8 @@ declare const getStartEndTimestampOfDay: () => {
725
726
  };
726
727
  declare const getTimestampUTC: (date: Date) => number;
727
728
 
729
+ declare function usePrevious<T>(value: T): T | undefined;
730
+
728
731
  declare function cn(...inputs: ClassValue[]): string;
729
732
 
730
- export { ActionButton, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, Calendar, Checkbox, Collapsible, DataTable, type DataTableProps, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type DropdownProps, Icon, Input, InputFilter, type InputFilterProps, type InputProps, Label, Loading, Navbar, type NavbarProps, type Options$1 as Options, Popover, PopoverContent, PopoverTrigger, ProgressBar, Search, type SearchProps, Slider, type SliderProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextInput, Toast$1 as Toast, ToastAction, type ToastActionElement, ToastClose, ToastDescription, type ToastProps, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipSimple, TooltipTrigger, Tree, type TreeData, TreeItem, type TreeItemProps, type TreeProps, cn, getEndDateOfDay, getStartDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, reducer, resloveTimestamp, toast, useToast };
733
+ export { ActionButton, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, Calendar, Checkbox, Collapsible, DataTable, type DataTableProps, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type DropdownProps, Icon, Input, InputFilter, type InputFilterProps, type InputProps, Label, Loading, Navbar, type NavbarProps, type Options$1 as Options, Popover, PopoverContent, PopoverTrigger, ProgressBar, Search, type SearchProps, Slider, type SliderProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextInput, Toast$1 as Toast, ToastAction, type ToastActionElement, ToastClose, ToastDescription, type ToastProps, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipSimple, TooltipTrigger, Tree, type TreeData, TreeItem, type TreeItemProps, type TreeProps, cn, getEndDateOfDay, getStartDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, reducer, resloveTimestamp, toast, usePrevious, useToast };
package/dist/index.js CHANGED
@@ -37,6 +37,8 @@ export * from "./components/Toast/useToast";
37
37
  export * from "./components/Tree";
38
38
  // UTILS
39
39
  export { resloveTimestamp, getStartDateOfDay, getEndDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, } from "./utils/datetime";
40
+ // Hooks
41
+ export * from "./hooks";
40
42
  export { cn } from "./utils/cn";
41
43
  // const mainPreset = require("./theme/main-preset");
42
44
  // export { mainPreset };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rovula/ui",
3
- "version": "0.0.60",
3
+ "version": "0.0.62",
4
4
  "main": "dist/cjs/bundle.js",
5
5
  "module": "dist/esm/bundle.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,6 +8,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "../Popover/Popover";
8
8
  import { Modifiers } from "react-day-picker";
9
9
  import { InputProps, TextInput } from "../TextInput/TextInput";
10
10
  import { format } from "date-fns/format";
11
+ import { cn } from "@/utils/cn";
11
12
 
12
13
  type DatePickerProps = {
13
14
  date: Date | undefined;
@@ -37,7 +38,7 @@ const DatePicker: FC<DatePickerProps> = ({
37
38
  <div className="flex">
38
39
  <TextInput
39
40
  fullwidth
40
- id="2" // TODO
41
+ id="date-picker"
41
42
  readOnly
42
43
  label="Date"
43
44
  size="md"
@@ -47,6 +48,10 @@ const DatePicker: FC<DatePickerProps> = ({
47
48
  <CalendarIcon fill="inherit" className="cursor-pointer" />
48
49
  }
49
50
  {...textInputProps}
51
+ labelClassName={cn(
52
+ "pointer-events-none",
53
+ textInputProps?.labelClassName
54
+ )}
50
55
  />
51
56
  </div>
52
57
  </PopoverTrigger>
@@ -411,3 +411,38 @@ export const RadioMode: StoryObj<typeof Tree> = {
411
411
  );
412
412
  },
413
413
  };
414
+
415
+ export const CheckAll: StoryObj<typeof Tree> = {
416
+ args: {
417
+ data: exampleData,
418
+ },
419
+ render: (args) => {
420
+ const [isCheckedAll, setIsCheckedAll] = useState(false);
421
+ const [checkedId, onCheckedId] = useState<string[]>([]);
422
+
423
+ return (
424
+ <div className="flex flex-col gap-4 w-full">
425
+ <div className="flex gap-2">
426
+ <Button
427
+ variant="outline"
428
+ onClick={() => setIsCheckedAll(!isCheckedAll)}
429
+ >
430
+ {isCheckedAll ? "Unchecked" : "Checked"} All
431
+ </Button>
432
+ <Button variant="outline" onClick={() => onCheckedId([])}>
433
+ Clear
434
+ </Button>
435
+ </div>
436
+ <Tree
437
+ {...args}
438
+ hierarchicalCheck
439
+ checkedAll={isCheckedAll}
440
+ checkedId={checkedId}
441
+ onCheckedChange={(state) => {
442
+ onCheckedId(Object.keys(state).filter((key) => state?.[key]));
443
+ }}
444
+ />
445
+ </div>
446
+ );
447
+ },
448
+ };
@@ -2,6 +2,7 @@ import React, { FC, useCallback, useEffect, useState } from "react";
2
2
  import TreeItem from "./TreeItem";
3
3
  import { TreeData, TreeProps } from "./type";
4
4
  import { cn } from "@/utils/cn";
5
+ import { usePrevious } from "@/hooks";
5
6
 
6
7
  const Tree: FC<TreeProps> = ({
7
8
  classes,
@@ -32,6 +33,7 @@ const Tree: FC<TreeProps> = ({
32
33
  maxLevel,
33
34
  mode = "checkbox",
34
35
  autoDisabled = false,
36
+ checkedAll = false,
35
37
  }) => {
36
38
  const [checkedState, setCheckedState] = useState<Record<string, boolean>>({});
37
39
  const [expandedState, setExpandedState] = useState<Record<string, boolean>>(
@@ -93,6 +95,7 @@ const Tree: FC<TreeProps> = ({
93
95
  }
94
96
  }, [checkedId]);
95
97
 
98
+ // For usecase loaded data a children coming after.
96
99
  useEffect(() => {
97
100
  if (!hierarchicalCheck) {
98
101
  return;
@@ -124,6 +127,36 @@ const Tree: FC<TreeProps> = ({
124
127
  });
125
128
  }, [data, hierarchicalCheck]);
126
129
 
130
+ const prevCheckedAll = usePrevious(checkedAll);
131
+ useEffect(() => {
132
+ if (prevCheckedAll === undefined || prevCheckedAll === checkedAll) return;
133
+ if (checkedAll) {
134
+ const newState: Record<string, boolean> = {};
135
+
136
+ traverseTree(data, (node) => {
137
+ if (node.id) {
138
+ newState[node.id] = true;
139
+ }
140
+ });
141
+ setCheckedState(newState);
142
+ onCheckedChange?.(newState, undefined, null);
143
+ } else {
144
+ let newState: Record<string, boolean> = {};
145
+
146
+ setCheckedState((prev) => {
147
+ newState = Object.keys(prev).reduce(
148
+ (p, key) => ({
149
+ ...p,
150
+ [key]: false,
151
+ }),
152
+ {}
153
+ );
154
+ return newState;
155
+ });
156
+ onCheckedChange?.(newState, undefined, null);
157
+ }
158
+ }, [data, checkedAll, prevCheckedAll]);
159
+
127
160
  const handleExpandChange = useCallback(
128
161
  (id: string, expanded: boolean, itemData: any) => {
129
162
  onExpandChange?.(id, expanded, itemData);
@@ -117,4 +117,5 @@ export interface TreeProps
117
117
  mode?: "checkbox" | "radio";
118
118
  // Only radio mode
119
119
  autoDisabled?: boolean;
120
+ checkedAll?: boolean;
120
121
  }
@@ -0,0 +1 @@
1
+ export { default as usePrevious } from "./usePrevious";
@@ -0,0 +1,13 @@
1
+ import { useEffect, useRef } from "react";
2
+
3
+ function usePrevious<T>(value: T): T | undefined {
4
+ const ref = useRef<T>();
5
+
6
+ useEffect(() => {
7
+ ref.current = value;
8
+ });
9
+
10
+ return ref.current;
11
+ }
12
+
13
+ export default usePrevious;
package/src/index.ts CHANGED
@@ -58,6 +58,9 @@ export {
58
58
  getTimestampUTC,
59
59
  } from "./utils/datetime";
60
60
 
61
+ // Hooks
62
+ export * from "./hooks";
63
+
61
64
  export { cn } from "./utils/cn";
62
65
 
63
66
  // const mainPreset = require("./theme/main-preset");