diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-05-02 14:15:35 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-05-05 11:11:04 +0200 |
| commit | 08534a39b3eeff62a206a2409af2f3e6b69aa95b (patch) | |
| tree | bbafcd0c7b642703591bf62f2d2622bafff5a004 | |
| parent | 7325107e01d8ff4c9cd405de36ccaa254d4e40c8 (diff) | |
| download | mullvadvpn-08534a39b3eeff62a206a2409af2f3e6b69aa95b.tar.xz mullvadvpn-08534a39b3eeff62a206a2409af2f3e6b69aa95b.zip | |
Add info button and info dialog components
| -rw-r--r-- | gui/src/renderer/components/AriaGroup.tsx | 13 | ||||
| -rw-r--r-- | gui/src/renderer/components/InfoButton.tsx | 65 |
2 files changed, 77 insertions, 1 deletions
diff --git a/gui/src/renderer/components/AriaGroup.tsx b/gui/src/renderer/components/AriaGroup.tsx index bf5b2d7439..9f7755cb6a 100644 --- a/gui/src/renderer/components/AriaGroup.tsx +++ b/gui/src/renderer/components/AriaGroup.tsx @@ -29,11 +29,15 @@ export function AriaControlGroup(props: IAriaGroupProps) { } interface IAriaDescriptionContext { + describedId: string; descriptionId?: string; setHasDescription: (value: boolean) => void; } const AriaDescriptionContext = React.createContext<IAriaDescriptionContext>({ + get describedId(): string { + throw new Error('Missing AriaDescriptionContext.Provider'); + }, setHasDescription(_value) { throw new Error('Missing AriaDescriptionContext.Provider'); }, @@ -45,6 +49,7 @@ export function AriaDescriptionGroup(props: IAriaGroupProps) { const contextValue = useMemo( () => ({ + describedId: `${id}-described`, descriptionId: hasDescription ? `${id}-description` : undefined, setHasDescription, }), @@ -137,9 +142,10 @@ export function AriaLabel(props: IAriaElementProps) { } export function AriaDescribed(props: IAriaElementProps) { - const { descriptionId } = useContext(AriaDescriptionContext); + const { describedId, descriptionId } = useContext(AriaDescriptionContext); return React.cloneElement(props.children, { + id: describedId, 'aria-describedby': descriptionId, }); } @@ -156,3 +162,8 @@ export function AriaDescription(props: IAriaElementProps) { id: descriptionId, }); } + +export function AriaDetails(props: IAriaElementProps) { + const { describedId } = useContext(AriaDescriptionContext); + return React.cloneElement(props.children, { 'aria-details': describedId }); +} diff --git a/gui/src/renderer/components/InfoButton.tsx b/gui/src/renderer/components/InfoButton.tsx new file mode 100644 index 0000000000..52d92e18d6 --- /dev/null +++ b/gui/src/renderer/components/InfoButton.tsx @@ -0,0 +1,65 @@ +import styled from 'styled-components'; + +import { colors } from '../../config.json'; +import { messages } from '../../shared/gettext'; +import { useBoolean } from '../lib/utilityHooks'; +import * as AppButton from './AppButton'; +import ImageView from './ImageView'; +import { ModalAlert, ModalAlertType } from './Modal'; + +const StyledInfoButton = styled.button({ + margin: '0 16px 0 0', + borderWidth: 0, + padding: 0, + cursor: 'default', + backgroundColor: 'transparent', +}); + +interface IInfoIconProps { + className?: string; +} + +export function InfoIcon(props: IInfoIconProps) { + return ( + <ImageView + source="icon-info" + width={18} + tintColor={colors.white} + tintHoverColor={colors.white80} + className={props.className} + /> + ); +} + +interface IInfoButtonProps extends React.HTMLAttributes<HTMLButtonElement> { + message?: string; + children?: React.ReactNode; +} + +export default function InfoButton(props: IInfoButtonProps) { + const { message, children, ...otherProps } = props; + const [isOpen, show, hide] = useBoolean(false); + + return ( + <> + <StyledInfoButton + onClick={show} + aria-label={messages.pgettext('accessibility', 'More information')} + {...otherProps}> + <InfoIcon /> + </StyledInfoButton> + <ModalAlert + isOpen={isOpen} + message={props.message} + type={ModalAlertType.info} + buttons={[ + <AppButton.BlueButton key="back" onClick={hide}> + {messages.gettext('Got it!')} + </AppButton.BlueButton>, + ]} + close={hide}> + {props.children} + </ModalAlert> + </> + ); +} |
