@rovula/ui 0.0.54 → 0.0.55
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/dist/cjs/bundle.css +7 -3
- package/dist/cjs/bundle.js +1 -1
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/Tree/Tree.stories.d.ts +1 -0
- package/dist/cjs/types/components/Tree/type.d.ts +3 -0
- package/dist/components/Tree/Tree.js +30 -3
- package/dist/components/Tree/Tree.stories.js +15 -2
- package/dist/components/Tree/TreeItem.js +5 -5
- package/dist/esm/bundle.css +7 -3
- package/dist/esm/bundle.js +1 -1
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Tree/Tree.stories.d.ts +1 -0
- package/dist/esm/types/components/Tree/type.d.ts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/src/theme/global.css +8 -3
- package/package.json +1 -1
- package/src/components/Tree/Tree.stories.tsx +29 -1
- package/src/components/Tree/Tree.tsx +41 -2
- package/src/components/Tree/TreeItem.tsx +6 -4
- package/src/components/Tree/type.ts +4 -0
|
@@ -14,3 +14,4 @@ export declare const ExpandLoadData: StoryObj<typeof Tree>;
|
|
|
14
14
|
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
|
+
export declare const RadioMode: StoryObj<typeof Tree>;
|
|
@@ -29,6 +29,7 @@ export interface TreeItemProps extends TreeData {
|
|
|
29
29
|
maxLevel?: number;
|
|
30
30
|
checkIsExpanded: (id: string) => boolean;
|
|
31
31
|
checkIsChecked: (id: string) => boolean;
|
|
32
|
+
checkAutoDisabled: (id: string) => boolean;
|
|
32
33
|
checkIsLoading?: (id: string) => void;
|
|
33
34
|
onExpandChange?: (id: string, expanded: boolean) => void;
|
|
34
35
|
onCheckedChange?: (id: string, checked: boolean) => void;
|
|
@@ -90,4 +91,6 @@ export interface TreeProps extends Pick<TreeItemProps, "renderIcon" | "renderRig
|
|
|
90
91
|
hierarchicalCheck?: boolean;
|
|
91
92
|
checkable?: boolean;
|
|
92
93
|
maxLevel?: number;
|
|
94
|
+
mode: "checkbox" | "radio";
|
|
95
|
+
autoDisabled?: boolean;
|
|
93
96
|
}
|
|
@@ -2,7 +2,7 @@ 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, }) => {
|
|
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, autoDisabled = false, }) => {
|
|
6
6
|
const [checkedState, setCheckedState] = useState({});
|
|
7
7
|
const [expandedState, setExpandedState] = useState({});
|
|
8
8
|
const traverseTree = (nodes, callback) => {
|
|
@@ -47,11 +47,23 @@ const Tree = ({ classes, data, defaultExpandedId, defaultCheckedId, checkedId, l
|
|
|
47
47
|
setCheckedState(initialCheckedState);
|
|
48
48
|
}
|
|
49
49
|
}, [data, defaultCheckedId, defaultCheckAll]);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (checkedId !== undefined) {
|
|
52
|
+
setCheckedState(checkedId.reduce((prev, cur) => (Object.assign(Object.assign({}, prev), { [cur]: true })), {}));
|
|
53
|
+
}
|
|
54
|
+
}, [checkedId]);
|
|
50
55
|
const handleExpandChange = useCallback((id, expanded) => {
|
|
51
56
|
onExpandChange === null || onExpandChange === void 0 ? void 0 : onExpandChange(id, expanded);
|
|
52
57
|
setExpandedState((prev) => (Object.assign(Object.assign({}, prev), { [id]: expanded })));
|
|
53
58
|
}, [onExpandChange]);
|
|
54
59
|
const handleCheckedChange = useCallback((id, checked) => {
|
|
60
|
+
if (mode === "radio") {
|
|
61
|
+
let newState = { [id]: checked };
|
|
62
|
+
onCheckedItem === null || onCheckedItem === void 0 ? void 0 : onCheckedItem(id, checked);
|
|
63
|
+
setCheckedState(newState);
|
|
64
|
+
onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(newState);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
55
67
|
onCheckedItem === null || onCheckedItem === void 0 ? void 0 : onCheckedItem(id, checked);
|
|
56
68
|
let newState = Object.assign(Object.assign({}, checkedState), { [id]: checked });
|
|
57
69
|
if (hierarchicalCheck) {
|
|
@@ -89,7 +101,15 @@ const Tree = ({ classes, data, defaultExpandedId, defaultCheckedId, checkedId, l
|
|
|
89
101
|
if (onCheckedChange) {
|
|
90
102
|
onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(newState);
|
|
91
103
|
}
|
|
92
|
-
}, [
|
|
104
|
+
}, [
|
|
105
|
+
checkedState,
|
|
106
|
+
data,
|
|
107
|
+
onCheckedChange,
|
|
108
|
+
hierarchicalCheck,
|
|
109
|
+
onCheckedItem,
|
|
110
|
+
mode,
|
|
111
|
+
autoDisabled,
|
|
112
|
+
]);
|
|
93
113
|
const checkIsExpanded = useCallback((id) => !!expandedState[id], [expandedState]);
|
|
94
114
|
const checkIsChecked = useCallback((id) => {
|
|
95
115
|
if (checkedId) {
|
|
@@ -102,6 +122,13 @@ const Tree = ({ classes, data, defaultExpandedId, defaultCheckedId, checkedId, l
|
|
|
102
122
|
return loadingId.includes(id);
|
|
103
123
|
}
|
|
104
124
|
}, [loadingId]);
|
|
105
|
-
|
|
125
|
+
const checkAutoDisabled = useCallback((id) => {
|
|
126
|
+
var _a;
|
|
127
|
+
if (autoDisabled && Object.values(checkedState).filter(Boolean).length) {
|
|
128
|
+
return (_a = (!(checkedState === null || checkedState === void 0 ? void 0 : checkedState[id]) || disabled)) !== null && _a !== void 0 ? _a : false;
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
}, [checkedState, disabled, autoDisabled]);
|
|
132
|
+
return (_jsx("div", { className: cn("w-full", classes === null || classes === void 0 ? void 0 : classes.container), children: data.map((item, idx) => (_jsx(TreeItem, Object.assign({ classes: classes, isFirstLevel: true, isLastItem: idx === data.length - 1, checkIsExpanded: checkIsExpanded, checkIsChecked: checkIsChecked, onExpandChange: handleExpandChange, onCheckedChange: handleCheckedChange, checkAutoDisabled: checkAutoDisabled, checkIsLoading: checkIsLoading, renderIcon: renderIcon, renderElement: renderElement, renderTitle: renderTitle, renderRightSection: renderRightSection, enableSeparatorLine: enableSeparatorLine, disabled: checkAutoDisabled(item.id), showIcon: showIcon, lineSize: lineSize, horizontalLineWidth: horizontalLineWidth, expandButtonSize: expandButtonSize, spacing: spacing, notifyClickItem: onClickItem, maxLevel: maxLevel, currentLevel: 1, checkable: checkable }, item), item.id))) }));
|
|
106
133
|
};
|
|
107
134
|
export default Tree;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useState } from "react";
|
|
3
3
|
import Tree from "./Tree";
|
|
4
|
-
import { ActionButton, Icon } from "@/index";
|
|
4
|
+
import { ActionButton, Button, Icon } from "@/index";
|
|
5
5
|
import { exampleData, exampleData2, exampleLeafData, sections, } from "./example-data";
|
|
6
6
|
const commonProps = {
|
|
7
7
|
defaultExpandedId: ["1", "1.1"],
|
|
@@ -197,3 +197,16 @@ export const HideCheckboxMode = {
|
|
|
197
197
|
return (_jsx("div", { className: "flex flex-row gap-4 w-full", children: _jsx(Tree, Object.assign({}, args)) }));
|
|
198
198
|
},
|
|
199
199
|
};
|
|
200
|
+
export const RadioMode = {
|
|
201
|
+
args: {
|
|
202
|
+
data: exampleData,
|
|
203
|
+
mode: "radio",
|
|
204
|
+
autoDisabled: true,
|
|
205
|
+
},
|
|
206
|
+
render: (args) => {
|
|
207
|
+
const [checkedId, onCheckedId] = useState(["1"]);
|
|
208
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full", children: [_jsx("div", { children: _jsx(Button, { variant: "outline", onClick: () => onCheckedId([]), children: "Clear" }) }), _jsx(Tree, Object.assign({}, args, { checkedId: checkedId, onCheckedChange: (state) => {
|
|
209
|
+
onCheckedId(Object.keys(state).filter((key) => state === null || state === void 0 ? void 0 : state[key]));
|
|
210
|
+
} }))] }));
|
|
211
|
+
},
|
|
212
|
+
};
|
|
@@ -3,7 +3,7 @@ import { ActionButton, Checkbox, Loading } from "@/index";
|
|
|
3
3
|
import { cn } from "@/utils/cn";
|
|
4
4
|
import { useCallback, useEffect, useMemo } from "react";
|
|
5
5
|
import Icon from "../Icon/Icon";
|
|
6
|
-
const TreeItem = ({ id, title, classes, children, isFirstLevel = false, isLeaf = false, disabled, icon, showIcon, showExpandButton, enableSeparatorLine = true, isLastItem, checkable, checkIsExpanded, checkIsChecked, checkIsLoading, onExpandChange, onCheckedChange, onClickItem, renderIcon, renderElement, renderTitle, renderRightSection, lineSize = 2, horizontalLineWidth = 4, expandButtonSize = 30, spacing = 2, currentLevel = 1, maxLevel = 10, notifyClickItem, }) => {
|
|
6
|
+
const TreeItem = ({ id, title, classes, children, isFirstLevel = false, isLeaf = false, disabled, icon, showIcon, showExpandButton, enableSeparatorLine = true, isLastItem, checkable, checkIsExpanded, checkIsChecked, checkAutoDisabled, checkIsLoading, onExpandChange, onCheckedChange, onClickItem, renderIcon, renderElement, renderTitle, renderRightSection, lineSize = 2, horizontalLineWidth = 4, expandButtonSize = 30, spacing = 2, currentLevel = 1, maxLevel = 10, notifyClickItem, }) => {
|
|
7
7
|
const isLoading = useMemo(() => checkIsLoading === null || checkIsLoading === void 0 ? void 0 : checkIsLoading(id), [checkIsLoading, id]);
|
|
8
8
|
const isChecked = useMemo(() => checkIsChecked(id), [checkIsChecked, id]);
|
|
9
9
|
const isExpanded = useMemo(() => checkIsExpanded(id), [checkIsExpanded, id]);
|
|
@@ -57,7 +57,7 @@ const TreeItem = ({ id, title, classes, children, isFirstLevel = false, isLeaf =
|
|
|
57
57
|
onClickItem === null || onClickItem === void 0 ? void 0 : onClickItem(id);
|
|
58
58
|
notifyClickItem === null || notifyClickItem === void 0 ? void 0 : notifyClickItem(id);
|
|
59
59
|
}, [onClickItem, notifyClickItem, id]);
|
|
60
|
-
const defaultIcon = (_jsx(Icon, { name: isExpanded ? "folder-open" : "folder", className: "fill-warning" }));
|
|
60
|
+
const defaultIcon = (_jsx(Icon, { name: isExpanded ? "folder-open" : "folder", className: "fill-warning size-[18px]" }));
|
|
61
61
|
const customIcon = icon !== null && icon !== void 0 ? icon : renderIcon === null || renderIcon === void 0 ? void 0 : renderIcon({
|
|
62
62
|
id,
|
|
63
63
|
expanded: isExpanded,
|
|
@@ -83,8 +83,8 @@ const TreeItem = ({ id, title, classes, children, isFirstLevel = false, isLeaf =
|
|
|
83
83
|
: content;
|
|
84
84
|
return elementWrapper(_jsx("div", { className: cn("flex flex-row w-full", classes === null || classes === void 0 ? void 0 : classes.elementWrapper), children: _jsxs("div", { className: cn("flex flex-col w-full", classes === null || classes === void 0 ? void 0 : classes.itemWrapper), children: [_jsxs("div", { className: cn("flex flex-row flex-1", classes === null || classes === void 0 ? void 0 : classes.rowWrapperClasses), children: [_jsxs("div", { className: cn("flex flex-col h-full", classes === null || classes === void 0 ? void 0 : classes.columnWrapperClasses), children: [!isFirstLevel && (_jsx("div", { className: cn("flex w-[2px] h-1/2 bg-grey-150", classes === null || classes === void 0 ? void 0 : classes.branch), style: styles.branch })), !isFirstLevel &&
|
|
85
85
|
!isLastItem &&
|
|
86
|
-
((isExpanded && (hasChildren || isLoading)) || !isExpanded) && (_jsx("div", { className: cn("flex w-[2px] h-1/2 bg-grey-150", classes === null || classes === void 0 ? void 0 : classes.branch), style: styles.branch }))] }), _jsxs("div", { className: cn("flex flex-1 items-center py-2 min-h-10", classes === null || classes === void 0 ? void 0 : classes.itemContainer), children: [!isFirstLevel && (_jsx("div", { className: cn("bg-grey-150", classes === null || classes === void 0 ? void 0 : classes.horizontalLine), style: styles.horizontalLine })), isFirstLevel && !shouldExpandButton && (_jsx("div", { className: cn("flex mr-[2px]", classes === null || classes === void 0 ? void 0 : classes.expandButton), style: styles.expandButton })), shouldExpandButton && (_jsx("div", { className: cn("flex mr-[2px]", classes === null || classes === void 0 ? void 0 : classes.expandButton), style: styles.expandButton, onClick: !isLoading && handleExpandToggle, children: _jsx(ActionButton, { variant: "icon", size: "sm", children: isLoading ? (_jsx(Loading, {})) : (_jsx(Icon, { name: isExpanded ? "chevron-down" : "chevron-right" })) }) })), shouldShowCheckbox ? (_jsx(Checkbox, { id: id, className: cn("size-[
|
|
87
|
-
? cn("size-[
|
|
88
|
-
: "" })), _jsxs("div", { className: cn("ml-2 gap-1 flex flex-1 items-center text-foreground", classes === null || classes === void 0 ? void 0 : classes.item), onClick: handleOnClickItem, children: [showIcon ? customIcon || defaultIcon : null, _jsx("div", { className: cn("flex flex-1 cursor-pointer text-subtitle5 text-ellipsis", classes === null || classes === void 0 ? void 0 : classes.title), children: titleContent })] }), rightIcon] })] }), isExpanded && hasChildren && currentLevel < (maxLevel || Infinity) && (_jsxs("div", { className: cn("flex flex-row overflow-hidden max-h-screen", classes === null || classes === void 0 ? void 0 : classes.expandedChildrenWrapper), children: [!isFirstLevel && !isLastItem && (_jsx("div", { className: cn("flex w-[2px] h-full bg-grey-150", classes === null || classes === void 0 ? void 0 : classes.branch), style: styles.branch })), _jsx("div", { className: cn("flex flex-col overflow-hidden max-h-screen", classes === null || classes === void 0 ? void 0 : classes.expandedChildrenWrapperInner), style: styles.childPadding, children: children === null || children === void 0 ? void 0 : children.map((child, idx) => (_jsx(TreeItem, Object.assign({ classes: classes, isLastItem: idx === children.length - 1, checkIsExpanded: checkIsExpanded, checkIsChecked: checkIsChecked, checkIsLoading: checkIsLoading, onExpandChange: onExpandChange, onCheckedChange: onCheckedChange, renderIcon: renderIcon, renderElement: renderElement, renderTitle: renderTitle, disabled:
|
|
86
|
+
((isExpanded && (hasChildren || isLoading)) || !isExpanded) && (_jsx("div", { className: cn("flex w-[2px] h-1/2 bg-grey-150", classes === null || classes === void 0 ? void 0 : classes.branch), style: styles.branch }))] }), _jsxs("div", { className: cn("flex flex-1 items-center py-2 min-h-10", classes === null || classes === void 0 ? void 0 : classes.itemContainer), children: [!isFirstLevel && (_jsx("div", { className: cn("bg-grey-150", classes === null || classes === void 0 ? void 0 : classes.horizontalLine), style: styles.horizontalLine })), isFirstLevel && !shouldExpandButton && (_jsx("div", { className: cn("flex mr-[2px]", classes === null || classes === void 0 ? void 0 : classes.expandButton), style: styles.expandButton })), shouldExpandButton && (_jsx("div", { className: cn("flex mr-[2px]", classes === null || classes === void 0 ? void 0 : classes.expandButton), style: styles.expandButton, onClick: !isLoading && handleExpandToggle, children: _jsx(ActionButton, { variant: "icon", size: "sm", children: isLoading ? (_jsx(Loading, {})) : (_jsx(Icon, { name: isExpanded ? "chevron-down" : "chevron-right" })) }) })), shouldShowCheckbox ? (_jsx(Checkbox, { id: id, className: cn("size-[16px]", classes === null || classes === void 0 ? void 0 : classes.checkbox), checked: isChecked, disabled: disabled, onCheckedChange: (newChecked) => onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(id, newChecked) })) : (_jsx("div", { className: isFirstLevel && checkable
|
|
87
|
+
? cn("size-[16px]", classes === null || classes === void 0 ? void 0 : classes.checkbox)
|
|
88
|
+
: "" })), _jsxs("div", { className: cn("ml-2 gap-1 flex flex-1 items-center text-foreground", classes === null || classes === void 0 ? void 0 : classes.item), onClick: handleOnClickItem, children: [showIcon ? customIcon || defaultIcon : null, _jsx("div", { className: cn("flex flex-1 cursor-pointer text-subtitle5 text-ellipsis", classes === null || classes === void 0 ? void 0 : classes.title), children: titleContent })] }), rightIcon] })] }), isExpanded && hasChildren && currentLevel < (maxLevel || Infinity) && (_jsxs("div", { className: cn("flex flex-row overflow-hidden max-h-screen", classes === null || classes === void 0 ? void 0 : classes.expandedChildrenWrapper), children: [!isFirstLevel && !isLastItem && (_jsx("div", { className: cn("flex w-[2px] h-full bg-grey-150", classes === null || classes === void 0 ? void 0 : classes.branch), style: styles.branch })), _jsx("div", { className: cn("flex flex-col overflow-hidden max-h-screen", classes === null || classes === void 0 ? void 0 : classes.expandedChildrenWrapperInner), style: styles.childPadding, children: children === null || children === void 0 ? void 0 : children.map((child, idx) => (_jsx(TreeItem, Object.assign({ classes: classes, isLastItem: idx === children.length - 1, checkIsExpanded: checkIsExpanded, checkIsChecked: checkIsChecked, checkAutoDisabled: checkAutoDisabled, checkIsLoading: checkIsLoading, onExpandChange: onExpandChange, onCheckedChange: onCheckedChange, renderIcon: renderIcon, renderElement: renderElement, renderTitle: renderTitle, disabled: checkAutoDisabled(child.id), showIcon: showIcon, lineSize: lineSize, horizontalLineWidth: horizontalLineWidth, expandButtonSize: expandButtonSize, spacing: spacing, notifyClickItem: notifyClickItem, maxLevel: maxLevel, currentLevel: currentLevel + 1, checkable: checkable }, child), child.id))) })] })), enableSeparatorLine && isFirstLevel && !isLastItem && (_jsx("div", { className: cn("bg-grey-150 w-full h-[2px] rounded", classes === null || classes === void 0 ? void 0 : classes.separatorLine) }))] }) }));
|
|
89
89
|
};
|
|
90
90
|
export default TreeItem;
|
package/dist/esm/bundle.css
CHANGED
|
@@ -783,9 +783,13 @@ input[type=number] {
|
|
|
783
783
|
width: 14px;
|
|
784
784
|
height: 14px;
|
|
785
785
|
}
|
|
786
|
-
.size-\[
|
|
787
|
-
width:
|
|
788
|
-
height:
|
|
786
|
+
.size-\[16px\]{
|
|
787
|
+
width: 16px;
|
|
788
|
+
height: 16px;
|
|
789
|
+
}
|
|
790
|
+
.size-\[18px\]{
|
|
791
|
+
width: 18px;
|
|
792
|
+
height: 18px;
|
|
789
793
|
}
|
|
790
794
|
.size-\[30px\]{
|
|
791
795
|
width: 30px;
|