@rovula/ui 0.0.54 → 0.0.56
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/Tabs/Tabs.d.ts +1 -0
- package/dist/cjs/types/components/Tabs/Tabs.stories.d.ts +14 -0
- 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/Tabs/Tabs.js +6 -1
- package/dist/components/Tabs/Tabs.stories.js +24 -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 +2 -2
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Tabs/Tabs.d.ts +1 -0
- package/dist/esm/types/components/Tabs/Tabs.stories.d.ts +14 -0
- 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 +4 -0
- package/dist/src/theme/global.css +8 -3
- package/package.json +1 -1
- package/src/components/Tabs/Tabs.stories.tsx +48 -0
- package/src/components/Tabs/Tabs.tsx +8 -0
- 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
|
@@ -10,6 +10,7 @@ declare const meta: {
|
|
|
10
10
|
disabled?: boolean | undefined;
|
|
11
11
|
isLoading?: boolean | undefined;
|
|
12
12
|
}[];
|
|
13
|
+
value?: number | undefined;
|
|
13
14
|
initialTab?: number | undefined;
|
|
14
15
|
tabBarSize?: number | undefined;
|
|
15
16
|
tabMode?: "start" | "justify" | undefined;
|
|
@@ -44,6 +45,7 @@ declare const meta: {
|
|
|
44
45
|
disabled?: boolean | undefined;
|
|
45
46
|
isLoading?: boolean | undefined;
|
|
46
47
|
}[];
|
|
48
|
+
value?: number | undefined;
|
|
47
49
|
initialTab?: number | undefined;
|
|
48
50
|
tabBarSize?: number | undefined;
|
|
49
51
|
tabMode?: "start" | "justify" | undefined;
|
|
@@ -144,3 +146,15 @@ export declare const Disabled: {
|
|
|
144
146
|
};
|
|
145
147
|
render: (args: {}) => import("react/jsx-runtime").JSX.Element;
|
|
146
148
|
};
|
|
149
|
+
export declare const Controller: {
|
|
150
|
+
args: {
|
|
151
|
+
initialTab: number;
|
|
152
|
+
value: number;
|
|
153
|
+
tabs: {
|
|
154
|
+
label: string;
|
|
155
|
+
content: import("react/jsx-runtime").JSX.Element;
|
|
156
|
+
}[];
|
|
157
|
+
enableAddTabButton: boolean;
|
|
158
|
+
};
|
|
159
|
+
render: (args: {}) => import("react/jsx-runtime").JSX.Element;
|
|
160
|
+
};
|
|
@@ -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
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -115,6 +115,7 @@ type Tab = {
|
|
|
115
115
|
};
|
|
116
116
|
type TabsProps = {
|
|
117
117
|
tabs: Tab[];
|
|
118
|
+
value?: number;
|
|
118
119
|
initialTab?: number;
|
|
119
120
|
tabBarSize?: number;
|
|
120
121
|
tabMode?: "start" | "justify";
|
|
@@ -643,6 +644,7 @@ interface TreeItemProps extends TreeData {
|
|
|
643
644
|
maxLevel?: number;
|
|
644
645
|
checkIsExpanded: (id: string) => boolean;
|
|
645
646
|
checkIsChecked: (id: string) => boolean;
|
|
647
|
+
checkAutoDisabled: (id: string) => boolean;
|
|
646
648
|
checkIsLoading?: (id: string) => void;
|
|
647
649
|
onExpandChange?: (id: string, expanded: boolean) => void;
|
|
648
650
|
onCheckedChange?: (id: string, checked: boolean) => void;
|
|
@@ -704,6 +706,8 @@ interface TreeProps extends Pick<TreeItemProps, "renderIcon" | "renderRightSecti
|
|
|
704
706
|
hierarchicalCheck?: boolean;
|
|
705
707
|
checkable?: boolean;
|
|
706
708
|
maxLevel?: number;
|
|
709
|
+
mode: "checkbox" | "radio";
|
|
710
|
+
autoDisabled?: boolean;
|
|
707
711
|
}
|
|
708
712
|
|
|
709
713
|
declare const Tree: FC<TreeProps>;
|
|
@@ -2501,9 +2501,14 @@ input[type=number] {
|
|
|
2501
2501
|
height: 14px;
|
|
2502
2502
|
}
|
|
2503
2503
|
|
|
2504
|
-
.size-\[
|
|
2505
|
-
width:
|
|
2506
|
-
height:
|
|
2504
|
+
.size-\[16px\] {
|
|
2505
|
+
width: 16px;
|
|
2506
|
+
height: 16px;
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
.size-\[18px\] {
|
|
2510
|
+
width: 18px;
|
|
2511
|
+
height: 18px;
|
|
2507
2512
|
}
|
|
2508
2513
|
|
|
2509
2514
|
.size-\[30px\] {
|
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@ import { ChevronDownIcon, ArchiveBoxIcon } from "@heroicons/react/16/solid";
|
|
|
5
5
|
import ActionButton from "../ActionButton/ActionButton";
|
|
6
6
|
import Icon from "../Icon/Icon";
|
|
7
7
|
import { useArgs } from "@storybook/preview-api";
|
|
8
|
+
import { Button } from "@/index";
|
|
8
9
|
|
|
9
10
|
const meta = {
|
|
10
11
|
title: "Components/Tabs",
|
|
@@ -209,3 +210,50 @@ export const Disabled = {
|
|
|
209
210
|
);
|
|
210
211
|
},
|
|
211
212
|
} satisfies StoryObj;
|
|
213
|
+
|
|
214
|
+
export const Controller = {
|
|
215
|
+
args: {
|
|
216
|
+
initialTab: 1,
|
|
217
|
+
value: 0,
|
|
218
|
+
tabs,
|
|
219
|
+
enableAddTabButton: true,
|
|
220
|
+
},
|
|
221
|
+
render: (args) => {
|
|
222
|
+
const props: any = {
|
|
223
|
+
...args,
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const [, setArgs] = useArgs();
|
|
227
|
+
return (
|
|
228
|
+
<div className="flex flex-col gap-4 w-[500px]">
|
|
229
|
+
<div className="flex flex-row gap-2">
|
|
230
|
+
<Button onClick={() => setArgs({ ...props.tabs, value: 0 })}>
|
|
231
|
+
Set active tab 0
|
|
232
|
+
</Button>
|
|
233
|
+
<Button onClick={() => setArgs({ ...props.tabs, value: 1 })}>
|
|
234
|
+
Set active tab 1
|
|
235
|
+
</Button>
|
|
236
|
+
<Button onClick={() => setArgs({ ...props.tabs, value: 2 })}>
|
|
237
|
+
Set active tab 2
|
|
238
|
+
</Button>
|
|
239
|
+
</div>
|
|
240
|
+
<Tabs
|
|
241
|
+
tabs={tabs}
|
|
242
|
+
{...props}
|
|
243
|
+
tabMode="start"
|
|
244
|
+
onAddTab={() => {
|
|
245
|
+
setArgs({
|
|
246
|
+
tabs: [
|
|
247
|
+
...props.tabs,
|
|
248
|
+
{
|
|
249
|
+
label: "Tab" + (props.tabs.length + 1),
|
|
250
|
+
content: <p>Tab {props.tabs.length + 1} content</p>,
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
});
|
|
254
|
+
}}
|
|
255
|
+
/>
|
|
256
|
+
</div>
|
|
257
|
+
);
|
|
258
|
+
},
|
|
259
|
+
} satisfies StoryObj;
|
|
@@ -16,6 +16,7 @@ type Tab = {
|
|
|
16
16
|
|
|
17
17
|
type TabsProps = {
|
|
18
18
|
tabs: Tab[];
|
|
19
|
+
value?: number;
|
|
19
20
|
initialTab?: number;
|
|
20
21
|
tabBarSize?: number;
|
|
21
22
|
tabMode?: "start" | "justify";
|
|
@@ -40,6 +41,7 @@ type TabsProps = {
|
|
|
40
41
|
|
|
41
42
|
const Tabs: React.FC<TabsProps> = ({
|
|
42
43
|
tabs = [],
|
|
44
|
+
value,
|
|
43
45
|
initialTab = 0,
|
|
44
46
|
tabBarSize = 38,
|
|
45
47
|
enableBorderLine = true,
|
|
@@ -69,6 +71,12 @@ const Tabs: React.FC<TabsProps> = ({
|
|
|
69
71
|
const tabRefs = useRef<(HTMLButtonElement | null)[]>([]);
|
|
70
72
|
const isInitialMount = useRef(true);
|
|
71
73
|
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (value !== undefined) {
|
|
76
|
+
setActiveTab(value);
|
|
77
|
+
}
|
|
78
|
+
}, [value]);
|
|
79
|
+
|
|
72
80
|
const updateSliderStyle = () => {
|
|
73
81
|
const activeTabElement = tabRefs.current[activeTab];
|
|
74
82
|
if (activeTabElement) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
3
|
import Tree from "./Tree";
|
|
4
|
-
import { ActionButton, Icon } from "@/index";
|
|
4
|
+
import { ActionButton, Button, Icon } from "@/index";
|
|
5
5
|
import {
|
|
6
6
|
exampleData,
|
|
7
7
|
exampleData2,
|
|
@@ -382,3 +382,31 @@ export const HideCheckboxMode: StoryObj<typeof Tree> = {
|
|
|
382
382
|
);
|
|
383
383
|
},
|
|
384
384
|
};
|
|
385
|
+
|
|
386
|
+
export const RadioMode: StoryObj<typeof Tree> = {
|
|
387
|
+
args: {
|
|
388
|
+
data: exampleData,
|
|
389
|
+
mode: "radio",
|
|
390
|
+
autoDisabled: true,
|
|
391
|
+
},
|
|
392
|
+
render: (args) => {
|
|
393
|
+
const [checkedId, onCheckedId] = useState<string[]>(["1"]);
|
|
394
|
+
|
|
395
|
+
return (
|
|
396
|
+
<div className="flex flex-col gap-4 w-full">
|
|
397
|
+
<div>
|
|
398
|
+
<Button variant="outline" onClick={() => onCheckedId([])}>
|
|
399
|
+
Clear
|
|
400
|
+
</Button>
|
|
401
|
+
</div>
|
|
402
|
+
<Tree
|
|
403
|
+
{...args}
|
|
404
|
+
checkedId={checkedId}
|
|
405
|
+
onCheckedChange={(state) => {
|
|
406
|
+
onCheckedId(Object.keys(state).filter((key) => state?.[key]));
|
|
407
|
+
}}
|
|
408
|
+
/>
|
|
409
|
+
</div>
|
|
410
|
+
);
|
|
411
|
+
},
|
|
412
|
+
};
|
|
@@ -30,6 +30,8 @@ const Tree: FC<TreeProps> = ({
|
|
|
30
30
|
enableSeparatorLine = true,
|
|
31
31
|
checkable = true,
|
|
32
32
|
maxLevel,
|
|
33
|
+
mode,
|
|
34
|
+
autoDisabled = false,
|
|
33
35
|
}) => {
|
|
34
36
|
const [checkedState, setCheckedState] = useState<Record<string, boolean>>({});
|
|
35
37
|
const [expandedState, setExpandedState] = useState<Record<string, boolean>>(
|
|
@@ -83,6 +85,14 @@ const Tree: FC<TreeProps> = ({
|
|
|
83
85
|
}
|
|
84
86
|
}, [data, defaultCheckedId, defaultCheckAll]);
|
|
85
87
|
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (checkedId !== undefined) {
|
|
90
|
+
setCheckedState(
|
|
91
|
+
checkedId.reduce((prev, cur) => ({ ...prev, [cur]: true }), {})
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}, [checkedId]);
|
|
95
|
+
|
|
86
96
|
const handleExpandChange = useCallback(
|
|
87
97
|
(id: string, expanded: boolean) => {
|
|
88
98
|
onExpandChange?.(id, expanded);
|
|
@@ -93,6 +103,15 @@ const Tree: FC<TreeProps> = ({
|
|
|
93
103
|
|
|
94
104
|
const handleCheckedChange = useCallback(
|
|
95
105
|
(id: string, checked: boolean) => {
|
|
106
|
+
if (mode === "radio") {
|
|
107
|
+
let newState = { [id]: checked };
|
|
108
|
+
|
|
109
|
+
onCheckedItem?.(id, checked);
|
|
110
|
+
setCheckedState(newState);
|
|
111
|
+
onCheckedChange?.(newState);
|
|
112
|
+
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
96
115
|
onCheckedItem?.(id, checked);
|
|
97
116
|
let newState = { ...checkedState, [id]: checked };
|
|
98
117
|
|
|
@@ -147,7 +166,15 @@ const Tree: FC<TreeProps> = ({
|
|
|
147
166
|
onCheckedChange?.(newState);
|
|
148
167
|
}
|
|
149
168
|
},
|
|
150
|
-
[
|
|
169
|
+
[
|
|
170
|
+
checkedState,
|
|
171
|
+
data,
|
|
172
|
+
onCheckedChange,
|
|
173
|
+
hierarchicalCheck,
|
|
174
|
+
onCheckedItem,
|
|
175
|
+
mode,
|
|
176
|
+
autoDisabled,
|
|
177
|
+
]
|
|
151
178
|
);
|
|
152
179
|
|
|
153
180
|
const checkIsExpanded = useCallback(
|
|
@@ -174,6 +201,17 @@ const Tree: FC<TreeProps> = ({
|
|
|
174
201
|
[loadingId]
|
|
175
202
|
);
|
|
176
203
|
|
|
204
|
+
const checkAutoDisabled = useCallback(
|
|
205
|
+
(id: string) => {
|
|
206
|
+
if (autoDisabled && Object.values(checkedState).filter(Boolean).length) {
|
|
207
|
+
return (!checkedState?.[id] || disabled) ?? false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return false;
|
|
211
|
+
},
|
|
212
|
+
[checkedState, disabled, autoDisabled]
|
|
213
|
+
);
|
|
214
|
+
|
|
177
215
|
return (
|
|
178
216
|
<div className={cn("w-full", classes?.container)}>
|
|
179
217
|
{data.map((item, idx) => (
|
|
@@ -186,13 +224,14 @@ const Tree: FC<TreeProps> = ({
|
|
|
186
224
|
checkIsChecked={checkIsChecked}
|
|
187
225
|
onExpandChange={handleExpandChange}
|
|
188
226
|
onCheckedChange={handleCheckedChange}
|
|
227
|
+
checkAutoDisabled={checkAutoDisabled}
|
|
189
228
|
checkIsLoading={checkIsLoading}
|
|
190
229
|
renderIcon={renderIcon}
|
|
191
230
|
renderElement={renderElement}
|
|
192
231
|
renderTitle={renderTitle}
|
|
193
232
|
renderRightSection={renderRightSection}
|
|
194
233
|
enableSeparatorLine={enableSeparatorLine}
|
|
195
|
-
disabled={
|
|
234
|
+
disabled={checkAutoDisabled(item.id)}
|
|
196
235
|
showIcon={showIcon}
|
|
197
236
|
lineSize={lineSize}
|
|
198
237
|
horizontalLineWidth={horizontalLineWidth}
|
|
@@ -20,6 +20,7 @@ const TreeItem: FC<TreeItemProps> = ({
|
|
|
20
20
|
checkable,
|
|
21
21
|
checkIsExpanded,
|
|
22
22
|
checkIsChecked,
|
|
23
|
+
checkAutoDisabled,
|
|
23
24
|
checkIsLoading,
|
|
24
25
|
onExpandChange,
|
|
25
26
|
onCheckedChange,
|
|
@@ -109,7 +110,7 @@ const TreeItem: FC<TreeItemProps> = ({
|
|
|
109
110
|
const defaultIcon = (
|
|
110
111
|
<Icon
|
|
111
112
|
name={isExpanded ? "folder-open" : "folder"}
|
|
112
|
-
className="fill-warning"
|
|
113
|
+
className="fill-warning size-[18px]"
|
|
113
114
|
/>
|
|
114
115
|
);
|
|
115
116
|
|
|
@@ -213,7 +214,7 @@ const TreeItem: FC<TreeItemProps> = ({
|
|
|
213
214
|
{shouldShowCheckbox ? (
|
|
214
215
|
<Checkbox
|
|
215
216
|
id={id}
|
|
216
|
-
className={cn("size-[
|
|
217
|
+
className={cn("size-[16px]", classes?.checkbox)}
|
|
217
218
|
checked={isChecked}
|
|
218
219
|
disabled={disabled}
|
|
219
220
|
onCheckedChange={(newChecked) =>
|
|
@@ -224,7 +225,7 @@ const TreeItem: FC<TreeItemProps> = ({
|
|
|
224
225
|
<div
|
|
225
226
|
className={
|
|
226
227
|
isFirstLevel && checkable
|
|
227
|
-
? cn("size-[
|
|
228
|
+
? cn("size-[16px]", classes?.checkbox)
|
|
228
229
|
: ""
|
|
229
230
|
}
|
|
230
231
|
/>
|
|
@@ -280,13 +281,14 @@ const TreeItem: FC<TreeItemProps> = ({
|
|
|
280
281
|
isLastItem={idx === children.length - 1}
|
|
281
282
|
checkIsExpanded={checkIsExpanded}
|
|
282
283
|
checkIsChecked={checkIsChecked}
|
|
284
|
+
checkAutoDisabled={checkAutoDisabled}
|
|
283
285
|
checkIsLoading={checkIsLoading}
|
|
284
286
|
onExpandChange={onExpandChange}
|
|
285
287
|
onCheckedChange={onCheckedChange}
|
|
286
288
|
renderIcon={renderIcon}
|
|
287
289
|
renderElement={renderElement}
|
|
288
290
|
renderTitle={renderTitle}
|
|
289
|
-
disabled={
|
|
291
|
+
disabled={checkAutoDisabled(child.id)}
|
|
290
292
|
showIcon={showIcon}
|
|
291
293
|
lineSize={lineSize}
|
|
292
294
|
horizontalLineWidth={horizontalLineWidth}
|
|
@@ -31,6 +31,7 @@ export interface TreeItemProps extends TreeData {
|
|
|
31
31
|
maxLevel?: number;
|
|
32
32
|
checkIsExpanded: (id: string) => boolean;
|
|
33
33
|
checkIsChecked: (id: string) => boolean;
|
|
34
|
+
checkAutoDisabled: (id: string) => boolean;
|
|
34
35
|
checkIsLoading?: (id: string) => void;
|
|
35
36
|
onExpandChange?: (id: string, expanded: boolean) => void;
|
|
36
37
|
onCheckedChange?: (id: string, checked: boolean) => void;
|
|
@@ -108,4 +109,7 @@ export interface TreeProps
|
|
|
108
109
|
hierarchicalCheck?: boolean;
|
|
109
110
|
checkable?: boolean;
|
|
110
111
|
maxLevel?: number;
|
|
112
|
+
mode: "checkbox" | "radio";
|
|
113
|
+
// Only radio mode
|
|
114
|
+
autoDisabled?: boolean;
|
|
111
115
|
}
|