diff options
author | Kristóf Marussy <kristof@marussy.com> | 2024-04-12 16:59:31 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2024-04-12 17:39:52 +0200 |
commit | d087a0abc83c07c067d7ac7afff1acc57dad6220 (patch) | |
tree | e317ed7d5bd576efbb3af51be89bd3bfa5e00115 | |
parent | refactor(frontend): friendlier table view messages (diff) | |
download | refinery-d087a0abc83c07c067d7ac7afff1acc57dad6220.tar.gz refinery-d087a0abc83c07c067d7ac7afff1acc57dad6220.tar.zst refinery-d087a0abc83c07c067d7ac7afff1acc57dad6220.zip |
feat(frontend): add tooltips to buttons
-rw-r--r-- | subprojects/frontend/src/ToggleDarkModeButton.tsx | 13 | ||||
-rw-r--r-- | subprojects/frontend/src/TopBar.tsx | 20 | ||||
-rw-r--r-- | subprojects/frontend/src/editor/ConnectButton.tsx | 51 | ||||
-rw-r--r-- | subprojects/frontend/src/editor/EditorButtons.tsx | 187 | ||||
-rw-r--r-- | subprojects/frontend/src/editor/SearchToolbar.tsx | 94 | ||||
-rw-r--r-- | subprojects/frontend/src/graph/SlideInPanel.tsx | 21 | ||||
-rw-r--r-- | subprojects/frontend/src/graph/VisibilityPanel.tsx | 2 | ||||
-rw-r--r-- | subprojects/frontend/src/graph/ZoomButtons.tsx | 38 | ||||
-rw-r--r-- | subprojects/frontend/src/graph/export/ExportPanel.tsx | 2 | ||||
-rw-r--r-- | subprojects/frontend/src/theme/ThemeProvider.tsx | 3 |
10 files changed, 238 insertions, 193 deletions
diff --git a/subprojects/frontend/src/ToggleDarkModeButton.tsx b/subprojects/frontend/src/ToggleDarkModeButton.tsx index 7a835e61..58238cab 100644 --- a/subprojects/frontend/src/ToggleDarkModeButton.tsx +++ b/subprojects/frontend/src/ToggleDarkModeButton.tsx | |||
@@ -7,6 +7,7 @@ | |||
7 | import DarkModeIcon from '@mui/icons-material/DarkMode'; | 7 | import DarkModeIcon from '@mui/icons-material/DarkMode'; |
8 | import LightModeIcon from '@mui/icons-material/LightMode'; | 8 | import LightModeIcon from '@mui/icons-material/LightMode'; |
9 | import IconButton from '@mui/material/IconButton'; | 9 | import IconButton from '@mui/material/IconButton'; |
10 | import Tooltip from '@mui/material/Tooltip'; | ||
10 | import { observer } from 'mobx-react-lite'; | 11 | import { observer } from 'mobx-react-lite'; |
11 | 12 | ||
12 | import { useRootStore } from './RootStoreProvider'; | 13 | import { useRootStore } from './RootStoreProvider'; |
@@ -16,12 +17,10 @@ export default observer(function ToggleDarkModeButton(): JSX.Element { | |||
16 | const { darkMode } = themeStore; | 17 | const { darkMode } = themeStore; |
17 | 18 | ||
18 | return ( | 19 | return ( |
19 | <IconButton | 20 | <Tooltip title={darkMode ? 'Switch to light mode' : 'Switch to dark mode'}> |
20 | color="inherit" | 21 | <IconButton color="inherit" onClick={() => themeStore.toggleDarkMode()}> |
21 | onClick={() => themeStore.toggleDarkMode()} | 22 | {darkMode ? <LightModeIcon /> : <DarkModeIcon />} |
22 | aria-label={darkMode ? 'Switch to light mode' : 'Switch to dark mode'} | 23 | </IconButton> |
23 | > | 24 | </Tooltip> |
24 | {darkMode ? <LightModeIcon /> : <DarkModeIcon />} | ||
25 | </IconButton> | ||
26 | ); | 25 | ); |
27 | }); | 26 | }); |
diff --git a/subprojects/frontend/src/TopBar.tsx b/subprojects/frontend/src/TopBar.tsx index 6c9c4f7e..e41f956e 100644 --- a/subprojects/frontend/src/TopBar.tsx +++ b/subprojects/frontend/src/TopBar.tsx | |||
@@ -9,6 +9,7 @@ import AppBar from '@mui/material/AppBar'; | |||
9 | import IconButton from '@mui/material/IconButton'; | 9 | import IconButton from '@mui/material/IconButton'; |
10 | import Stack from '@mui/material/Stack'; | 10 | import Stack from '@mui/material/Stack'; |
11 | import Toolbar from '@mui/material/Toolbar'; | 11 | import Toolbar from '@mui/material/Toolbar'; |
12 | import Tooltip from '@mui/material/Tooltip'; | ||
12 | import Typography from '@mui/material/Typography'; | 13 | import Typography from '@mui/material/Typography'; |
13 | import { styled, useTheme } from '@mui/material/styles'; | 14 | import { styled, useTheme } from '@mui/material/styles'; |
14 | import useMediaQuery from '@mui/material/useMediaQuery'; | 15 | import useMediaQuery from '@mui/material/useMediaQuery'; |
@@ -134,7 +135,7 @@ export default observer(function TopBar(): JSX.Element { | |||
134 | py: 0.5, | 135 | py: 0.5, |
135 | }} | 136 | }} |
136 | > | 137 | > |
137 | <RefineryIcon size={24} /> | 138 | <RefineryIcon size={32} /> |
138 | <Typography variant="h6" component="h1" pl={1}> | 139 | <Typography variant="h6" component="h1" pl={1}> |
139 | Refinery {import.meta.env.DEV && <DevModeBadge>Dev</DevModeBadge>} | 140 | Refinery {import.meta.env.DEV && <DevModeBadge>Dev</DevModeBadge>} |
140 | </Typography> | 141 | </Typography> |
@@ -172,14 +173,15 @@ export default observer(function TopBar(): JSX.Element { | |||
172 | > | 173 | > |
173 | <GenerateButton editorStore={editorStore} hideWarnings={!veryLarge} /> | 174 | <GenerateButton editorStore={editorStore} hideWarnings={!veryLarge} /> |
174 | {large && ( | 175 | {large && ( |
175 | <IconButton | 176 | <Tooltip title="Check us out at GitHub"> |
176 | aria-label="GitHub" | 177 | <IconButton |
177 | href="https://github.com/graphs4value/refinery" | 178 | href="https://github.com/graphs4value/refinery" |
178 | target="_blank" | 179 | target="_blank" |
179 | color="inherit" | 180 | color="inherit" |
180 | > | 181 | > |
181 | <GitHubIcon /> | 182 | <GitHubIcon /> |
182 | </IconButton> | 183 | </IconButton> |
184 | </Tooltip> | ||
183 | )} | 185 | )} |
184 | </Stack> | 186 | </Stack> |
185 | <ToggleDarkModeButton /> | 187 | <ToggleDarkModeButton /> |
diff --git a/subprojects/frontend/src/editor/ConnectButton.tsx b/subprojects/frontend/src/editor/ConnectButton.tsx index eed6fbc7..d08fbb4d 100644 --- a/subprojects/frontend/src/editor/ConnectButton.tsx +++ b/subprojects/frontend/src/editor/ConnectButton.tsx | |||
@@ -9,6 +9,7 @@ import CloudOffIcon from '@mui/icons-material/CloudOff'; | |||
9 | import SyncIcon from '@mui/icons-material/Sync'; | 9 | import SyncIcon from '@mui/icons-material/Sync'; |
10 | import SyncProblemIcon from '@mui/icons-material/SyncProblem'; | 10 | import SyncProblemIcon from '@mui/icons-material/SyncProblem'; |
11 | import IconButton from '@mui/material/IconButton'; | 11 | import IconButton from '@mui/material/IconButton'; |
12 | import Tooltip from '@mui/material/Tooltip'; | ||
12 | import { keyframes, styled } from '@mui/material/styles'; | 13 | import { keyframes, styled } from '@mui/material/styles'; |
13 | import { observer } from 'mobx-react-lite'; | 14 | import { observer } from 'mobx-react-lite'; |
14 | 15 | ||
@@ -37,37 +38,51 @@ export default observer(function ConnectButton({ | |||
37 | (editorStore.opening || editorStore.opened) | 38 | (editorStore.opening || editorStore.opened) |
38 | ) { | 39 | ) { |
39 | return ( | 40 | return ( |
40 | <IconButton | 41 | <Tooltip |
41 | onClick={() => editorStore.disconnect()} | 42 | title={ |
42 | aria-label="Disconnect" | 43 | editorStore.opening |
43 | color="inherit" | 44 | ? 'Connecting (click to cancel)' |
45 | : 'Connected (click to disconnect)' | ||
46 | } | ||
44 | > | 47 | > |
45 | {editorStore.opening ? ( | 48 | <IconButton |
46 | <AnimatedSyncIcon fontSize="small" /> | 49 | onClick={() => editorStore.disconnect()} |
47 | ) : ( | 50 | aria-label="Disconnect" |
48 | <CloudIcon fontSize="small" /> | 51 | color="inherit" |
49 | )} | 52 | > |
50 | </IconButton> | 53 | {editorStore.opening ? ( |
54 | <AnimatedSyncIcon fontSize="small" /> | ||
55 | ) : ( | ||
56 | <CloudIcon fontSize="small" /> | ||
57 | )} | ||
58 | </IconButton> | ||
59 | </Tooltip> | ||
51 | ); | 60 | ); |
52 | } | 61 | } |
53 | 62 | ||
63 | let title: string; | ||
54 | let disconnectedIcon: JSX.Element; | 64 | let disconnectedIcon: JSX.Element; |
55 | if (editorStore === undefined) { | 65 | if (editorStore === undefined) { |
66 | title = 'Connecting'; | ||
56 | disconnectedIcon = <SyncIcon fontSize="small" />; | 67 | disconnectedIcon = <SyncIcon fontSize="small" />; |
57 | } else if (editorStore.connectionErrors.length > 0) { | 68 | } else if (editorStore.connectionErrors.length > 0) { |
69 | title = 'Connection error (click to retry)'; | ||
58 | disconnectedIcon = <SyncProblemIcon fontSize="small" />; | 70 | disconnectedIcon = <SyncProblemIcon fontSize="small" />; |
59 | } else { | 71 | } else { |
72 | title = 'Disconnected (click to connect)'; | ||
60 | disconnectedIcon = <CloudOffIcon fontSize="small" />; | 73 | disconnectedIcon = <CloudOffIcon fontSize="small" />; |
61 | } | 74 | } |
62 | 75 | ||
63 | return ( | 76 | return ( |
64 | <IconButton | 77 | <Tooltip title={title}> |
65 | disabled={editorStore === undefined} | 78 | <IconButton |
66 | onClick={() => editorStore?.connect()} | 79 | disabled={editorStore === undefined} |
67 | aria-label="Connect" | 80 | onClick={() => editorStore?.connect()} |
68 | color="inherit" | 81 | aria-label="Connect" |
69 | > | 82 | color="inherit" |
70 | {disconnectedIcon} | 83 | > |
71 | </IconButton> | 84 | {disconnectedIcon} |
85 | </IconButton> | ||
86 | </Tooltip> | ||
72 | ); | 87 | ); |
73 | }); | 88 | }); |
diff --git a/subprojects/frontend/src/editor/EditorButtons.tsx b/subprojects/frontend/src/editor/EditorButtons.tsx index 4afba607..50cd51dc 100644 --- a/subprojects/frontend/src/editor/EditorButtons.tsx +++ b/subprojects/frontend/src/editor/EditorButtons.tsx | |||
@@ -22,6 +22,7 @@ import IconButton from '@mui/material/IconButton'; | |||
22 | import Stack from '@mui/material/Stack'; | 22 | import Stack from '@mui/material/Stack'; |
23 | import ToggleButton from '@mui/material/ToggleButton'; | 23 | import ToggleButton from '@mui/material/ToggleButton'; |
24 | import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; | 24 | import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; |
25 | import Tooltip from '@mui/material/Tooltip'; | ||
25 | import { observer } from 'mobx-react-lite'; | 26 | import { observer } from 'mobx-react-lite'; |
26 | 27 | ||
27 | import ConnectButton from './ConnectButton'; | 28 | import ConnectButton from './ConnectButton'; |
@@ -49,103 +50,113 @@ export default observer(function EditorButtons({ | |||
49 | }): JSX.Element { | 50 | }): JSX.Element { |
50 | return ( | 51 | return ( |
51 | <Stack direction="row" flexGrow={1}> | 52 | <Stack direction="row" flexGrow={1}> |
52 | <IconButton | 53 | <Tooltip title="Open"> |
53 | disabled={editorStore === undefined} | ||
54 | onClick={() => editorStore?.openFile()} | ||
55 | aria-label="Open" | ||
56 | color="inherit" | ||
57 | > | ||
58 | <FileOpenIcon fontSize="small" /> | ||
59 | </IconButton> | ||
60 | <IconButton | ||
61 | disabled={editorStore === undefined || !editorStore.unsavedChanges} | ||
62 | onClick={() => editorStore?.saveFile()} | ||
63 | aria-label="Save" | ||
64 | color="inherit" | ||
65 | > | ||
66 | <SaveIcon fontSize="small" /> | ||
67 | </IconButton> | ||
68 | {'showSaveFilePicker' in window && ( | ||
69 | <IconButton | 54 | <IconButton |
70 | disabled={editorStore === undefined} | 55 | disabled={editorStore === undefined} |
71 | onClick={() => editorStore?.saveFileAs()} | 56 | onClick={() => editorStore?.openFile()} |
72 | aria-label="Save as" | ||
73 | color="inherit" | 57 | color="inherit" |
74 | > | 58 | > |
75 | <SaveAsIcon fontSize="small" /> | 59 | <FileOpenIcon fontSize="small" /> |
76 | </IconButton> | 60 | </IconButton> |
77 | )} | 61 | </Tooltip> |
78 | <IconButton | 62 | <Tooltip title="Save"> |
79 | disabled={editorStore === undefined || !editorStore.canUndo} | 63 | <IconButton |
80 | onClick={() => editorStore?.undo()} | 64 | disabled={editorStore === undefined || !editorStore.unsavedChanges} |
81 | aria-label="Undo" | 65 | onClick={() => editorStore?.saveFile()} |
82 | color="inherit" | 66 | color="inherit" |
83 | sx={{ ml: 1 }} | ||
84 | > | ||
85 | <UndoIcon fontSize="small" /> | ||
86 | </IconButton> | ||
87 | <IconButton | ||
88 | disabled={editorStore === undefined || !editorStore.canRedo} | ||
89 | onClick={() => editorStore?.redo()} | ||
90 | aria-label="Redo" | ||
91 | color="inherit" | ||
92 | > | ||
93 | <RedoIcon fontSize="small" /> | ||
94 | </IconButton> | ||
95 | <ToggleButtonGroup size="small" className="rounded" sx={{ mx: 1 }}> | ||
96 | <ToggleButton | ||
97 | selected={editorStore?.showLineNumbers ?? false} | ||
98 | disabled={editorStore === undefined} | ||
99 | onClick={() => editorStore?.toggleLineNumbers()} | ||
100 | aria-label="Show line numbers" | ||
101 | value="show-line-numbers" | ||
102 | > | ||
103 | <FormatListNumberedIcon fontSize="small" /> | ||
104 | </ToggleButton> | ||
105 | <ToggleButton | ||
106 | selected={editorStore?.colorIdentifiers ?? false} | ||
107 | disabled={editorStore === undefined} | ||
108 | onClick={() => editorStore?.toggleColorIdentifiers()} | ||
109 | aria-label="Color identifiers" | ||
110 | value="color-identifiers" | ||
111 | > | 67 | > |
112 | <LooksIcon fontSize="small" /> | 68 | <SaveIcon fontSize="small" /> |
113 | </ToggleButton> | 69 | </IconButton> |
114 | <ToggleButton | 70 | </Tooltip> |
115 | selected={editorStore?.searchPanel?.state ?? false} | 71 | {'showSaveFilePicker' in window && ( |
116 | disabled={editorStore === undefined} | 72 | <Tooltip title={`Save as\u2026`}> |
117 | onClick={() => editorStore?.searchPanel?.toggle()} | 73 | <IconButton |
118 | aria-label="Show find/replace" | 74 | disabled={editorStore === undefined} |
119 | {...(editorStore !== undefined && | 75 | onClick={() => editorStore?.saveFileAs()} |
120 | editorStore.searchPanel.state && { | 76 | color="inherit" |
121 | 'aria-controls': editorStore.searchPanel.id, | 77 | > |
122 | })} | 78 | <SaveAsIcon fontSize="small" /> |
123 | value="show-search-panel" | 79 | </IconButton> |
80 | </Tooltip> | ||
81 | )} | ||
82 | <Tooltip title="Undo"> | ||
83 | <IconButton | ||
84 | disabled={editorStore === undefined || !editorStore.canUndo} | ||
85 | onClick={() => editorStore?.undo()} | ||
86 | color="inherit" | ||
87 | sx={{ ml: 1 }} | ||
124 | > | 88 | > |
125 | <SearchIcon fontSize="small" /> | 89 | <UndoIcon fontSize="small" /> |
126 | </ToggleButton> | 90 | </IconButton> |
127 | <ToggleButton | 91 | </Tooltip> |
128 | selected={editorStore?.lintPanel?.state ?? false} | 92 | <Tooltip title="Redo"> |
129 | disabled={editorStore === undefined} | 93 | <IconButton |
130 | onClick={() => editorStore?.lintPanel.toggle()} | 94 | disabled={editorStore === undefined || !editorStore.canRedo} |
131 | aria-label="Show diagnostics panel" | 95 | onClick={() => editorStore?.redo()} |
132 | {...(editorStore !== undefined && | 96 | color="inherit" |
133 | editorStore.lintPanel.state && { | ||
134 | 'aria-controls': editorStore.lintPanel.id, | ||
135 | })} | ||
136 | value="show-lint-panel" | ||
137 | > | 97 | > |
138 | {getLintIcon(editorStore?.delayedErrors?.highestDiagnosticLevel)} | 98 | <RedoIcon fontSize="small" /> |
139 | </ToggleButton> | 99 | </IconButton> |
100 | </Tooltip> | ||
101 | <ToggleButtonGroup size="small" className="rounded" sx={{ mx: 1 }}> | ||
102 | <Tooltip title="Line numbers"> | ||
103 | <ToggleButton | ||
104 | selected={editorStore?.showLineNumbers ?? false} | ||
105 | disabled={editorStore === undefined} | ||
106 | onClick={() => editorStore?.toggleLineNumbers()} | ||
107 | value="show-line-numbers" | ||
108 | > | ||
109 | <FormatListNumberedIcon fontSize="small" /> | ||
110 | </ToggleButton> | ||
111 | </Tooltip> | ||
112 | <Tooltip title="Color identifiers"> | ||
113 | <ToggleButton | ||
114 | selected={editorStore?.colorIdentifiers ?? false} | ||
115 | disabled={editorStore === undefined} | ||
116 | onClick={() => editorStore?.toggleColorIdentifiers()} | ||
117 | value="color-identifiers" | ||
118 | > | ||
119 | <LooksIcon fontSize="small" /> | ||
120 | </ToggleButton> | ||
121 | </Tooltip> | ||
122 | <Tooltip title="Find and replace"> | ||
123 | <ToggleButton | ||
124 | selected={editorStore?.searchPanel?.state ?? false} | ||
125 | disabled={editorStore === undefined} | ||
126 | onClick={() => editorStore?.searchPanel?.toggle()} | ||
127 | {...(editorStore !== undefined && | ||
128 | editorStore.searchPanel.state && { | ||
129 | 'aria-controls': editorStore.searchPanel.id, | ||
130 | })} | ||
131 | value="show-search-panel" | ||
132 | > | ||
133 | <SearchIcon fontSize="small" /> | ||
134 | </ToggleButton> | ||
135 | </Tooltip> | ||
136 | <Tooltip title="Diagnostics panel"> | ||
137 | <ToggleButton | ||
138 | selected={editorStore?.lintPanel?.state ?? false} | ||
139 | disabled={editorStore === undefined} | ||
140 | onClick={() => editorStore?.lintPanel.toggle()} | ||
141 | {...(editorStore !== undefined && | ||
142 | editorStore.lintPanel.state && { | ||
143 | 'aria-controls': editorStore.lintPanel.id, | ||
144 | })} | ||
145 | value="show-lint-panel" | ||
146 | > | ||
147 | {getLintIcon(editorStore?.delayedErrors?.highestDiagnosticLevel)} | ||
148 | </ToggleButton> | ||
149 | </Tooltip> | ||
140 | </ToggleButtonGroup> | 150 | </ToggleButtonGroup> |
141 | <IconButton | 151 | <Tooltip title="Automatic format"> |
142 | disabled={editorStore === undefined || !editorStore.opened} | 152 | <IconButton |
143 | onClick={() => editorStore?.formatText()} | 153 | disabled={editorStore === undefined || !editorStore.opened} |
144 | aria-label="Automatic format" | 154 | onClick={() => editorStore?.formatText()} |
145 | color="inherit" | 155 | color="inherit" |
146 | > | 156 | > |
147 | <FormatPaintIcon fontSize="small" /> | 157 | <FormatPaintIcon fontSize="small" /> |
148 | </IconButton> | 158 | </IconButton> |
159 | </Tooltip> | ||
149 | <ConnectButton editorStore={editorStore} /> | 160 | <ConnectButton editorStore={editorStore} /> |
150 | </Stack> | 161 | </Stack> |
151 | ); | 162 | ); |
diff --git a/subprojects/frontend/src/editor/SearchToolbar.tsx b/subprojects/frontend/src/editor/SearchToolbar.tsx index 4ae7e893..bfdff234 100644 --- a/subprojects/frontend/src/editor/SearchToolbar.tsx +++ b/subprojects/frontend/src/editor/SearchToolbar.tsx | |||
@@ -17,15 +17,14 @@ import Stack from '@mui/material/Stack'; | |||
17 | import TextField from '@mui/material/TextField'; | 17 | import TextField from '@mui/material/TextField'; |
18 | import ToggleButton from '@mui/material/ToggleButton'; | 18 | import ToggleButton from '@mui/material/ToggleButton'; |
19 | import Toolbar from '@mui/material/Toolbar'; | 19 | import Toolbar from '@mui/material/Toolbar'; |
20 | import Tooltip from '@mui/material/Tooltip'; | ||
20 | import { styled } from '@mui/material/styles'; | 21 | import { styled } from '@mui/material/styles'; |
21 | import useMediaQuery from '@mui/material/useMediaQuery'; | ||
22 | import { observer } from 'mobx-react-lite'; | 22 | import { observer } from 'mobx-react-lite'; |
23 | import { useCallback, useState } from 'react'; | 23 | import { useCallback, useState } from 'react'; |
24 | import { useResizeDetector } from 'react-resize-detector'; | ||
24 | 25 | ||
25 | import type SearchPanelStore from './SearchPanelStore'; | 26 | import type SearchPanelStore from './SearchPanelStore'; |
26 | 27 | ||
27 | const SPLIT_MEDIA_QUERY = '@media (max-width: 1200px)'; | ||
28 | |||
29 | const DimLabel = styled(FormControlLabel)(({ theme }) => ({ | 28 | const DimLabel = styled(FormControlLabel)(({ theme }) => ({ |
30 | '.MuiFormControlLabel-label': { | 29 | '.MuiFormControlLabel-label': { |
31 | ...theme.typography.body2, | 30 | ...theme.typography.body2, |
@@ -43,7 +42,8 @@ export default observer(function SearchToolbar({ | |||
43 | query: { search, valid, caseSensitive, literal, regexp, replace }, | 42 | query: { search, valid, caseSensitive, literal, regexp, replace }, |
44 | invalidRegexp, | 43 | invalidRegexp, |
45 | } = searchPanelStore; | 44 | } = searchPanelStore; |
46 | const split = useMediaQuery(SPLIT_MEDIA_QUERY); | 45 | const { width, ref } = useResizeDetector(); |
46 | const split = width !== undefined && width <= 1200; | ||
47 | const [showRepalceState, setShowReplaceState] = useState(false); | 47 | const [showRepalceState, setShowReplaceState] = useState(false); |
48 | 48 | ||
49 | const showReplace = !split || showRepalceState || replace !== ''; | 49 | const showReplace = !split || showRepalceState || replace !== ''; |
@@ -61,16 +61,19 @@ export default observer(function SearchToolbar({ | |||
61 | <Toolbar | 61 | <Toolbar |
62 | variant="dense" | 62 | variant="dense" |
63 | sx={{ py: 0.5, alignItems: 'center', minHeight: 'auto' }} | 63 | sx={{ py: 0.5, alignItems: 'center', minHeight: 'auto' }} |
64 | ref={ref} | ||
64 | > | 65 | > |
65 | <Stack | 66 | <Stack |
66 | direction={split ? 'column' : 'row'} | 67 | direction={split ? 'column' : 'row'} |
67 | sx={{ | 68 | sx={{ |
68 | alignItems: 'center', | 69 | alignItems: 'center', |
69 | flexGrow: 1, | 70 | flexGrow: 1, |
70 | [SPLIT_MEDIA_QUERY]: { | 71 | ...(split |
71 | alignItems: 'start', | 72 | ? { |
72 | gap: 0.5, | 73 | alignItems: 'start', |
73 | }, | 74 | gap: 0.5, |
75 | } | ||
76 | : {}), | ||
74 | }} | 77 | }} |
75 | > | 78 | > |
76 | <Stack direction="row" flexWrap="wrap" alignItems="center" rowGap={0.5}> | 79 | <Stack direction="row" flexWrap="wrap" alignItems="center" rowGap={0.5}> |
@@ -121,22 +124,24 @@ export default observer(function SearchToolbar({ | |||
121 | mr={1} | 124 | mr={1} |
122 | rowGap={0.5} | 125 | rowGap={0.5} |
123 | > | 126 | > |
124 | <IconButton | 127 | <Tooltip title="Previous match"> |
125 | aria-label="Previous" | 128 | <IconButton |
126 | disabled={!valid} | 129 | disabled={!valid} |
127 | onClick={() => searchPanelStore.findPrevious()} | 130 | onClick={() => searchPanelStore.findPrevious()} |
128 | color="inherit" | 131 | color="inherit" |
129 | > | 132 | > |
130 | <KeyboardArrowUpIcon fontSize="small" /> | 133 | <KeyboardArrowUpIcon fontSize="small" /> |
131 | </IconButton> | 134 | </IconButton> |
132 | <IconButton | 135 | </Tooltip> |
133 | aria-label="Next" | 136 | <Tooltip title="Next match"> |
134 | disabled={!valid} | 137 | <IconButton |
135 | onClick={() => searchPanelStore.findNext()} | 138 | disabled={!valid} |
136 | color="inherit" | 139 | onClick={() => searchPanelStore.findNext()} |
137 | > | 140 | color="inherit" |
138 | <KeyboardArrowDownIcon fontSize="small" /> | 141 | > |
139 | </IconButton> | 142 | <KeyboardArrowDownIcon fontSize="small" /> |
143 | </IconButton> | ||
144 | </Tooltip> | ||
140 | </Stack> | 145 | </Stack> |
141 | <Stack | 146 | <Stack |
142 | direction="row" | 147 | direction="row" |
@@ -187,24 +192,25 @@ export default observer(function SearchToolbar({ | |||
187 | label="Regexp" | 192 | label="Regexp" |
188 | /> | 193 | /> |
189 | {split && ( | 194 | {split && ( |
190 | <ToggleButton | 195 | <Tooltip title="Replace"> |
191 | value="show-replace" | 196 | <ToggleButton |
192 | selected={showReplace} | 197 | value="show-replace" |
193 | onClick={() => { | 198 | selected={showReplace} |
194 | if (showReplace) { | 199 | onClick={() => { |
195 | searchPanelStore.updateQuery({ replace: '' }); | 200 | if (showReplace) { |
196 | setShowReplaceState(false); | 201 | searchPanelStore.updateQuery({ replace: '' }); |
197 | } else { | 202 | setShowReplaceState(false); |
198 | setShowReplaceState(true); | 203 | } else { |
199 | } | 204 | setShowReplaceState(true); |
200 | }} | 205 | } |
201 | aria-label="Show replace options" | 206 | }} |
202 | aria-controls={replaceId} | 207 | aria-controls={replaceId} |
203 | size="small" | 208 | size="small" |
204 | className="iconOnly" | 209 | className="iconOnly" |
205 | > | 210 | > |
206 | <FindReplaceIcon fontSize="small" /> | 211 | <FindReplaceIcon fontSize="small" /> |
207 | </ToggleButton> | 212 | </ToggleButton> |
213 | </Tooltip> | ||
208 | )} | 214 | )} |
209 | </Stack> | 215 | </Stack> |
210 | </Stack> | 216 | </Stack> |
@@ -263,9 +269,7 @@ export default observer(function SearchToolbar({ | |||
263 | alignSelf="stretch" | 269 | alignSelf="stretch" |
264 | alignItems="start" | 270 | alignItems="start" |
265 | mt="1px" | 271 | mt="1px" |
266 | sx={{ | 272 | sx={split ? { display: 'none' } : {}} |
267 | [SPLIT_MEDIA_QUERY]: { display: 'none' }, | ||
268 | }} | ||
269 | > | 273 | > |
270 | <IconButton | 274 | <IconButton |
271 | aria-label="Close find/replace" | 275 | aria-label="Close find/replace" |
diff --git a/subprojects/frontend/src/graph/SlideInPanel.tsx b/subprojects/frontend/src/graph/SlideInPanel.tsx index 2c189b5b..47bbe0a6 100644 --- a/subprojects/frontend/src/graph/SlideInPanel.tsx +++ b/subprojects/frontend/src/graph/SlideInPanel.tsx | |||
@@ -8,6 +8,7 @@ import Dialog from '@mui/material/Dialog'; | |||
8 | import IconButton from '@mui/material/IconButton'; | 8 | import IconButton from '@mui/material/IconButton'; |
9 | import Paper from '@mui/material/Paper'; | 9 | import Paper from '@mui/material/Paper'; |
10 | import Slide from '@mui/material/Slide'; | 10 | import Slide from '@mui/material/Slide'; |
11 | import Tooltip from '@mui/material/Tooltip'; | ||
11 | import { styled } from '@mui/material/styles'; | 12 | import { styled } from '@mui/material/styles'; |
12 | import React, { useCallback, useId, useState } from 'react'; | 13 | import React, { useCallback, useId, useState } from 'react'; |
13 | 14 | ||
@@ -58,15 +59,19 @@ export default function SlideInPanel({ | |||
58 | 59 | ||
59 | return ( | 60 | return ( |
60 | <SlideInPanelRoot anchor={anchor}> | 61 | <SlideInPanelRoot anchor={anchor}> |
61 | <IconButton | 62 | <Tooltip |
62 | role="switch" | 63 | title={iconLabel} |
63 | aria-checked={show} | 64 | placement={anchor === 'left' ? 'right' : 'left'} |
64 | aria-controls={dialog ? undefined : id} | ||
65 | aria-label={iconLabel} | ||
66 | onClick={() => setShow(!show)} | ||
67 | > | 65 | > |
68 | {icon(show)} | 66 | <IconButton |
69 | </IconButton> | 67 | role="switch" |
68 | aria-checked={show} | ||
69 | aria-controls={dialog ? undefined : id} | ||
70 | onClick={() => setShow(!show)} | ||
71 | > | ||
72 | {icon(show)} | ||
73 | </IconButton> | ||
74 | </Tooltip> | ||
70 | {dialog ? ( | 75 | {dialog ? ( |
71 | <Dialog open={show} onClose={close} maxWidth="xl"> | 76 | <Dialog open={show} onClose={close} maxWidth="xl"> |
72 | <SlideInDialog close={close} dialog title={title} buttons={buttons}> | 77 | <SlideInDialog close={close} dialog title={title} buttons={buttons}> |
diff --git a/subprojects/frontend/src/graph/VisibilityPanel.tsx b/subprojects/frontend/src/graph/VisibilityPanel.tsx index 210ff5d5..8474b7be 100644 --- a/subprojects/frontend/src/graph/VisibilityPanel.tsx +++ b/subprojects/frontend/src/graph/VisibilityPanel.tsx | |||
@@ -199,7 +199,7 @@ function VisibilityPanel({ | |||
199 | dialog={dialog} | 199 | dialog={dialog} |
200 | title="Customize view" | 200 | title="Customize view" |
201 | icon={icon} | 201 | icon={icon} |
202 | iconLabel="Show filter panel" | 202 | iconLabel="Filter panel" |
203 | buttons={ | 203 | buttons={ |
204 | <> | 204 | <> |
205 | <Button | 205 | <Button |
diff --git a/subprojects/frontend/src/graph/ZoomButtons.tsx b/subprojects/frontend/src/graph/ZoomButtons.tsx index 83938cf4..b292a617 100644 --- a/subprojects/frontend/src/graph/ZoomButtons.tsx +++ b/subprojects/frontend/src/graph/ZoomButtons.tsx | |||
@@ -10,6 +10,7 @@ import RemoveIcon from '@mui/icons-material/Remove'; | |||
10 | import IconButton from '@mui/material/IconButton'; | 10 | import IconButton from '@mui/material/IconButton'; |
11 | import Stack from '@mui/material/Stack'; | 11 | import Stack from '@mui/material/Stack'; |
12 | import ToggleButton from '@mui/material/ToggleButton'; | 12 | import ToggleButton from '@mui/material/ToggleButton'; |
13 | import Tooltip from '@mui/material/Tooltip'; | ||
13 | 14 | ||
14 | import type { ChangeZoomCallback, SetFitZoomCallback } from './ZoomCanvas'; | 15 | import type { ChangeZoomCallback, SetFitZoomCallback } from './ZoomCanvas'; |
15 | 16 | ||
@@ -28,22 +29,27 @@ export default function ZoomButtons({ | |||
28 | p={1} | 29 | p={1} |
29 | sx={{ position: 'absolute', bottom: 0, right: 0 }} | 30 | sx={{ position: 'absolute', bottom: 0, right: 0 }} |
30 | > | 31 | > |
31 | <IconButton aria-label="Zoom in" onClick={() => changeZoom(2)}> | 32 | <Tooltip title="Zoom in" placement="left"> |
32 | <AddIcon fontSize="small" /> | 33 | <IconButton onClick={() => changeZoom(2)}> |
33 | </IconButton> | 34 | <AddIcon fontSize="small" /> |
34 | <IconButton aria-label="Zoom out" onClick={() => changeZoom(0.5)}> | 35 | </IconButton> |
35 | <RemoveIcon fontSize="small" /> | 36 | </Tooltip> |
36 | </IconButton> | 37 | <Tooltip title="Zoom out" placement="left"> |
37 | <ToggleButton | 38 | <IconButton onClick={() => changeZoom(0.5)}> |
38 | value="show-replace" | 39 | <RemoveIcon fontSize="small" /> |
39 | selected={fitZoom} | 40 | </IconButton> |
40 | onClick={() => setFitZoom(!fitZoom)} | 41 | </Tooltip> |
41 | aria-label="Fit screen" | 42 | <Tooltip title="Fit screen" placement="left"> |
42 | size="small" | 43 | <ToggleButton |
43 | className="iconOnly" | 44 | value="show-replace" |
44 | > | 45 | selected={fitZoom} |
45 | <CropFreeIcon fontSize="small" /> | 46 | onClick={() => setFitZoom(!fitZoom)} |
46 | </ToggleButton> | 47 | size="small" |
48 | className="iconOnly" | ||
49 | > | ||
50 | <CropFreeIcon fontSize="small" /> | ||
51 | </ToggleButton> | ||
52 | </Tooltip> | ||
47 | </Stack> | 53 | </Stack> |
48 | ); | 54 | ); |
49 | } | 55 | } |
diff --git a/subprojects/frontend/src/graph/export/ExportPanel.tsx b/subprojects/frontend/src/graph/export/ExportPanel.tsx index 8d82b95c..81bd9081 100644 --- a/subprojects/frontend/src/graph/export/ExportPanel.tsx +++ b/subprojects/frontend/src/graph/export/ExportPanel.tsx | |||
@@ -135,7 +135,7 @@ function ExportPanel({ | |||
135 | dialog={dialog} | 135 | dialog={dialog} |
136 | title="Export diagram" | 136 | title="Export diagram" |
137 | icon={icon} | 137 | icon={icon} |
138 | iconLabel="Show export panel" | 138 | iconLabel={`Export image\u2026`} |
139 | buttons={buttons} | 139 | buttons={buttons} |
140 | > | 140 | > |
141 | <SwitchButtonGroup size="small" className="rounded"> | 141 | <SwitchButtonGroup size="small" className="rounded"> |
diff --git a/subprojects/frontend/src/theme/ThemeProvider.tsx b/subprojects/frontend/src/theme/ThemeProvider.tsx index 6905fb4b..1d70dbaf 100644 --- a/subprojects/frontend/src/theme/ThemeProvider.tsx +++ b/subprojects/frontend/src/theme/ThemeProvider.tsx | |||
@@ -206,6 +206,9 @@ function createResponsiveTheme( | |||
206 | tooltip: { | 206 | tooltip: { |
207 | background: alpha('#212121', 0.93), | 207 | background: alpha('#212121', 0.93), |
208 | color: '#fff', | 208 | color: '#fff', |
209 | fontSize: '0.875rem', | ||
210 | lineHeight: 1.43, | ||
211 | letterSpacing: '0.01071em', | ||
209 | }, | 212 | }, |
210 | arrow: { | 213 | arrow: { |
211 | color: alpha('#212121', 0.93), | 214 | color: alpha('#212121', 0.93), |