admin: clearer tooltip for toggle-buttons

Massimo Melina committed Feb 23, 2024 at 15:18 UTC c30d407f0b1453d35fd85149288e9608013dfb24
2 files changed +12 -10
admin/src/LogsPage.ts
+1 -2
@@ -84,8 +84,7 @@ function LogFile({ file, addToFooter, hidden }: { hidden?: boolean, file: string
84 const [showCountry, setShowCountry] = useState(false)
85 const [showAgent, setShowAgent] = useState(false)
86 const { pause, pauseButton } = usePauseButton()
87 - const [showApi, showApiButton] = useToggleButton(v => ({
88 - title: "Show/hide APIs",
87 + const [showApi, showApiButton] = useToggleButton("Show APIs", "Hide APIs", v => ({
88 icon: SmartToy,
89 sx: { rotate: v ? '0deg' : '180deg' },
90 disabled: file === 'console',
admin/src/mui.ts
+11 -8
@@ -3,8 +3,10 @@
3
4 import { PauseCircle, PlayCircle, Refresh, SvgIconComponent } from '@mui/icons-material'
5 import { SxProps } from '@mui/system'
6 -import { createElement as h, FC, forwardRef, Fragment, ReactElement, ReactNode, useCallback, useEffect, useRef,
7 - ForwardedRef, useState } from 'react'
6 +import {
7 + createElement as h, FC, forwardRef, Fragment, ReactElement, ReactNode, useCallback, useEffect, useRef,
8 + ForwardedRef, useState, useMemo
9 +} from 'react'
10 import { Box, BoxProps, Breakpoint, ButtonProps, CircularProgress, IconButton, IconButtonProps, Link, LinkProps,
11 Tooltip, TooltipProps, useMediaQuery } from '@mui/material'
12 import { formatPerc, isIpLan, isIpLocalHost, prefix, WIKI_URL } from '../../src/cross'
@@ -264,27 +266,28 @@ export function LinkBtn({ ...rest }: LinkProps) {
266 }
267
268 export function usePauseButton(props?: Partial<IconBtnProps>) {
267 - const [go, btn] = useToggleButton(v => ({
268 - title: "Pause",
269 + const [going, btn] = useToggleButton("Pause", "Play", v => ({
270 icon: v ? PauseCircle : PlayCircle,
271 sx: { rotate: v ? '180deg' : '0deg' },
272 ...props,
273 }), true)
273 - return { pause: !go, pauseButton: btn }
274 + return { pause: !going, pauseButton: btn }
275 }
276
276 -export function useToggleButton(iconBtn: (state:boolean) => Omit<IconBtnProps, 'onClick'>, def=false) {
277 +export function useToggleButton(onTitle: string, offTitle: undefined | string, iconBtn: (state:boolean) => Omit<IconBtnProps, 'onClick'>, def=false) {
278 const [state, setState] = useState(def)
279 const toggle = useCallback(() => setState(x => !x), [])
280 const props = iconBtn(state)
280 - const el = h(IconBtn, {
281 + const el = useMemo(() => h(IconBtn, {
282 size: 'small',
283 color: state ? 'primary' : 'default',
284 + title: state || offTitle === undefined ? onTitle : offTitle,
285 + 'aria-label': onTitle, // aria should be steady, and rely on aria-pressed
286 'aria-pressed': state,
287 ...props,
288 sx: { transition: 'all .5s', ...props.sx },
289 onClick: toggle,
287 - })
290 + }), [state]) // memoize or tooltip flickers on mouse-over
291 return [state, el] as const
292 }
293