1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-06 00:07:44 +01:00
unleash.unleash/frontend/src/component/common/FormTemplate/FormTemplate.tsx
olav ff0d55b6cc fix: improve HTML landmarks (#886)
* fix: improve HTML landmarks

* refactor: footer headers should use h2

* refactor: fix header order on the feature overview page

* fix: make drawer logo clickable

* fix: wrap header links in <nav>

* fix: label breadcrumbs nav element

* refactor: remove unused breadcrumb.jsx

* fix: add search role to SearchField

* fix: correct heading order on form pages
2022-04-21 09:52:43 +02:00

191 lines
5.8 KiB
TypeScript

import { useStyles } from './FormTemplate.styles';
import MenuBookIcon from '@material-ui/icons/MenuBook';
import Codebox from '../Codebox/Codebox';
import {
Collapse,
IconButton,
useMediaQuery,
Tooltip,
} from '@material-ui/core';
import { FileCopy, Info } from '@material-ui/icons';
import ConditionallyRender from '../ConditionallyRender';
import Loader from '../Loader/Loader';
import copy from 'copy-to-clipboard';
import useToast from 'hooks/useToast';
import React, { useState } from 'react';
import classNames from 'classnames';
import { ReactComponent as MobileGuidanceBG } from 'assets/img/mobileGuidanceBg.svg';
import { useCommonStyles } from 'themes/commonStyles';
interface ICreateProps {
title: string;
description: string;
documentationLink: string;
documentationLinkLabel?: string;
loading?: boolean;
modal?: boolean;
formatApiCode: () => string;
}
const FormTemplate: React.FC<ICreateProps> = ({
title,
description,
children,
documentationLink,
documentationLinkLabel,
loading,
modal,
formatApiCode,
}) => {
const { setToastData } = useToast();
const styles = useStyles();
const commonStyles = useCommonStyles();
const smallScreen = useMediaQuery(`(max-width:${1099}px)`);
const copyCommand = () => {
if (copy(formatApiCode())) {
setToastData({
title: 'Successfully copied the command',
text: 'The command should now be automatically copied to your clipboard',
autoHideDuration: 6000,
type: 'success',
show: true,
});
} else {
setToastData({
title: 'Could not copy the command',
text: 'Sorry, but we could not copy the command.',
autoHideDuration: 6000,
type: 'error',
show: true,
});
}
};
return (
<section
className={classNames(styles.container, modal && styles.modal)}
>
<ConditionallyRender
condition={smallScreen}
show={
<div className={commonStyles.relative}>
<MobileGuidance
description={description}
documentationLink={documentationLink}
documentationLinkLabel={documentationLinkLabel}
/>
</div>
}
/>
<div className={styles.formContent}>
<ConditionallyRender
condition={loading || false}
show={<Loader />}
elseShow={
<>
<h1 className={styles.title}>{title}</h1>
{children}
</>
}
/>{' '}
</div>
<ConditionallyRender
condition={!smallScreen}
show={
<Guidance
description={description}
documentationLink={documentationLink}
documentationLinkLabel={documentationLinkLabel}
>
<h2 className={styles.subtitle}>
API Command{' '}
<Tooltip title="Copy command">
<IconButton onClick={copyCommand}>
<FileCopy className={styles.icon} />
</IconButton>
</Tooltip>
</h2>
<Codebox text={formatApiCode()} />
</Guidance>
}
/>
</section>
);
};
interface IMobileGuidance {
description: string;
documentationLink: string;
documentationLinkLabel?: string;
}
const MobileGuidance = ({
description,
documentationLink,
documentationLinkLabel,
}: IMobileGuidance) => {
const [open, setOpen] = useState(false);
const styles = useStyles();
return (
<>
<div className={styles.mobileGuidanceBgContainer}>
<MobileGuidanceBG className={styles.mobileGuidanceBackground} />
</div>
<Tooltip title="Toggle help">
<IconButton
className={styles.mobileGuidanceButton}
onClick={() => setOpen(prev => !prev)}
>
<Info className={styles.infoIcon} />
</IconButton>
</Tooltip>
<Collapse in={open} timeout={500}>
<Guidance
description={description}
documentationLink={documentationLink}
documentationLinkLabel={documentationLinkLabel}
/>
</Collapse>
</>
);
};
interface IGuidanceProps {
description: string;
documentationLink: string;
documentationLinkLabel?: string;
}
const Guidance: React.FC<IGuidanceProps> = ({
description,
children,
documentationLink,
documentationLinkLabel = 'Learn more',
}) => {
const styles = useStyles();
return (
<aside className={styles.sidebar}>
<p className={styles.description}>{description}</p>
<div className={styles.linkContainer}>
<MenuBookIcon className={styles.linkIcon} />
<a
className={styles.documentationLink}
href={documentationLink}
rel="noopener noreferrer"
target="_blank"
>
{documentationLinkLabel}
</a>
</div>
{children}
</aside>
);
};
export default FormTemplate;