Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7c4fbe5

Browse files
refactor(site): make HelpTooltip easier to reuse and compose (#11242)
1 parentf2606a7 commit7c4fbe5

File tree

19 files changed

+330
-448
lines changed

19 files changed

+330
-448
lines changed

‎site/src/components/ActiveUserChart/ActiveUserChart.tsx‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
HelpTooltip,
1818
HelpTooltipTitle,
1919
HelpTooltipText,
20+
HelpTooltipContent,
21+
HelpTooltipTrigger,
2022
}from"components/HelpTooltip/HelpTooltip";
2123
importdayjsfrom"dayjs";
2224
import{useTheme}from"@emotion/react";
@@ -139,12 +141,15 @@ export const ActiveUsersTitle: FC = () => {
139141
return(
140142
<divcss={{display:"flex",alignItems:"center",gap:8}}>
141143
Active Users
142-
<HelpTooltipsize="small">
143-
<HelpTooltipTitle>How do we calculate active users?</HelpTooltipTitle>
144-
<HelpTooltipText>
145-
When a connection is initiated to a user&apos;s workspace they are
146-
considered an active user. e.g. apps, web terminal, SSH
147-
</HelpTooltipText>
144+
<HelpTooltip>
145+
<HelpTooltipTriggersize="small"/>
146+
<HelpTooltipContent>
147+
<HelpTooltipTitle>How do we calculate active users?</HelpTooltipTitle>
148+
<HelpTooltipText>
149+
When a connection is initiated to a user&apos;s workspace they are
150+
considered an active user. e.g. apps, web terminal, SSH
151+
</HelpTooltipText>
152+
</HelpTooltipContent>
148153
</HelpTooltip>
149154
</div>
150155
);

‎site/src/components/HelpTooltip/HelpTooltip.tsx‎

Lines changed: 63 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,170 +1,107 @@
11
importLinkfrom"@mui/material/Link";
2-
// This is used as base for the main HelpTooltip component
3-
// eslint-disable-next-line no-restricted-imports -- Read above
4-
importPopover,{typePopoverProps}from"@mui/material/Popover";
52
importHelpIconfrom"@mui/icons-material/HelpOutline";
63
importOpenInNewIconfrom"@mui/icons-material/OpenInNew";
74
import{
8-
createContext,
9-
useContext,
10-
useRef,
11-
useState,
125
typeFC,
136
typePropsWithChildren,
147
typeHTMLAttributes,
158
typeReactNode,
9+
forwardRef,
10+
ComponentProps,
1611
}from"react";
1712
import{Stack}from"components/Stack/Stack";
18-
importtype{CSSObject}from"@emotion/css";
13+
import{typeCSSObject}from"@emotion/css";
1914
import{css,typeInterpolation,typeTheme,useTheme}from"@emotion/react";
20-
import{typeClassName,useClassName}from"hooks/useClassName";
15+
import{
16+
Popover,
17+
PopoverContent,
18+
PopoverTrigger,
19+
usePopover,
20+
}from"components/Popover/Popover";
2121

2222
typeIcon=typeofHelpIcon;
2323

2424
typeSize="small"|"medium";
2525

26-
exportconstHelpTooltipContext=createContext<
27-
{open:boolean;onClose:()=>void}|undefined
28-
>(undefined);
29-
30-
constuseHelpTooltip=()=>{
31-
consthelpTooltipContext=useContext(HelpTooltipContext);
26+
exportconstHelpTooltipIcon=HelpIcon;
3227

33-
if(!helpTooltipContext){
34-
thrownewError(
35-
"This hook should be used in side of the HelpTooltipContext.",
36-
);
37-
}
38-
39-
returnhelpTooltipContext;
28+
exportconstHelpTooltip:FC<ComponentProps<typeofPopover>>=(props)=>{
29+
return<Popovermode="hover"{...props}/>;
4030
};
4131

42-
interfaceHelpPopoverPropsextendsPopoverProps{
43-
onOpen:()=>void;
44-
onClose:()=>void;
45-
}
46-
47-
exportconstHelpPopover:FC<HelpPopoverProps>=({
48-
onOpen,
49-
onClose,
50-
children,
51-
...props
52-
})=>{
53-
constpopover=useClassName(classNames.popover,[]);
54-
constpaper=useClassName(classNames.paper,[]);
32+
exportconstHelpTooltipContent=(
33+
props:ComponentProps<typeofPopoverContent>,
34+
)=>{
35+
consttheme=useTheme();
5536

5637
return(
57-
<Popover
58-
className={popover}
59-
classes={{ paper}}
60-
onClose={onClose}
61-
anchorOrigin={{
62-
vertical:"bottom",
63-
horizontal:"left",
64-
}}
65-
transformOrigin={{
66-
vertical:"top",
67-
horizontal:"left",
68-
}}
69-
PaperProps={{
70-
onMouseEnter:onOpen,
71-
onMouseLeave:onClose,
72-
}}
38+
<PopoverContent
7339
{...props}
74-
>
75-
{children}
76-
</Popover>
40+
css={{
41+
"& .MuiPaper-root":{
42+
fontSize:14,
43+
width:304,
44+
padding:20,
45+
color:theme.palette.text.secondary,
46+
},
47+
}}
48+
/>
7749
);
7850
};
7951

80-
exportinterfaceHelpTooltipProps{
81-
// Useful to test on storybook
82-
open?:boolean;
52+
typeHelpTooltipTriggerProps=HTMLAttributes<HTMLButtonElement>&{
8353
size?:Size;
84-
icon?:Icon;
85-
buttonStyles?:Interpolation<Theme>;
86-
iconStyles?:Interpolation<Theme>;
87-
children?:ReactNode;
88-
}
89-
90-
exportconstHelpTooltip:FC<HelpTooltipProps>=({
91-
children,
92-
open=false,
93-
size="medium",
94-
icon:Icon=HelpIcon,
95-
buttonStyles,
96-
iconStyles,
97-
})=>{
98-
consttheme=useTheme();
99-
constanchorRef=useRef<HTMLButtonElement>(null);
100-
const[isOpen,setIsOpen]=useState(open);
101-
constid=isOpen ?"help-popover" :undefined;
54+
hoverEffect?:boolean;
55+
};
10256

103-
constonClose=()=>{
104-
setIsOpen(false);
105-
};
57+
exportconstHelpTooltipTrigger=forwardRef<
58+
HTMLButtonElement,
59+
HelpTooltipTriggerProps
60+
>((props,ref)=>{
61+
const{
62+
size="medium",
63+
children=<HelpTooltipIcon/>,
64+
hoverEffect=true,
65+
...buttonProps
66+
}=props;
67+
68+
consthoverEffectStyles=css({
69+
opacity:0.5,
70+
"&:hover":{
71+
opacity:0.75,
72+
},
73+
});
10674

10775
return(
108-
<>
76+
<PopoverTrigger>
10977
<button
110-
ref={anchorRef}
111-
aria-describedby={id}
78+
{...buttonProps}
79+
aria-label="More info"
80+
ref={ref}
11281
css={[
11382
css`
11483
display: flex;
11584
align-items: center;
11685
justify-content: center;
117-
width:${theme.spacing(getButtonSpacingFromSize(size))};
118-
height:${theme.spacing(getButtonSpacingFromSize(size))};
119-
padding:0;
86+
padding:4px0;
12087
border:0;
12188
background: transparent;
122-
color:${theme.palette.text.primary};
123-
opacity:0.5;
12489
cursor: pointer;
90+
color: inherit;
12591
126-
&:hover {
127-
opacity:0.75;
92+
&svg {
93+
width:${getIconSpacingFromSize(size)}px;
94+
height:${getIconSpacingFromSize(size)}px;
12895
}
12996
`,
130-
buttonStyles,
97+
hoverEffect ?hoverEffectStyles :null,
13198
]}
132-
onClick={(event)=>{
133-
event.stopPropagation();
134-
setIsOpen(true);
135-
}}
136-
onMouseEnter={()=>{
137-
setIsOpen(true);
138-
}}
139-
onMouseLeave={()=>{
140-
setIsOpen(false);
141-
}}
142-
aria-label="More info"
14399
>
144-
<Icon
145-
css={[
146-
{
147-
width:theme.spacing(getIconSpacingFromSize(size)),
148-
height:theme.spacing(getIconSpacingFromSize(size)),
149-
},
150-
iconStyles,
151-
]}
152-
/>
100+
{children}
153101
</button>
154-
<HelpPopover
155-
id={id}
156-
open={isOpen}
157-
anchorEl={anchorRef.current}
158-
onOpen={()=>setIsOpen(true)}
159-
onClose={()=>setIsOpen(false)}
160-
>
161-
<HelpTooltipContext.Providervalue={{open:isOpen, onClose}}>
162-
{children}
163-
</HelpTooltipContext.Provider>
164-
</HelpPopover>
165-
</>
102+
</PopoverTrigger>
166103
);
167-
};
104+
});
168105

169106
exportconstHelpTooltipTitle:FC<HTMLAttributes<HTMLHeadingElement>>=({
170107
children,
@@ -213,7 +150,7 @@ export const HelpTooltipAction: FC<HelpTooltipActionProps> = ({
213150
onClick,
214151
ariaLabel,
215152
})=>{
216-
consttooltip=useHelpTooltip();
153+
constpopover=usePopover();
217154

218155
return(
219156
<button
@@ -222,7 +159,7 @@ export const HelpTooltipAction: FC<HelpTooltipActionProps> = ({
222159
onClick={(event)=>{
223160
event.stopPropagation();
224161
onClick();
225-
tooltip.onClose();
162+
popover.setIsOpen(false);
226163
}}
227164
>
228165
<Iconcss={styles.actionIcon}/>
@@ -239,42 +176,16 @@ export const HelpTooltipLinksGroup: FC<PropsWithChildren> = ({ children }) => {
239176
);
240177
};
241178

242-
constgetButtonSpacingFromSize=(size?:Size):number=>{
243-
switch(size){
244-
case"small":
245-
return2.5;
246-
case"medium":
247-
default:
248-
return3;
249-
}
250-
};
251-
252179
constgetIconSpacingFromSize=(size?:Size):number=>{
253180
switch(size){
254181
case"small":
255-
return1.5;
182+
return12;
256183
case"medium":
257184
default:
258-
return2;
185+
return16;
259186
}
260187
};
261188

262-
constclassNames={
263-
popover:(css)=>css`
264-
pointer-events: none;
265-
`,
266-
267-
paper:(css,theme)=>css`
268-
${theme.typography.body2asCSSObject}
269-
270-
margin-top:4px;
271-
width:304px;
272-
padding:20px;
273-
color:${theme.palette.text.secondary};
274-
pointer-events: auto;
275-
`,
276-
}satisfiesRecord<string,ClassName>;
277-
278189
conststyles={
279190
title:(theme)=>({
280191
marginTop:0,

‎site/src/components/InfoTooltip/InfoTooltip.tsx‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import{typeFC,typeReactNode}from"react";
22
import{
33
HelpTooltip,
4+
HelpTooltipContent,
5+
HelpTooltipIcon,
46
HelpTooltipText,
57
HelpTooltipTitle,
8+
HelpTooltipTrigger,
69
}from"components/HelpTooltip/HelpTooltip";
7-
importInfoIconfrom"@mui/icons-material/InfoOutlined";
810
import{Interpolation,Theme,css,useTheme}from"@emotion/react";
911

1012
interfaceInfoTooltipProps{
@@ -22,14 +24,16 @@ export const InfoTooltip: FC<InfoTooltipProps> = ({
2224
consttheme=useTheme();
2325

2426
return(
25-
<HelpTooltip
26-
size="small"
27-
icon={InfoIcon}
28-
iconStyles={{color:theme.experimental.roles[type].outline}}
29-
buttonStyles={styles.button}
30-
>
31-
<HelpTooltipTitle>{title}</HelpTooltipTitle>
32-
<HelpTooltipText>{message}</HelpTooltipText>
27+
<HelpTooltip>
28+
<HelpTooltipTriggersize="small"css={styles.button}>
29+
<HelpTooltipIcon
30+
css={{color:theme.experimental.roles[type].outline}}
31+
/>
32+
</HelpTooltipTrigger>
33+
<HelpTooltipContent>
34+
<HelpTooltipTitle>{title}</HelpTooltipTitle>
35+
<HelpTooltipText>{message}</HelpTooltipText>
36+
</HelpTooltipContent>
3337
</HelpTooltip>
3438
);
3539
};

‎site/src/components/Popover/Popover.tsx‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
useId,
1010
useRef,
1111
useState,
12+
HTMLAttributes,
1213
}from"react";
1314
// This is used as base for the main Popover component
1415
// eslint-disable-next-line no-restricted-imports -- Read above
@@ -79,8 +80,11 @@ export const usePopover = () => {
7980
returncontext;
8081
};
8182

82-
exportconstPopoverTrigger=(props:{children:TriggerElement})=>{
83+
exportconstPopoverTrigger=(
84+
props:HTMLAttributes<HTMLElement>&{children:TriggerElement},
85+
)=>{
8386
constpopover=usePopover();
87+
const{ children, ...elementProps}=props;
8488

8589
constclickProps={
8690
onClick:()=>{
@@ -98,6 +102,7 @@ export const PopoverTrigger = (props: { children: TriggerElement }) => {
98102
};
99103

100104
returncloneElement(props.children,{
105+
...elementProps,
101106
...(popover.mode==="click" ?clickProps :hoverProps),
102107
"aria-haspopup":true,
103108
"aria-owns":popover.isOpen ?popover.id :undefined,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp