mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 01:23:52 +00:00
settings: change tooltips to help buttons
This is more friendly for touch screen users.
This commit is contained in:
+78
-56
@@ -7,25 +7,26 @@ import {
|
||||
ButtonGroup,
|
||||
ControlGroup,
|
||||
FormGroup,
|
||||
IRef,
|
||||
Icon,
|
||||
InputGroup,
|
||||
Intent,
|
||||
Label,
|
||||
Switch,
|
||||
} from '@blueprintjs/core';
|
||||
import { Tooltip2 } from '@blueprintjs/popover2';
|
||||
import { Classes as Classes2, Popover2 } from '@blueprintjs/popover2';
|
||||
import { useI18n } from '@shopify/react-i18n';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useTernaryDarkMode } from 'usehooks-ts';
|
||||
import AboutDialog from '../about/AboutDialog';
|
||||
import { appCheckForUpdate, appReload, appShowInstallPrompt } from '../app/actions';
|
||||
import {
|
||||
appName,
|
||||
pybricksBugReportsUrl,
|
||||
pybricksGitterUrl,
|
||||
pybricksProjectsUrl,
|
||||
pybricksSupportUrl,
|
||||
tooltipDelay,
|
||||
} from '../app/constants';
|
||||
import { pseudolocalize } from '../i18n';
|
||||
import { useSelector } from '../reducers';
|
||||
@@ -39,6 +40,43 @@ import {
|
||||
import { I18nId } from './i18n';
|
||||
import './settings.scss';
|
||||
|
||||
type HelpButtonProps = {
|
||||
label: string;
|
||||
content: string | JSX.Element;
|
||||
};
|
||||
|
||||
const HelpButton: React.VoidFunctionComponent<HelpButtonProps> = ({
|
||||
label,
|
||||
content,
|
||||
}) => {
|
||||
const handleOpening = useCallback((node: HTMLElement) => {
|
||||
// role must match aria-haspopup
|
||||
node.setAttribute('role', 'dialog');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Popover2
|
||||
onOpening={handleOpening}
|
||||
placement="right"
|
||||
shouldReturnFocusOnClose
|
||||
popoverClassName={Classes2.POPOVER2_CONTENT_SIZING}
|
||||
content={content}
|
||||
renderTarget={({ isOpen, ref, ...targetProps }) => (
|
||||
<Button
|
||||
aria-label={label}
|
||||
aria-expanded={isOpen}
|
||||
minimal
|
||||
icon="help"
|
||||
elementRef={ref as IRef<HTMLButtonElement>}
|
||||
{...targetProps}
|
||||
// override targetProps
|
||||
aria-haspopup="dialog"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const Settings: React.VoidFunctionComponent = () => {
|
||||
const { isSettingShowDocsEnabled, setIsSettingShowDocsEnabled } =
|
||||
useSettingIsShowDocsEnabled();
|
||||
@@ -65,7 +103,7 @@ const Settings: React.VoidFunctionComponent = () => {
|
||||
const [i18n] = useI18n();
|
||||
|
||||
return (
|
||||
<div aria-label={i18n.translate(I18nId.Title)}>
|
||||
<div className="pb-settings" aria-label={i18n.translate(I18nId.Title)}>
|
||||
<FormGroup
|
||||
label={i18n.translate(I18nId.AppearanceTitle)}
|
||||
helperText={i18n.translate(I18nId.AppearanceZoomHelp, {
|
||||
@@ -73,13 +111,7 @@ const Settings: React.VoidFunctionComponent = () => {
|
||||
out: <span>{isMacOS() ? 'Cmd' : 'Ctrl'}--</span>,
|
||||
})}
|
||||
>
|
||||
<Tooltip2
|
||||
content={i18n.translate(I18nId.AppearanceDocumentationTooltip)}
|
||||
rootBoundary="document"
|
||||
placement="left"
|
||||
targetTagName="div"
|
||||
hoverOpenDelay={tooltipDelay}
|
||||
>
|
||||
<ControlGroup>
|
||||
<Switch
|
||||
label={i18n.translate(I18nId.AppearanceDocumentationLabel)}
|
||||
checked={isSettingShowDocsEnabled}
|
||||
@@ -89,14 +121,14 @@ const Settings: React.VoidFunctionComponent = () => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Tooltip2>
|
||||
<Tooltip2
|
||||
content={i18n.translate(I18nId.AppearanceDarkModeTooltip)}
|
||||
rootBoundary="document"
|
||||
placement="left"
|
||||
targetTagName="div"
|
||||
hoverOpenDelay={tooltipDelay}
|
||||
>
|
||||
<HelpButton
|
||||
label={i18n.translate(I18nId.AppearanceDocumentationHelpLabel)}
|
||||
content={i18n.translate(
|
||||
I18nId.AppearanceDocumentationHelpContent,
|
||||
)}
|
||||
/>
|
||||
</ControlGroup>
|
||||
<ControlGroup>
|
||||
<Switch
|
||||
label={i18n.translate(I18nId.AppearanceDarkModeLabel)}
|
||||
checked={isDarkMode}
|
||||
@@ -108,16 +140,14 @@ const Settings: React.VoidFunctionComponent = () => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Tooltip2>
|
||||
<HelpButton
|
||||
label={i18n.translate(I18nId.AppearanceDarkModeHelpLabel)}
|
||||
content={i18n.translate(I18nId.AppearanceDarkModeHelpContent)}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
<FormGroup label={i18n.translate(I18nId.FirmwareTitle)}>
|
||||
<Tooltip2
|
||||
content={i18n.translate(I18nId.FirmwareCurrentProgramTooltip)}
|
||||
rootBoundary="document"
|
||||
placement="left"
|
||||
targetTagName="div"
|
||||
hoverOpenDelay={tooltipDelay}
|
||||
>
|
||||
<ControlGroup>
|
||||
<Switch
|
||||
label={i18n.translate(I18nId.FirmwareCurrentProgramLabel)}
|
||||
checked={isFlashCurrentProgramEnabled}
|
||||
@@ -127,47 +157,39 @@ const Settings: React.VoidFunctionComponent = () => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Tooltip2>
|
||||
<ControlGroup vertical={true}>
|
||||
<Tooltip2
|
||||
content={i18n.translate(I18nId.FirmwareHubNameTooltip)}
|
||||
rootBoundary="document"
|
||||
placement="left"
|
||||
targetTagName="div"
|
||||
hoverOpenDelay={tooltipDelay}
|
||||
openOnTargetFocus={false}
|
||||
>
|
||||
<Label htmlFor="hub-name-input">
|
||||
{i18n.translate(I18nId.FirmwareHubNameLabel)}
|
||||
</Label>
|
||||
</Tooltip2>
|
||||
<HelpButton
|
||||
label={i18n.translate(I18nId.FirmwareCurrentProgramHelpLabel)}
|
||||
content={i18n.translate(
|
||||
I18nId.FirmwareCurrentProgramHelpContent,
|
||||
{ appName },
|
||||
)}
|
||||
/>
|
||||
</ControlGroup>
|
||||
<Label htmlFor="hub-name-input">
|
||||
{i18n.translate(I18nId.FirmwareHubNameLabel)}
|
||||
</Label>
|
||||
<ControlGroup>
|
||||
<InputGroup
|
||||
id="hub-name-input"
|
||||
value={hubName}
|
||||
onChange={(e) => setHubName(e.currentTarget.value)}
|
||||
onMouseOver={(e) => e.preventDefault()}
|
||||
className="pb-hub-name-input"
|
||||
intent={isHubNameValid ? Intent.NONE : Intent.DANGER}
|
||||
placeholder="Pybricks Hub"
|
||||
rightElement={
|
||||
isHubNameValid ? undefined : (
|
||||
<Tooltip2
|
||||
content={i18n.translate(
|
||||
I18nId.FirmwareHubNameErrorTooltip,
|
||||
)}
|
||||
rootBoundary="document"
|
||||
placement="bottom"
|
||||
targetTagName="div"
|
||||
>
|
||||
<Icon
|
||||
icon="error"
|
||||
intent={Intent.DANGER}
|
||||
itemType="div"
|
||||
/>
|
||||
</Tooltip2>
|
||||
<Icon
|
||||
icon="error"
|
||||
intent={Intent.DANGER}
|
||||
itemType="div"
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<HelpButton
|
||||
label={i18n.translate(I18nId.FirmwareHubNameHelpLabel)}
|
||||
content={i18n.translate(I18nId.FirmwareHubNameHelpContent)}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
<FormGroup label={i18n.translate(I18nId.HelpTitle)}>
|
||||
|
||||
+12
-8
@@ -7,16 +7,20 @@ export enum I18nId {
|
||||
Title = 'title',
|
||||
AppearanceTitle = 'appearance.title',
|
||||
AppearanceDocumentationLabel = 'appearance.documentation.label',
|
||||
AppearanceDocumentationTooltip = 'appearance.documentation.tooltip',
|
||||
AppearanceDarkModeLabel = 'appearance.dark-mode.label',
|
||||
AppearanceDarkModeTooltip = 'appearance.dark-mode.tooltip',
|
||||
AppearanceDocumentationHelpLabel = 'appearance.documentation.help.label',
|
||||
AppearanceDocumentationHelpContent = 'appearance.documentation.help.content',
|
||||
AppearanceDarkModeLabel = 'appearance.darkMode.label',
|
||||
AppearanceDarkModeHelpLabel = 'appearance.darkMode.help.label',
|
||||
AppearanceDarkModeHelpContent = 'appearance.darkMode.help.content',
|
||||
AppearanceZoomHelp = 'appearance.zoom.help',
|
||||
FirmwareTitle = 'firmware.title',
|
||||
FirmwareCurrentProgramLabel = 'firmware.flash-current-program.label',
|
||||
FirmwareCurrentProgramTooltip = 'firmware.flash-current-program.tooltip',
|
||||
FirmwareHubNameLabel = 'firmware.hub-name.label',
|
||||
FirmwareHubNameTooltip = 'firmware.hub-name.tooltip',
|
||||
FirmwareHubNameErrorTooltip = 'firmware.hub-name.error.tooltip',
|
||||
FirmwareCurrentProgramLabel = 'firmware.flashCurrentProgram.label',
|
||||
FirmwareCurrentProgramHelpLabel = 'firmware.flashCurrentProgram.help.label',
|
||||
FirmwareCurrentProgramHelpContent = 'firmware.flashCurrentProgram.help.content',
|
||||
FirmwareHubNameLabel = 'firmware.hubName.label',
|
||||
FirmwareHubNameHelpLabel = 'firmware.hubName.help.label',
|
||||
FirmwareHubNameHelpContent = 'firmware.hubName.help.content',
|
||||
FirmwareHubNameError = 'firmware.hubName.error',
|
||||
HelpTitle = 'help.title',
|
||||
HelpProjectsLabel = 'help.projects.label',
|
||||
HelpSupportLabel = 'help.support.label',
|
||||
|
||||
@@ -5,7 +5,14 @@
|
||||
|
||||
@use '@blueprintjs/core/lib/scss/variables' as bp;
|
||||
|
||||
.pb-hub-name-input .#{bp.$ns}-input {
|
||||
width: 200px;
|
||||
margin-left: 8px;
|
||||
.pb-settings {
|
||||
.#{bp.$ns}-control-group {
|
||||
.#{bp.$ns}-button {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.#{bp.$ns}-input-group {
|
||||
width: bp.$pt-grid-size * 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,17 @@
|
||||
"title": "Appearance",
|
||||
"documentation": {
|
||||
"label": "Documentation",
|
||||
"tooltip": "Show or hide the documentation pane."
|
||||
"help": {
|
||||
"label": "Show help for documentation toggle.",
|
||||
"content": "Enable to show the documentation and disable to hide the documentation."
|
||||
}
|
||||
},
|
||||
"dark-mode": {
|
||||
"darkMode": {
|
||||
"label": "Dark mode",
|
||||
"tooltip": "Enable or disable dark mode."
|
||||
"help": {
|
||||
"label": "Show help for dark mode toggle.",
|
||||
"content": "Enable to set theme to dark mode and disable to set theme to light mode."
|
||||
}
|
||||
},
|
||||
"zoom": {
|
||||
"help": "Use {in} and {out} to zoom."
|
||||
@@ -16,16 +22,20 @@
|
||||
},
|
||||
"firmware": {
|
||||
"title": "Firmware",
|
||||
"flash-current-program": {
|
||||
"flashCurrentProgram": {
|
||||
"label": "Include current program",
|
||||
"tooltip": "Select to include your program when installing the firmware."
|
||||
},
|
||||
"hub-name": {
|
||||
"label": "Hub name",
|
||||
"tooltip": "Hub name to use when flashing the firmware.",
|
||||
"error": {
|
||||
"tooltip": "The name is too long."
|
||||
"help": {
|
||||
"label": "Show help for include current program toggle.",
|
||||
"content": "Enable to include your program when flashing the firmware or disable to use the default program. Flashing your program along with the firmware will allow you to run your program without being connected to {appName}"
|
||||
}
|
||||
},
|
||||
"hubName": {
|
||||
"label": "Hub name",
|
||||
"help": {
|
||||
"label": "Show help on hub name input",
|
||||
"content": "Enter a name here to customize the hub name when flashing the firmware. This name will be used in the Bluetooth advertising data and can be used to identify the hub when connecting."
|
||||
},
|
||||
"error": "The name is too long."
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
|
||||
Reference in New Issue
Block a user