mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-13 01:55:53 +00:00
Finally figured out a way to make typescript strongly type translation keys so we can avoid the tedium of creating enums of translation keys.
80 lines
2.4 KiB
TypeScript
80 lines
2.4 KiB
TypeScript
// SPDX-License-Identifier: MIT
|
|
// Copyright (c) 2022 The Pybricks Authors
|
|
|
|
import { Classes } from '@blueprintjs/core';
|
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
import { OverlayContainer } from 'react-aria';
|
|
import { useBoolean } from 'usehooks-ts';
|
|
import { Button } from './Button';
|
|
import HelpDialog from './HelpDialog';
|
|
import { useI18n } from './i18n';
|
|
|
|
type HelpButtonProps = {
|
|
/** The label of the control this button provides help for. */
|
|
helpForLabel: string;
|
|
/** The help dialog content. */
|
|
content: React.ReactNode;
|
|
};
|
|
|
|
const HelpButton: React.VoidFunctionComponent<HelpButtonProps> = ({
|
|
helpForLabel,
|
|
content,
|
|
}) => {
|
|
const i18n = useI18n();
|
|
|
|
const {
|
|
value: isDialogOpen,
|
|
setTrue: setIsDialogOpenTrue,
|
|
setFalse: setIsDialogOpenFalse,
|
|
} = useBoolean(false);
|
|
|
|
const [isDialogMounted, setIsDialogMounted] = useState(false);
|
|
|
|
// isDialogMounted=true is triggered on isDialogOpen==true rising edge
|
|
useEffect(() => {
|
|
if (isDialogOpen) {
|
|
setIsDialogMounted(true);
|
|
}
|
|
}, [isDialogOpen, setIsDialogMounted]);
|
|
|
|
// isDialogMounted=false is triggered when isDialogOpen==false and the animation ends
|
|
const handleAnimationEnd = useCallback(() => {
|
|
if (!isDialogOpen) {
|
|
setIsDialogMounted(false);
|
|
}
|
|
}, [isDialogOpen, setIsDialogMounted]);
|
|
|
|
const [openButton, setOpenButton] = useState<HTMLButtonElement | null>(null);
|
|
|
|
return (
|
|
<>
|
|
<Button
|
|
label={i18n.translate('helpButton.label')}
|
|
hideLabel
|
|
description={i18n.translate('helpButton.description', {
|
|
helpForLabel,
|
|
})}
|
|
minimal
|
|
icon="help"
|
|
elementRef={setOpenButton}
|
|
onPress={setIsDialogOpenTrue}
|
|
/>
|
|
{isDialogMounted && (
|
|
<OverlayContainer className={Classes.PORTAL}>
|
|
<HelpDialog
|
|
title={i18n.translate('helpDialog.title')}
|
|
isOpen={isDialogOpen}
|
|
openButton={openButton}
|
|
onClose={setIsDialogOpenFalse}
|
|
onAnimationEnd={handleAnimationEnd}
|
|
>
|
|
{content}
|
|
</HelpDialog>
|
|
</OverlayContainer>
|
|
)}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default HelpButton;
|