Skip to content

Commit 5fe6810

Browse files
author
Administrator
committed
Item reveal modes
1 parent 12cca62 commit 5fe6810

File tree

12 files changed

+208
-59
lines changed

12 files changed

+208
-59
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
node_modules/
33
# build/
44
storybook-static/
5-
5+
yarn.lock

.storybook/preview.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,22 @@
6767
* Will add a new dropdown in your toolbar with options light and dark.
6868
**/
6969

70+
/*
71+
export const globalTypes = {
72+
theme: {
73+
name: 'Theme',
74+
description: 'Global theme for components',
75+
defaultValue: 'light',
76+
toolbar: {
77+
icon: 'circlehollow',
78+
// array of plain string values or MenuItem shape
79+
items: ['light', 'dark'],
80+
},
81+
},
82+
};
83+
*/
84+
85+
7086
export const parameters = {
7187
darkMode: {
7288
// Set the initial theme

TreeMenu.gif

-5.31 MB
Binary file not shown.

img/full.gif

2.11 MB
Loading

img/items_reveal.gif

765 KB
Loading

img/rorate_group.gif

393 KB
Loading

img/static_group.gif

616 KB
Loading

src/TreeMenu/TreeMenu.less

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,80 @@
9898
display: flex;
9999
flex-direction: row;
100100
align-items: center;
101+
overflow: hidden;
102+
103+
> .text .title, .text .info {
104+
// display: flex;
105+
// align-items: center;
106+
overflow: hidden;
107+
108+
transition: all .4s ease-in-out;
109+
}
101110

102-
&:hover{
111+
&:hover:has(.info) {
103112
color:var(--item-hover-color);
113+
114+
> .text .title.vertical {
115+
top:0%;
116+
transform: translateY(-100%);
117+
opacity: .1;
118+
}
119+
120+
> .text .title.horizontal {
121+
top:0%;
122+
transform: translateY(-100%);
123+
}
124+
125+
> .text .info.vertical {
126+
top:50%;
127+
transform: translateY(0%);
128+
}
129+
130+
> .text .info.horizontal {
131+
position: absolute;
132+
transform: translateX(0%);
133+
}
134+
135+
}
136+
137+
> .text {
138+
139+
// border: 1px solid white;
140+
position: relative;
141+
flex-grow: 1;
142+
display: flex;
143+
flex-direction: column;
144+
align-content: center;
145+
146+
147+
> .title:has(~.info.vertical,~.info.horizontal) {
148+
position: absolute;
149+
top:50%;
150+
transform: translateY(-50%);
151+
display: flex;
152+
flex-grow: 1;
153+
align-content: center;
154+
}
155+
156+
157+
> .info {
158+
position: relative;
159+
font-size: .7em;
160+
color: var(--item-info);
161+
overflow: hidden;
162+
display: flex;
163+
flex-grow: 1;
164+
165+
}
166+
167+
> .info.vertical {
168+
transform:translateY(300%);
169+
}
170+
171+
> .info.horizontal {
172+
transform:translateX(-300%);
173+
}
174+
104175
}
105176

106177
/*
@@ -110,19 +181,13 @@
110181
*/
111182

112183
> .icon {
113-
display: flex;
114-
padding-right: 5px;
115-
}
116-
> .title {
184+
display: flex;
185+
padding-right: 5px;
186+
}
187+
188+
189+
117190

118-
display: flex;
119-
flex-grow: 1;
120-
flex-direction: column;
121-
> .info {
122-
font-size: .7em;
123-
color: var(--item-info);
124-
}
125-
}
126191
/*
127192
> .marker {
128193

src/TreeMenu/TreeMenu.stories.tsx

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,39 @@ const ITEMS : TreeMenuItem[] = [
4040
{
4141
id:"heading",
4242
title:"Heading",
43-
info:"TreeMenu sample",
43+
info:"Horizontal reveal infos",
4444
unselectable:false,
45-
icon:<FaStar color="white" />
45+
infoReveal:"horizontal",
46+
icon:<FaStar color="white" />,
47+
titleStyle:{
48+
color:"orange",
49+
fontWeight:"bolder"
50+
}
4651
// badge:<Badge color="red" />
4752
},
4853
{
4954
id:"main",
5055
title:"TreeMenu",
56+
info:"Vertical reveal infos",
57+
titleStyle:{
58+
color:"green",
59+
// lineHeight:1
60+
},
61+
infoStyle:{
62+
color:"red",
63+
fontSize:24,
64+
// lineHeight:.3,
65+
},
66+
infoReveal:"vertical",
5167
icon:<FaArchive />,
5268
childs:[
5369
{
5470
id:"home",
55-
title:"Demo",
56-
info:"Welcome to TreeMenu",
71+
title:"Regular Title with",
72+
info:"Custom infoStyle",
73+
infoStyle:{
74+
fontSize:12,
75+
},
5776
infoClass:"heading",
5877
style:{
5978
// fontSize:24
@@ -65,6 +84,7 @@ const ITEMS : TreeMenuItem[] = [
6584
icon:<FaInfo />,
6685
title:<Badge color="orange" />,
6786
info:"Item with custom title",
87+
infoReveal:"vertical",
6888
childs:[
6989
{ id:"n1",title:"Sub item 1" },
7090
{ id:"n2",title:"Sub item 2" }
@@ -78,8 +98,9 @@ const ITEMS : TreeMenuItem[] = [
7898
},
7999
{
80100
id:"sub",
81-
title:"Nested subs",
101+
title:"Static goup icons",
82102
info:"This is sub menu",
103+
infoReveal:"horizontal",
83104
disabled:false,
84105
unselectable:false,
85106
// collapsed:false,
@@ -149,6 +170,7 @@ export const FullSample = () => {
149170
};
150171

151172
const renderGroupState = (item:TreeMenuItem) => {
173+
console.log(">>>",item);
152174
return item.collapsed ? <FaFolder /> : <FaFolderOpen/>;
153175
};
154176
const renderIcon = (item:TreeMenuItem) => {
@@ -164,13 +186,13 @@ export const FullSample = () => {
164186
// initialCollapsed
165187
// theme="dark"
166188
enableRotate={true}
167-
// initialSelected="LAST"
189+
initialSelected="LAST"
168190
// ref={ref}
169191
items={ITEMS}
170192
renderGroupState={<FaChevronRight />}
171193
// renderIcon={renderIcon}
172-
//renderGroupState={renderGroupState}
173-
renderBadge={renderMarker}
194+
// renderGroupState={renderGroupState}
195+
// renderBadge={renderMarker}
174196
onClick={onClick}
175197
onToggle={onToggle}
176198
/>

src/TreeMenu/TreeMenu.tsx

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,87 @@
22
import React, { useEffect, useMemo, useState, useImperativeHandle } from "react";
33
import clsx from "clsx";
44
import { TreeMenuItem,TreeMenuProps,ItemProps,ItemRenderProps,TreeMenuItemType } from "./TreeMenu.types";
5-
import "./TreeMenu.less";
5+
import "./TreeMenu.less";
66

77
export { TreeMenuItem };
88

9+
// type ItemIconProps = Pick<ItemRenderProps,"icon" | "renderIcon">;
10+
11+
const ItemIcon : React.FC<ItemRenderProps> = (props) => {
12+
const { icon,renderIcon } = props;
13+
const iconView = useMemo(()=>{
14+
if ( !icon && !renderIcon )
15+
return null;
16+
return icon || (typeof renderIcon === "function" ? renderIcon(props) : renderIcon);
17+
},[icon,renderIcon]);
18+
return (
19+
<div className="icon">
20+
{iconView}
21+
</div>
22+
);
23+
};
24+
25+
const ItemBadge : React.FC<ItemRenderProps> = (props) => {
26+
const { renderBadge,badge } = props;
27+
const badgeView = useMemo(()=>{
28+
if ( !badge && !renderBadge )
29+
return null;
30+
return badge || (typeof renderBadge === "function" ? renderBadge(props) : renderBadge);
31+
},[badge,renderBadge]);
32+
return (
33+
<div className="marker">
34+
{badgeView}
35+
</div>
36+
);
37+
};
38+
39+
const GroupState : React.FC<ItemRenderProps> = (props) => {
40+
const { hasChilds,renderGroupState,enableRotate,collapsed } = props;
41+
const state = useMemo(()=>{
42+
if ( !hasChilds || !renderGroupState )
43+
return null;
44+
return typeof renderGroupState === "function" ? renderGroupState(props) : renderGroupState;
45+
},[hasChilds,renderGroupState,enableRotate,collapsed]);
46+
47+
return (
48+
<div className={clsx("folder",{ "enable-rotate":enableRotate })}>
49+
{state}
50+
</div>
51+
);
52+
};
53+
54+
const ItemText : React.FC<ItemRenderProps> = (props) => {
55+
const { title,info,titleClass,infoClass,infoReveal = "none",titleStyle,infoStyle } = props;
56+
return (
57+
<div className="text">
58+
<div className={clsx("title",titleClass,infoReveal)} style={titleStyle}>
59+
{title}
60+
</div>
61+
{info && <div className={clsx("info",infoClass,infoReveal)} style={infoStyle}>
62+
{info}
63+
</div>}
64+
</div>
65+
);
66+
};
67+
968
const Item : React.FC<ItemRenderProps> = (props) => {
1069
const {
11-
id,
12-
badge,
13-
titleClass,
14-
infoClass,
15-
enableRotate,
16-
icon,info,
17-
renderBadge,
18-
renderGroupState,
19-
renderIcon,
20-
hasChilds,disabled, onClick,level = 0,
21-
style,classes = [] } = props;
22-
const padding = icon && hasChilds ? 3 : 0;
70+
icon,
71+
hasChilds,
72+
disabled,
73+
onClick,level = 0,
74+
style,
75+
classes = []
76+
} = props;
77+
const padding = icon && hasChilds ? 0 : 0;
2378
return (
2479
<div style={{ paddingLeft:`${(level*12)+padding}px`,...style }}
2580
className={clsx("item",{ hasChilds,disabled },Array.from(classes))} onClick={() => onClick && onClick(props)}>
26-
<div className="content">
27-
{icon && <div className="icon">{icon}</div>}
28-
{renderIcon &&
29-
<div className="icon">
30-
{typeof renderIcon === "function" ? renderIcon(props) : renderIcon}
31-
</div>}
32-
<div className={clsx("title",titleClass)}>
33-
{props.title}
34-
{info && <div className={clsx("info",infoClass)}>
35-
{info}
36-
</div>}
37-
</div>
38-
{(renderBadge || badge) && <div className="marker">
39-
{badge || renderBadge(props)}
40-
</div>}
41-
{hasChilds && renderGroupState &&
42-
<div className={clsx("folder",{ "enable-rotate":enableRotate })}>
43-
{typeof renderGroupState === "function" ? renderGroupState(props) : renderGroupState}
44-
</div>}
81+
<div className="content">
82+
<ItemIcon {...props} />
83+
<ItemText {...props} />
84+
<ItemBadge {...props} />
85+
<GroupState {...props} />
4586
</div>
4687
</div>
4788
);

0 commit comments

Comments
 (0)