mirror of
https://github.com/checktheroads/hyperglass
synced 2024-05-11 05:55:08 +00:00
continue typescript & chakra-ui 1.0 migrations
This commit is contained in:
@@ -1,26 +1,26 @@
|
||||
import * as React from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Flex, useColorMode } from '@chakra-ui/core';
|
||||
import { Box, Flex } from '@chakra-ui/core';
|
||||
import { FiCode } from '@meronex/icons/fi';
|
||||
import { GoLinkExternal } from '@meronex/icons/go';
|
||||
import format from 'string-format';
|
||||
import { useConfig } from 'app/context';
|
||||
import stringFormat from 'string-format';
|
||||
import { useConfig, useColorValue } from '~/context';
|
||||
import { FooterButton } from './FooterButton';
|
||||
import { FooterContent } from './FooterContent';
|
||||
|
||||
format.extend(String.prototype, {});
|
||||
|
||||
const footerBg = { light: 'blackAlpha.50', dark: 'whiteAlpha.100' };
|
||||
const footerColor = { light: 'black', dark: 'white' };
|
||||
const contentBorder = { light: 'blackAlpha.100', dark: 'whiteAlpha.200' };
|
||||
import type { TFooterItems } from './types';
|
||||
|
||||
export const Footer = () => {
|
||||
const config = useConfig();
|
||||
const { colorMode } = useColorMode();
|
||||
const [helpVisible, showHelp] = useState(false);
|
||||
const [termsVisible, showTerms] = useState(false);
|
||||
const [creditVisible, showCredit] = useState(false);
|
||||
const handleCollapse = i => {
|
||||
|
||||
const footerBg = useColorValue('blackAlpha.50', 'whiteAlpha.100');
|
||||
const footerColor = useColorValue('black', 'white');
|
||||
const contentBorder = useColorValue('blackAlpha.100', 'whiteAlpha.200');
|
||||
|
||||
const handleCollapse = (i: TFooterItems) => {
|
||||
if (i === 'help') {
|
||||
showTerms(false);
|
||||
showCredit(false);
|
||||
@@ -35,18 +35,19 @@ export const Footer = () => {
|
||||
showTerms(!termsVisible);
|
||||
}
|
||||
};
|
||||
|
||||
const extUrl = config.web.external_link.url.includes('{primary_asn}')
|
||||
? config.web.external_link.url.format({ primary_asn: config.primary_asn })
|
||||
? stringFormat(config.web.external_link.url, { primary_asn: config.primary_asn })
|
||||
: config.web.external_link.url || '/';
|
||||
|
||||
return (
|
||||
<>
|
||||
{config.web.help_menu.enable && (
|
||||
<FooterContent
|
||||
isOpen={helpVisible}
|
||||
content={config.content.help_menu}
|
||||
title={config.web.help_menu.title}
|
||||
bg={footerBg[colorMode]}
|
||||
borderColor={contentBorder[colorMode]}
|
||||
bg={footerBg}
|
||||
borderColor={contentBorder}
|
||||
side="left"
|
||||
/>
|
||||
)}
|
||||
@@ -54,9 +55,8 @@ export const Footer = () => {
|
||||
<FooterContent
|
||||
isOpen={termsVisible}
|
||||
content={config.content.terms}
|
||||
title={config.web.terms.title}
|
||||
bg={footerBg[colorMode]}
|
||||
borderColor={contentBorder[colorMode]}
|
||||
bg={footerBg}
|
||||
borderColor={contentBorder}
|
||||
side="left"
|
||||
/>
|
||||
)}
|
||||
@@ -64,9 +64,8 @@ export const Footer = () => {
|
||||
<FooterContent
|
||||
isOpen={creditVisible}
|
||||
content={config.content.credit}
|
||||
title={config.web.credit.title}
|
||||
bg={footerBg[colorMode]}
|
||||
borderColor={contentBorder[colorMode]}
|
||||
bg={footerBg}
|
||||
borderColor={contentBorder}
|
||||
side="right"
|
||||
/>
|
||||
)}
|
||||
@@ -78,8 +77,8 @@ export const Footer = () => {
|
||||
flexWrap="wrap"
|
||||
textAlign="center"
|
||||
alignItems="center"
|
||||
bg={footerBg[colorMode]}
|
||||
color={footerColor[colorMode]}
|
||||
bg={footerBg}
|
||||
color={footerColor}
|
||||
justifyContent="space-between">
|
||||
{config.web.terms.enable && (
|
||||
<FooterButton
|
||||
@@ -115,13 +114,11 @@ export const Footer = () => {
|
||||
)}
|
||||
{config.web.external_link.enable && (
|
||||
<FooterButton
|
||||
as="a"
|
||||
href={extUrl}
|
||||
side="right"
|
||||
aria-label={config.web.external_link.title}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
variant="ghost"
|
||||
rightIcon={GoLinkExternal}
|
||||
rightIcon={<Box as={GoLinkExternal} />}
|
||||
size="xs">
|
||||
{config.web.external_link.title}
|
||||
</FooterButton>
|
@@ -1,26 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Button, Flex } from '@chakra-ui/core';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
const AnimatedFlex = motion.custom(Flex);
|
||||
|
||||
export const FooterButton = React.forwardRef(({ onClick, side, children, ...props }, ref) => {
|
||||
return (
|
||||
<AnimatedFlex
|
||||
p={0}
|
||||
w="auto"
|
||||
ref={ref}
|
||||
flexGrow={0}
|
||||
float={side}
|
||||
flexShrink={0}
|
||||
maxWidth="100%"
|
||||
flexBasis="auto"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6 }}>
|
||||
<Button size="xs" variant="ghost" onClick={onClick} {...props}>
|
||||
{children}
|
||||
</Button>
|
||||
</AnimatedFlex>
|
||||
);
|
||||
});
|
32
hyperglass/ui/components/Footer/FooterButton.tsx
Normal file
32
hyperglass/ui/components/Footer/FooterButton.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import * as React from 'react';
|
||||
import { Button, Flex, FlexProps } from '@chakra-ui/core';
|
||||
import { withAnimation } from '~/components';
|
||||
|
||||
import type { IFooterButton } from './types';
|
||||
|
||||
const AnimatedFlex = withAnimation<FlexProps>(Flex);
|
||||
|
||||
export const FooterButton = (props: IFooterButton) => {
|
||||
const { side, href, ...rest } = props;
|
||||
|
||||
let buttonProps = Object();
|
||||
if (typeof href !== 'undefined') {
|
||||
buttonProps = { href, as: 'a', target: '_blank', rel: 'noopener noreferrer' };
|
||||
}
|
||||
|
||||
return (
|
||||
<AnimatedFlex
|
||||
p={0}
|
||||
w="auto"
|
||||
flexGrow={0}
|
||||
float={side}
|
||||
flexShrink={0}
|
||||
maxWidth="100%"
|
||||
flexBasis="auto"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6 }}>
|
||||
<Button size="xs" variant="ghost" {...buttonProps} {...rest} />
|
||||
</AnimatedFlex>
|
||||
);
|
||||
};
|
@@ -1,27 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import { Box, Collapse } from '@chakra-ui/core';
|
||||
import { Markdown } from 'app/components/Markdown';
|
||||
|
||||
export const FooterContent = forwardRef(
|
||||
({ isOpen = false, content, side = 'left', title, ...props }, ref) => {
|
||||
return (
|
||||
<Collapse
|
||||
px={6}
|
||||
py={4}
|
||||
w="auto"
|
||||
ref={ref}
|
||||
borderBottom="1px"
|
||||
display="flex"
|
||||
maxWidth="100%"
|
||||
isOpen={isOpen}
|
||||
flexBasis="auto"
|
||||
justifyContent={side === 'left' ? 'flex-start' : 'flex-end'}
|
||||
{...props}>
|
||||
<Box textAlign={side}>
|
||||
<Markdown content={content} />
|
||||
</Box>
|
||||
</Collapse>
|
||||
);
|
||||
},
|
||||
);
|
27
hyperglass/ui/components/Footer/FooterContent.tsx
Normal file
27
hyperglass/ui/components/Footer/FooterContent.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import * as React from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import { Box, Collapse } from '@chakra-ui/core';
|
||||
import { Markdown } from '~/components';
|
||||
|
||||
import type { IFooterContent } from './types';
|
||||
|
||||
export const FooterContent = (props: IFooterContent) => {
|
||||
const { isOpen = false, content, side = 'left', children: _, ...rest } = props;
|
||||
return (
|
||||
<Collapse
|
||||
px={6}
|
||||
py={4}
|
||||
w="auto"
|
||||
borderBottom="1px"
|
||||
display="flex"
|
||||
maxWidth="100%"
|
||||
isOpen={isOpen}
|
||||
flexBasis="auto"
|
||||
justifyContent={side === 'left' ? 'flex-start' : 'flex-end'}
|
||||
{...rest}>
|
||||
<Box textAlign={side}>
|
||||
<Markdown content={content} />
|
||||
</Box>
|
||||
</Collapse>
|
||||
);
|
||||
};
|
17
hyperglass/ui/components/Footer/types.ts
Normal file
17
hyperglass/ui/components/Footer/types.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { FlexProps, ButtonProps, CollapseProps } from '@chakra-ui/core';
|
||||
|
||||
type TFooterSide = 'left' | 'right';
|
||||
|
||||
export interface IFooterButton extends ButtonProps {
|
||||
side: TFooterSide;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
export interface IFooterContent extends Omit<CollapseProps, 'children'> {
|
||||
isOpen: boolean;
|
||||
content: string;
|
||||
side: TFooterSide;
|
||||
children?: undefined;
|
||||
}
|
||||
|
||||
export type TFooterItems = 'help' | 'credit' | 'terms';
|
@@ -1,60 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Checkbox as ChakraCheckbox,
|
||||
Divider as ChakraDivider,
|
||||
Code as ChakraCode,
|
||||
Heading as ChakraHeading,
|
||||
Link as ChakraLink,
|
||||
List as ChakraList,
|
||||
ListItem as ChakraListItem,
|
||||
Text as ChakraText,
|
||||
} from '@chakra-ui/core';
|
||||
|
||||
import { TableCell, TableHeader, Table as ChakraTable } from './MDTable';
|
||||
|
||||
import { CodeBlock as CustomCodeBlock } from 'app/components';
|
||||
|
||||
export const Checkbox = ({ checked, children }) => (
|
||||
<ChakraCheckbox isChecked={checked}>{children}</ChakraCheckbox>
|
||||
);
|
||||
|
||||
export const List = ({ ordered, children }) => (
|
||||
<ChakraList as={ordered ? 'ol' : 'ul'}>{children}</ChakraList>
|
||||
);
|
||||
|
||||
export const ListItem = ({ checked, children }) =>
|
||||
checked ? (
|
||||
<Checkbox checked={checked}>{children}</Checkbox>
|
||||
) : (
|
||||
<ChakraListItem>{children}</ChakraListItem>
|
||||
);
|
||||
|
||||
export const Heading = ({ level, children }) => {
|
||||
const levelMap = {
|
||||
1: { as: 'h1', size: 'lg', fontWeight: 'bold' },
|
||||
2: { as: 'h2', size: 'lg', fontWeight: 'normal' },
|
||||
3: { as: 'h3', size: 'lg', fontWeight: 'bold' },
|
||||
4: { as: 'h4', size: 'md', fontWeight: 'normal' },
|
||||
5: { as: 'h5', size: 'md', fontWeight: 'bold' },
|
||||
6: { as: 'h6', size: 'sm', fontWeight: 'bold' },
|
||||
};
|
||||
return <ChakraHeading {...levelMap[level]}>{children}</ChakraHeading>;
|
||||
};
|
||||
|
||||
export const Link = ({ children, ...props }) => (
|
||||
<ChakraLink isExternal {...props}>
|
||||
{children}
|
||||
</ChakraLink>
|
||||
);
|
||||
|
||||
export const CodeBlock = ({ value }) => <CustomCodeBlock>{value}</CustomCodeBlock>;
|
||||
|
||||
export const TableData = ({ isHeader, children, ...props }) => {
|
||||
const Component = isHeader ? TableHeader : TableCell;
|
||||
return <Component {...props}>{children}</Component>;
|
||||
};
|
||||
|
||||
export const Paragraph = props => <ChakraText {...props} />;
|
||||
export const InlineCode = props => <ChakraCode {...props} />;
|
||||
export const Divider = props => <ChakraDivider {...props} />;
|
||||
export const Table = props => <ChakraTable {...props} />;
|
63
hyperglass/ui/components/Markdown/MDComponents.tsx
Normal file
63
hyperglass/ui/components/Markdown/MDComponents.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Checkbox as ChakraCheckbox,
|
||||
Divider as ChakraDivider,
|
||||
Code as ChakraCode,
|
||||
Heading as ChakraHeading,
|
||||
Link as ChakraLink,
|
||||
ListItem as ChakraListItem,
|
||||
Text as ChakraText,
|
||||
UnorderedList,
|
||||
OrderedList,
|
||||
} from '@chakra-ui/core';
|
||||
|
||||
import { TableCell, TableHeader, Table as ChakraTable } from './MDTable';
|
||||
|
||||
import { CodeBlock as CustomCodeBlock } from '~/components';
|
||||
|
||||
import type { BoxProps, TextProps, CodeProps, DividerProps, LinkProps } from '@chakra-ui/core';
|
||||
import type { ICheckbox, IList, IHeading, ICodeBlock, ITableData } from './types';
|
||||
|
||||
export const Checkbox = (props: ICheckbox) => {
|
||||
const { checked, ...rest } = props;
|
||||
return <ChakraCheckbox isChecked={checked} {...rest} />;
|
||||
};
|
||||
|
||||
export const List = (props: IList) => {
|
||||
const { ordered, ...rest } = props;
|
||||
const Component = ordered ? OrderedList : UnorderedList;
|
||||
return <Component {...rest} />;
|
||||
};
|
||||
|
||||
export const ListItem = (props: ICheckbox) => {
|
||||
const { checked, ...rest } = props;
|
||||
return checked ? <Checkbox checked={checked} {...rest} /> : <ChakraListItem {...rest} />;
|
||||
};
|
||||
|
||||
export const Heading = (props: IHeading) => {
|
||||
const { level, ...rest } = props;
|
||||
const levelMap = {
|
||||
1: { as: 'h1', size: 'lg', fontWeight: 'bold' },
|
||||
2: { as: 'h2', size: 'lg', fontWeight: 'normal' },
|
||||
3: { as: 'h3', size: 'lg', fontWeight: 'bold' },
|
||||
4: { as: 'h4', size: 'md', fontWeight: 'normal' },
|
||||
5: { as: 'h5', size: 'md', fontWeight: 'bold' },
|
||||
6: { as: 'h6', size: 'sm', fontWeight: 'bold' },
|
||||
};
|
||||
return <ChakraHeading {...levelMap[level]} {...rest} />;
|
||||
};
|
||||
|
||||
export const Link = (props: LinkProps) => <ChakraLink isExternal {...props} />;
|
||||
|
||||
export const CodeBlock = (props: ICodeBlock) => <CustomCodeBlock>{props.value}</CustomCodeBlock>;
|
||||
|
||||
export const TableData = (props: ITableData) => {
|
||||
const { isHeader, ...rest } = props;
|
||||
const Component = isHeader ? TableHeader : TableCell;
|
||||
return <Component {...rest} />;
|
||||
};
|
||||
|
||||
export const Paragraph = (props: TextProps) => <ChakraText {...props} />;
|
||||
export const InlineCode = (props: CodeProps) => <ChakraCode {...props} />;
|
||||
export const Divider = (props: DividerProps) => <ChakraDivider {...props} />;
|
||||
export const Table = (props: BoxProps) => <ChakraTable {...props} />;
|
@@ -1,24 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Box, useColorMode } from '@chakra-ui/core';
|
||||
|
||||
export const Table = props => <Box as="table" textAlign="left" mt={4} width="full" {...props} />;
|
||||
|
||||
const bg = { light: 'blackAlpha.50', dark: 'whiteAlpha.50' };
|
||||
|
||||
export const TableHeader = props => {
|
||||
const { colorMode } = useColorMode();
|
||||
|
||||
return <Box as="th" bg={bg[colorMode]} fontWeight="semibold" p={2} fontSize="sm" {...props} />;
|
||||
};
|
||||
|
||||
export const TableCell = ({ isHeader = false, ...props }) => (
|
||||
<Box
|
||||
as={isHeader ? 'th' : 'td'}
|
||||
p={2}
|
||||
borderTopWidth="1px"
|
||||
borderColor="inherit"
|
||||
fontSize="sm"
|
||||
whiteSpace="normal"
|
||||
{...props}
|
||||
/>
|
||||
);
|
29
hyperglass/ui/components/Markdown/MDTable.tsx
Normal file
29
hyperglass/ui/components/Markdown/MDTable.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import * as React from 'react';
|
||||
import { Box } from '@chakra-ui/core';
|
||||
import { useColorValue } from '~/context';
|
||||
import type { BoxProps } from '@chakra-ui/core';
|
||||
import type { ITableData } from './types';
|
||||
|
||||
export const Table = (props: BoxProps) => (
|
||||
<Box as="table" textAlign="left" mt={4} width="full" {...props} />
|
||||
);
|
||||
|
||||
export const TableHeader = (props: BoxProps) => {
|
||||
const bg = useColorValue('blackAlpha.50', 'whiteAlpha.50');
|
||||
return <Box as="th" bg={bg} fontWeight="semibold" p={2} fontSize="sm" {...props} />;
|
||||
};
|
||||
|
||||
export const TableCell = (props: ITableData) => {
|
||||
const { isHeader = false, ...rest } = props;
|
||||
return (
|
||||
<Box
|
||||
as={isHeader ? 'th' : 'td'}
|
||||
p={2}
|
||||
borderTopWidth="1px"
|
||||
borderColor="inherit"
|
||||
fontSize="sm"
|
||||
whiteSpace="normal"
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
@@ -1,5 +1,4 @@
|
||||
import * as React from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import {
|
||||
List,
|
||||
@@ -14,6 +13,8 @@ import {
|
||||
Table,
|
||||
} from './MDComponents';
|
||||
|
||||
import type { IMarkdown } from './types';
|
||||
|
||||
const mdComponents = {
|
||||
paragraph: Paragraph,
|
||||
link: Link,
|
||||
@@ -27,6 +28,6 @@ const mdComponents = {
|
||||
tableCell: TableData,
|
||||
};
|
||||
|
||||
export const Markdown = forwardRef(({ content }, ref) => (
|
||||
<ReactMarkdown ref={ref} renderers={mdComponents} source={content} />
|
||||
));
|
||||
export const Markdown = (props: IMarkdown) => (
|
||||
<ReactMarkdown renderers={mdComponents} source={props.content} />
|
||||
);
|
24
hyperglass/ui/components/Markdown/types.ts
Normal file
24
hyperglass/ui/components/Markdown/types.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import type { BoxProps, CheckboxProps, HeadingProps } from '@chakra-ui/core';
|
||||
export interface IMarkdown {
|
||||
content: string;
|
||||
}
|
||||
export interface ICheckbox extends CheckboxProps {
|
||||
checked: boolean;
|
||||
}
|
||||
|
||||
export interface IList {
|
||||
ordered: boolean;
|
||||
children?: ReactNode;
|
||||
}
|
||||
export interface IHeading extends HeadingProps {
|
||||
level: 1 | 2 | 3 | 4 | 5 | 6;
|
||||
}
|
||||
|
||||
export interface ICodeBlock {
|
||||
value: ReactNode;
|
||||
}
|
||||
|
||||
export interface ITableData extends BoxProps {
|
||||
isHeader: boolean;
|
||||
}
|
@@ -33,3 +33,4 @@ export * from './SubmitButton';
|
||||
export * from './Table';
|
||||
export * from './TextOutput';
|
||||
export * from './Title';
|
||||
export * from './withAnimation';
|
5
hyperglass/ui/components/withAnimation.ts
Normal file
5
hyperglass/ui/components/withAnimation.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export function withAnimation<P>(Component: React.FunctionComponent) {
|
||||
return motion.custom<Omit<P, 'transition'>>(Component);
|
||||
}
|
9
hyperglass/ui/globals.d.ts
vendored
9
hyperglass/ui/globals.d.ts
vendored
@@ -1 +1,8 @@
|
||||
type Dict<T = string> = { [k: string]: T };
|
||||
import type { MotionProps } from 'framer-motion';
|
||||
|
||||
type Dict<T = string> = Record<string, T>;
|
||||
|
||||
type ReactRef<T = HTMLElement> = MutableRefObject<T>;
|
||||
|
||||
type Animated<T> = Omit<T, keyof MotionProps> &
|
||||
Omit<MotionProps, keyof T> & { transition?: MotionProps['transition'] };
|
||||
|
1
hyperglass/ui/package.json
vendored
1
hyperglass/ui/package.json
vendored
@@ -42,6 +42,7 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.11.10",
|
||||
"@types/react-select": "^3.0.22",
|
||||
"@types/string-format": "^2.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.24.0",
|
||||
"@typescript-eslint/parser": "^2.24.0",
|
||||
"@upstatement/eslint-config": "^0.4.3",
|
||||
|
5
hyperglass/ui/yarn.lock
vendored
5
hyperglass/ui/yarn.lock
vendored
@@ -1966,6 +1966,11 @@
|
||||
"@types/prop-types" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/string-format@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/string-format/-/string-format-2.0.0.tgz#c1588f507be7b8ef5eb5074a41e48e4538f3f6d5"
|
||||
integrity sha512-mMwtmgN0ureESnJ3SuMM4W9lsi4CgOxs43YxNo14SDHgzJ+OPYO3yM7nOTJTh8x5YICseBdtrySUbvxnpb+NYQ==
|
||||
|
||||
"@types/tinycolor2@1.4.2":
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf"
|
||||
|
Reference in New Issue
Block a user