forked from mirrors/thatmattlove-hyperglass
remove cached incorrectly cased directories
This commit is contained in:
parent
2acecd8437
commit
90a837313f
29 changed files with 0 additions and 842 deletions
|
|
@ -1,24 +0,0 @@
|
||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
import { useColorValue } from '~/context';
|
|
||||||
|
|
||||||
import type { ICardBody } from './types';
|
|
||||||
|
|
||||||
export const CardBody = (props: ICardBody) => {
|
|
||||||
const { onClick, ...rest } = props;
|
|
||||||
const bg = useColorValue('white', 'dark.500');
|
|
||||||
const color = useColorValue('dark.500', 'white');
|
|
||||||
return (
|
|
||||||
<Flex
|
|
||||||
bg={bg}
|
|
||||||
w="100%"
|
|
||||||
maxW="95%"
|
|
||||||
rounded="md"
|
|
||||||
color={color}
|
|
||||||
onClick={onClick}
|
|
||||||
overflow="hidden"
|
|
||||||
borderWidth="1px"
|
|
||||||
direction="column"
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
import type { ICardFooter } from './types';
|
|
||||||
|
|
||||||
export const CardFooter = (props: ICardFooter) => (
|
|
||||||
<Flex
|
|
||||||
p={4}
|
|
||||||
direction="column"
|
|
||||||
overflowX="hidden"
|
|
||||||
overflowY="hidden"
|
|
||||||
flexDirection="row"
|
|
||||||
borderTopWidth="1px"
|
|
||||||
roundedBottomLeft={4}
|
|
||||||
roundedBottomRight={4}
|
|
||||||
justifyContent="space-between"
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import { Flex, Text } from '@chakra-ui/react';
|
|
||||||
import { useColorValue } from '~/context';
|
|
||||||
|
|
||||||
import type { ICardHeader } from './types';
|
|
||||||
|
|
||||||
export const CardHeader = (props: ICardHeader) => {
|
|
||||||
const { children, ...rest } = props;
|
|
||||||
const bg = useColorValue('blackAlpha.50', 'whiteAlpha.100');
|
|
||||||
return (
|
|
||||||
<Flex
|
|
||||||
p={4}
|
|
||||||
bg={bg}
|
|
||||||
direction="column"
|
|
||||||
roundedTopLeft={4}
|
|
||||||
roundedTopRight={4}
|
|
||||||
borderBottomWidth="1px"
|
|
||||||
{...rest}>
|
|
||||||
<Text fontWeight="bold">{children}</Text>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
export * from './body';
|
|
||||||
export * from './footer';
|
|
||||||
export * from './header';
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
import type { FlexProps } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
export interface ICardBody extends Omit<FlexProps, 'onClick'> {
|
|
||||||
onClick?: () => boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ICardFooter extends FlexProps {}
|
|
||||||
|
|
||||||
export interface ICardHeader extends FlexProps {}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
import { Button, Menu, MenuButton, MenuList } from '@chakra-ui/react';
|
|
||||||
import { Markdown } from '~/components';
|
|
||||||
import { useColorValue, useBreakpointValue } from '~/context';
|
|
||||||
import { useOpposingColor } from '~/hooks';
|
|
||||||
|
|
||||||
import type { TFooterButton } from './types';
|
|
||||||
|
|
||||||
export const FooterButton = (props: TFooterButton) => {
|
|
||||||
const { content, title, side, ...rest } = props;
|
|
||||||
const placement = side === 'left' ? 'top' : side === 'right' ? 'top-start' : undefined;
|
|
||||||
const bg = useColorValue('white', 'gray.900');
|
|
||||||
const color = useOpposingColor(bg);
|
|
||||||
const size = useBreakpointValue({ base: 'xs', lg: 'sm' });
|
|
||||||
return (
|
|
||||||
<Menu placement={placement}>
|
|
||||||
<MenuButton
|
|
||||||
as={Button}
|
|
||||||
size={size}
|
|
||||||
variant="ghost"
|
|
||||||
aria-label={typeof title === 'string' ? title : undefined}>
|
|
||||||
{title}
|
|
||||||
</MenuButton>
|
|
||||||
<MenuList
|
|
||||||
bg={bg}
|
|
||||||
boxShadow="2xl"
|
|
||||||
color={color}
|
|
||||||
px={6}
|
|
||||||
py={4}
|
|
||||||
textAlign="left"
|
|
||||||
mx={{ base: 1, lg: 2 }}
|
|
||||||
maxW={{ base: '100vw', lg: '50vw' }}
|
|
||||||
{...rest}>
|
|
||||||
<Markdown content={content} />
|
|
||||||
</MenuList>
|
|
||||||
</Menu>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
import { forwardRef } from 'react';
|
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { Button, Icon, Tooltip } from '@chakra-ui/react';
|
|
||||||
import { If } from '~/components';
|
|
||||||
import { useColorMode, useColorValue, useBreakpointValue } from '~/context';
|
|
||||||
import { useOpposingColor } from '~/hooks';
|
|
||||||
|
|
||||||
import type { TColorModeToggle } from './types';
|
|
||||||
|
|
||||||
const Sun = dynamic<MeronexIcon>(() => import('@meronex/icons/hi').then(i => i.HiSun));
|
|
||||||
const Moon = dynamic<MeronexIcon>(() => import('@meronex/icons/hi').then(i => i.HiMoon));
|
|
||||||
|
|
||||||
export const ColorModeToggle = forwardRef<HTMLButtonElement, TColorModeToggle>((props, ref) => {
|
|
||||||
const { size = '1.5rem', ...rest } = props;
|
|
||||||
const { colorMode, toggleColorMode } = useColorMode();
|
|
||||||
|
|
||||||
const bg = useColorValue('primary.500', 'yellow.300');
|
|
||||||
const color = useOpposingColor(bg);
|
|
||||||
const label = useColorValue('Switch to dark mode', 'Switch to light mode');
|
|
||||||
const btnSize = useBreakpointValue({ base: 'xs', lg: 'sm' });
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tooltip hasArrow placement="top-end" label={label} bg={bg} color={color}>
|
|
||||||
<Button
|
|
||||||
ref={ref}
|
|
||||||
size={btnSize}
|
|
||||||
title={label}
|
|
||||||
variant="ghost"
|
|
||||||
aria-label={label}
|
|
||||||
_hover={{ color: bg }}
|
|
||||||
color="currentColor"
|
|
||||||
onClick={toggleColorMode}
|
|
||||||
{...rest}>
|
|
||||||
<If c={colorMode === 'light'}>
|
|
||||||
<Icon as={Moon} boxSize={size} />
|
|
||||||
</If>
|
|
||||||
<If c={colorMode === 'dark'}>
|
|
||||||
<Icon as={Sun} boxSize={size} />
|
|
||||||
</If>
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { Button, Flex, Link, Icon, HStack, useToken } from '@chakra-ui/react';
|
|
||||||
import { If } from '~/components';
|
|
||||||
import { useConfig, useMobile, useColorValue, useBreakpointValue } from '~/context';
|
|
||||||
import { useStrf } from '~/hooks';
|
|
||||||
import { FooterButton } from './button';
|
|
||||||
import { ColorModeToggle } from './colorMode';
|
|
||||||
|
|
||||||
const CodeIcon = dynamic<MeronexIcon>(() => import('@meronex/icons/fi').then(i => i.FiCode));
|
|
||||||
const ExtIcon = dynamic<MeronexIcon>(() => import('@meronex/icons/go').then(i => i.GoLinkExternal));
|
|
||||||
|
|
||||||
export const Footer = () => {
|
|
||||||
const { web, content, primary_asn } = useConfig();
|
|
||||||
|
|
||||||
const footerBg = useColorValue('blackAlpha.50', 'whiteAlpha.100');
|
|
||||||
const footerColor = useColorValue('black', 'white');
|
|
||||||
|
|
||||||
const extUrl = useStrf(web.external_link.url, { primary_asn }) ?? '/';
|
|
||||||
|
|
||||||
const size = useBreakpointValue({ base: useToken('sizes', 4), lg: useToken('sizes', 6) });
|
|
||||||
const btnSize = useBreakpointValue({ base: 'xs', lg: 'sm' });
|
|
||||||
|
|
||||||
const isMobile = useMobile();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<HStack
|
|
||||||
px={6}
|
|
||||||
py={4}
|
|
||||||
w="100%"
|
|
||||||
zIndex={1}
|
|
||||||
as="footer"
|
|
||||||
bg={footerBg}
|
|
||||||
color={footerColor}
|
|
||||||
spacing={{ base: 8, lg: 6 }}
|
|
||||||
justifyContent={{ base: 'center', lg: 'space-between' }}>
|
|
||||||
<If c={web.terms.enable}>
|
|
||||||
<FooterButton side="left" content={content.terms} title={web.terms.title} />
|
|
||||||
</If>
|
|
||||||
<If c={web.help_menu.enable}>
|
|
||||||
<FooterButton side="left" content={content.help_menu} title={web.help_menu.title} />
|
|
||||||
</If>
|
|
||||||
<If c={web.external_link.enable}>
|
|
||||||
<Button
|
|
||||||
as={Link}
|
|
||||||
isExternal
|
|
||||||
href={extUrl}
|
|
||||||
size={btnSize}
|
|
||||||
variant="ghost"
|
|
||||||
rightIcon={<ExtIcon />}
|
|
||||||
aria-label={web.external_link.title}>
|
|
||||||
{web.external_link.title}
|
|
||||||
</Button>
|
|
||||||
</If>
|
|
||||||
{!isMobile && <Flex p={0} flex="0 0 auto" maxWidth="100%" mr="auto" />}
|
|
||||||
<If c={web.credit.enable}>
|
|
||||||
<FooterButton
|
|
||||||
side="right"
|
|
||||||
content={content.credit}
|
|
||||||
title={<Icon as={CodeIcon} boxSize={size} />}
|
|
||||||
/>
|
|
||||||
</If>
|
|
||||||
<ColorModeToggle size={size} />
|
|
||||||
</HStack>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export * from './footer';
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import type { ButtonProps, MenuListProps } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
type TFooterSide = 'left' | 'right';
|
|
||||||
|
|
||||||
export interface TFooterButton extends Omit<MenuListProps, 'title'> {
|
|
||||||
side: TFooterSide;
|
|
||||||
title?: MenuListProps['children'];
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TFooterItems = 'help' | 'credit' | 'terms';
|
|
||||||
|
|
||||||
export interface TColorModeToggle extends ButtonProps {
|
|
||||||
size?: string;
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
import ReactMarkdown from 'react-markdown';
|
|
||||||
import {
|
|
||||||
List,
|
|
||||||
ListItem,
|
|
||||||
Heading,
|
|
||||||
Link,
|
|
||||||
CodeBlock,
|
|
||||||
TableData,
|
|
||||||
Paragraph,
|
|
||||||
InlineCode,
|
|
||||||
Divider,
|
|
||||||
Table,
|
|
||||||
} from './elements';
|
|
||||||
|
|
||||||
import type { ReactMarkdownProps } from 'react-markdown';
|
|
||||||
import type { TMarkdown } from './types';
|
|
||||||
|
|
||||||
const renderers = {
|
|
||||||
paragraph: Paragraph,
|
|
||||||
link: Link,
|
|
||||||
heading: Heading,
|
|
||||||
inlineCode: InlineCode,
|
|
||||||
list: List,
|
|
||||||
listItem: ListItem,
|
|
||||||
thematicBreak: Divider,
|
|
||||||
code: CodeBlock,
|
|
||||||
table: Table,
|
|
||||||
tableCell: TableData,
|
|
||||||
} as ReactMarkdownProps['renderers'];
|
|
||||||
|
|
||||||
export const Markdown = (props: TMarkdown) => (
|
|
||||||
<ReactMarkdown renderers={renderers} source={props.content} />
|
|
||||||
);
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
import {
|
|
||||||
OrderedList,
|
|
||||||
UnorderedList,
|
|
||||||
Code as ChakraCode,
|
|
||||||
Link as ChakraLink,
|
|
||||||
Text as ChakraText,
|
|
||||||
Divider as ChakraDivider,
|
|
||||||
Heading as ChakraHeading,
|
|
||||||
Checkbox as ChakraCheckbox,
|
|
||||||
ListItem as ChakraListItem,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
|
|
||||||
import { TD, TH, Table as ChakraTable } from './table';
|
|
||||||
|
|
||||||
import { CodeBlock as CustomCodeBlock, If } from '~/components';
|
|
||||||
|
|
||||||
import type {
|
|
||||||
BoxProps,
|
|
||||||
TextProps,
|
|
||||||
CodeProps,
|
|
||||||
LinkProps,
|
|
||||||
HeadingProps,
|
|
||||||
DividerProps,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import type { TCheckbox, TList, THeading, TCodeBlock, TTableData, TListItem } from './types';
|
|
||||||
|
|
||||||
export const Checkbox = (props: TCheckbox) => {
|
|
||||||
const { checked, ...rest } = props;
|
|
||||||
return <ChakraCheckbox isChecked={checked} {...rest} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const List = (props: TList) => {
|
|
||||||
const { ordered, ...rest } = props;
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<If c={ordered}>
|
|
||||||
<OrderedList {...rest} />
|
|
||||||
</If>
|
|
||||||
<If c={!ordered}>
|
|
||||||
<UnorderedList {...rest} />
|
|
||||||
</If>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ListItem = (props: TListItem) => {
|
|
||||||
const { checked, ...rest } = props;
|
|
||||||
return checked ? <Checkbox checked={checked} {...rest} /> : <ChakraListItem {...rest} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Heading = (props: THeading) => {
|
|
||||||
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' },
|
|
||||||
} as { [i: number]: HeadingProps };
|
|
||||||
|
|
||||||
return <ChakraHeading {...levelMap[level]} {...rest} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Link = (props: LinkProps) => <ChakraLink isExternal {...props} />;
|
|
||||||
|
|
||||||
export const CodeBlock = (props: TCodeBlock) => <CustomCodeBlock>{props.value}</CustomCodeBlock>;
|
|
||||||
|
|
||||||
export const TableData = (props: TTableData) => {
|
|
||||||
const { isHeader, ...rest } = props;
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<If c={isHeader}>
|
|
||||||
<TH {...rest} />
|
|
||||||
</If>
|
|
||||||
<If c={!isHeader}>
|
|
||||||
<TD {...rest} />
|
|
||||||
</If>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Paragraph = (props: TextProps) => <ChakraText {...props} />;
|
|
||||||
export const InlineCode = (props: CodeProps) => <ChakraCode children={props.children} />;
|
|
||||||
export const Divider = (props: DividerProps) => <ChakraDivider {...props} />;
|
|
||||||
export const Table = (props: BoxProps) => <ChakraTable {...props} />;
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export * from './markdown';
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
import { Box } from '@chakra-ui/react';
|
|
||||||
import { useColorValue } from '~/context';
|
|
||||||
|
|
||||||
import type { BoxProps } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
export const Table = (props: BoxProps) => (
|
|
||||||
<Box as="table" textAlign="left" mt={4} width="full" {...props} />
|
|
||||||
);
|
|
||||||
|
|
||||||
export const TH = (props: BoxProps) => {
|
|
||||||
const bg = useColorValue('blackAlpha.50', 'whiteAlpha.50');
|
|
||||||
return <Box as="th" bg={bg} fontWeight="semibold" p={2} fontSize="sm" {...props} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TD = (props: BoxProps) => {
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
p={2}
|
|
||||||
as="td"
|
|
||||||
fontSize="sm"
|
|
||||||
whiteSpace="normal"
|
|
||||||
borderTopWidth="1px"
|
|
||||||
borderColor="inherit"
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
import type {
|
|
||||||
BoxProps,
|
|
||||||
CheckboxProps,
|
|
||||||
HeadingProps,
|
|
||||||
ListProps,
|
|
||||||
ListItemProps,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
|
|
||||||
export interface TMarkdown {
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TCheckbox extends CheckboxProps {
|
|
||||||
checked: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TListItem {
|
|
||||||
checked: boolean;
|
|
||||||
children?: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TList extends ListProps {
|
|
||||||
ordered: boolean;
|
|
||||||
children?: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface THeading extends HeadingProps {
|
|
||||||
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TCodeBlock {
|
|
||||||
value: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TTableData extends BoxProps {
|
|
||||||
isHeader: boolean;
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import { Box } from '@chakra-ui/react';
|
|
||||||
import { useColorValue } from '~/context';
|
|
||||||
|
|
||||||
import type { BoxProps } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
export const TableMain = (props: BoxProps) => {
|
|
||||||
const scrollbar = useColorValue('blackAlpha.300', 'whiteAlpha.300');
|
|
||||||
const scrollbarHover = useColorValue('blackAlpha.400', 'whiteAlpha.400');
|
|
||||||
const scrollbarBg = useColorValue('blackAlpha.50', 'whiteAlpha.50');
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
as="table"
|
|
||||||
display="block"
|
|
||||||
overflowX="auto"
|
|
||||||
borderRadius="md"
|
|
||||||
boxSizing="border-box"
|
|
||||||
css={{
|
|
||||||
'&::-webkit-scrollbar': { height: '5px' },
|
|
||||||
'&::-webkit-scrollbar-track': {
|
|
||||||
backgroundColor: scrollbarBg,
|
|
||||||
},
|
|
||||||
'&::-webkit-scrollbar-thumb': {
|
|
||||||
backgroundColor: scrollbar,
|
|
||||||
},
|
|
||||||
'&::-webkit-scrollbar-thumb:hover': {
|
|
||||||
backgroundColor: scrollbarHover,
|
|
||||||
},
|
|
||||||
|
|
||||||
'-ms-overflow-style': { display: 'none' },
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import { Box } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
import type { BoxProps } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
export const TableBody = (props: BoxProps) => (
|
|
||||||
<Box
|
|
||||||
as="tbody"
|
|
||||||
overflowY="scroll"
|
|
||||||
css={{
|
|
||||||
'&::-webkit-scrollbar': { display: 'none' },
|
|
||||||
'&': { msOverflowStyle: 'none' },
|
|
||||||
}}
|
|
||||||
overflowX="hidden"
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
import { IconButton } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
import type { TTableIconButton } from './types';
|
|
||||||
|
|
||||||
export const TableIconButton = (props: TTableIconButton) => (
|
|
||||||
<IconButton size="sm" borderWidth={1} {...props} aria-label="Table Icon Button" />
|
|
||||||
);
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { Box } from '@chakra-ui/react';
|
|
||||||
import { useColorValue } from '~/context';
|
|
||||||
|
|
||||||
import type { TTableCell } from './types';
|
|
||||||
|
|
||||||
export const TableCell = (props: TTableCell) => {
|
|
||||||
const { bordersVertical = [false, 0], align, ...rest } = props;
|
|
||||||
const [doVerticalBorders, index] = bordersVertical;
|
|
||||||
const borderLeftColor = useColorValue('blackAlpha.100', 'whiteAlpha.100');
|
|
||||||
|
|
||||||
let borderProps = {};
|
|
||||||
if (doVerticalBorders && index !== 0) {
|
|
||||||
borderProps = { borderLeft: '1px solid', borderLeftColor };
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
p={4}
|
|
||||||
m={0}
|
|
||||||
w="1%"
|
|
||||||
as="td"
|
|
||||||
textAlign={align}
|
|
||||||
whiteSpace="nowrap"
|
|
||||||
{...borderProps}
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
import { Box } from '@chakra-ui/react';
|
|
||||||
import { useColorValue } from '~/context';
|
|
||||||
|
|
||||||
import type { BoxProps } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
export const TableHead = (props: BoxProps) => {
|
|
||||||
const bg = useColorValue('blackAlpha.100', 'whiteAlpha.100');
|
|
||||||
return <Box as="thead" overflowX="hidden" overflowY="auto" bg={bg} {...props} />;
|
|
||||||
};
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
export * from './body';
|
|
||||||
export * from './button';
|
|
||||||
export * from './cell';
|
|
||||||
export * from './head';
|
|
||||||
export * from './main';
|
|
||||||
export * from './main';
|
|
||||||
export * from './pageSelect';
|
|
||||||
export * from './row';
|
|
||||||
|
|
@ -1,202 +0,0 @@
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { Flex, Icon, Text } from '@chakra-ui/react';
|
|
||||||
import { usePagination, useSortBy, useTable } from 'react-table';
|
|
||||||
import { useMobile } from '~/context';
|
|
||||||
import { CardBody, CardFooter, CardHeader, If } from '~/components';
|
|
||||||
import { TableMain } from './table';
|
|
||||||
import { TableCell } from './cell';
|
|
||||||
import { TableHead } from './head';
|
|
||||||
import { TableRow } from './row';
|
|
||||||
import { TableBody } from './body';
|
|
||||||
import { TableIconButton } from './button';
|
|
||||||
import { TableSelectShow } from './pageSelect';
|
|
||||||
|
|
||||||
import type { TableOptions, PluginHook } from 'react-table';
|
|
||||||
import type { TCellRender } from '~/types';
|
|
||||||
import type { TTable } from './types';
|
|
||||||
|
|
||||||
const ChevronRight = dynamic<MeronexIcon>(() =>
|
|
||||||
import('@meronex/icons/fa').then(i => i.FaChevronRight),
|
|
||||||
);
|
|
||||||
|
|
||||||
const ChevronLeft = dynamic<MeronexIcon>(() =>
|
|
||||||
import('@meronex/icons/fa').then(i => i.FaChevronLeft),
|
|
||||||
);
|
|
||||||
|
|
||||||
const ChevronDown = dynamic<MeronexIcon>(() =>
|
|
||||||
import('@meronex/icons/fa').then(i => i.FaChevronDown),
|
|
||||||
);
|
|
||||||
|
|
||||||
const DoubleChevronRight = dynamic<MeronexIcon>(() =>
|
|
||||||
import('@meronex/icons/fi').then(i => i.FiChevronsRight),
|
|
||||||
);
|
|
||||||
const DoubleChevronLeft = dynamic<MeronexIcon>(() =>
|
|
||||||
import('@meronex/icons/fi').then(i => i.FiChevronsLeft),
|
|
||||||
);
|
|
||||||
|
|
||||||
export function Table(props: TTable) {
|
|
||||||
const {
|
|
||||||
data,
|
|
||||||
columns,
|
|
||||||
heading,
|
|
||||||
Cell,
|
|
||||||
rowHighlightBg,
|
|
||||||
striped = false,
|
|
||||||
rowHighlightProp,
|
|
||||||
bordersVertical = false,
|
|
||||||
bordersHorizontal = false,
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const isMobile = useMobile();
|
|
||||||
|
|
||||||
const defaultColumn = {
|
|
||||||
minWidth: 100,
|
|
||||||
width: 150,
|
|
||||||
maxWidth: 300,
|
|
||||||
};
|
|
||||||
|
|
||||||
let hiddenColumns = [] as string[];
|
|
||||||
|
|
||||||
for (const col of columns) {
|
|
||||||
if (col.hidden) {
|
|
||||||
hiddenColumns.push(col.accessor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
columns,
|
|
||||||
defaultColumn,
|
|
||||||
data,
|
|
||||||
initialState: { hiddenColumns },
|
|
||||||
} as TableOptions<TRoute>;
|
|
||||||
|
|
||||||
const plugins = [useSortBy, usePagination] as PluginHook<TRoute>[];
|
|
||||||
|
|
||||||
const instance = useTable<TRoute>(options, ...plugins);
|
|
||||||
|
|
||||||
const {
|
|
||||||
page,
|
|
||||||
gotoPage,
|
|
||||||
nextPage,
|
|
||||||
pageCount,
|
|
||||||
prepareRow,
|
|
||||||
canNextPage,
|
|
||||||
pageOptions,
|
|
||||||
setPageSize,
|
|
||||||
headerGroups,
|
|
||||||
previousPage,
|
|
||||||
getTableProps,
|
|
||||||
canPreviousPage,
|
|
||||||
state: { pageIndex, pageSize },
|
|
||||||
} = instance;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CardBody>
|
|
||||||
{heading && <CardHeader>{heading}</CardHeader>}
|
|
||||||
<TableMain {...getTableProps()}>
|
|
||||||
<TableHead>
|
|
||||||
{headerGroups.map((headerGroup, i) => (
|
|
||||||
<TableRow index={i} {...headerGroup.getHeaderGroupProps()}>
|
|
||||||
{headerGroup.headers.map(column => (
|
|
||||||
<TableCell
|
|
||||||
as="th"
|
|
||||||
align={column.align}
|
|
||||||
{...column.getHeaderProps()}
|
|
||||||
{...column.getSortByToggleProps()}>
|
|
||||||
<Text fontSize="sm" fontWeight="bold" display="inline-block">
|
|
||||||
{column.render('Header')}
|
|
||||||
</Text>
|
|
||||||
<If c={column.isSorted}>
|
|
||||||
<If c={typeof column.isSortedDesc !== 'undefined'}>
|
|
||||||
<Icon as={ChevronDown} boxSize={4} ml={1} />
|
|
||||||
</If>
|
|
||||||
<If c={!column.isSortedDesc}>
|
|
||||||
<Icon as={ChevronRight} boxSize={4} ml={1} />
|
|
||||||
</If>
|
|
||||||
</If>
|
|
||||||
<If c={!column.isSorted}>{''}</If>
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{page.map((row, key) => {
|
|
||||||
prepareRow(row);
|
|
||||||
return (
|
|
||||||
<TableRow
|
|
||||||
index={key}
|
|
||||||
doStripe={striped}
|
|
||||||
highlightBg={rowHighlightBg}
|
|
||||||
doHorizontalBorders={bordersHorizontal}
|
|
||||||
highlight={row.values[rowHighlightProp ?? ''] ?? false}
|
|
||||||
{...row.getRowProps()}>
|
|
||||||
{row.cells.map((cell, i) => {
|
|
||||||
const { column, row, value } = cell as TCellRender;
|
|
||||||
return (
|
|
||||||
<TableCell
|
|
||||||
align={cell.column.align}
|
|
||||||
bordersVertical={[bordersVertical, i]}
|
|
||||||
{...cell.getCellProps()}>
|
|
||||||
{typeof Cell !== 'undefined' ? (
|
|
||||||
<Cell column={column} row={row} value={value} />
|
|
||||||
) : (
|
|
||||||
cell.render('Cell')
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</TableRow>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</TableBody>
|
|
||||||
</TableMain>
|
|
||||||
<CardFooter>
|
|
||||||
<Flex direction="row">
|
|
||||||
<TableIconButton
|
|
||||||
mr={2}
|
|
||||||
onClick={() => gotoPage(0)}
|
|
||||||
isDisabled={!canPreviousPage}
|
|
||||||
icon={<Icon as={DoubleChevronLeft} boxSize={4} />}
|
|
||||||
/>
|
|
||||||
<TableIconButton
|
|
||||||
mr={2}
|
|
||||||
onClick={() => previousPage()}
|
|
||||||
isDisabled={!canPreviousPage}
|
|
||||||
icon={<Icon as={ChevronLeft} boxSize={3} />}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<Flex justifyContent="center" alignItems="center">
|
|
||||||
<Text fontSize="sm" mr={4} whiteSpace="nowrap">
|
|
||||||
Page{' '}
|
|
||||||
<strong>
|
|
||||||
{pageIndex + 1} of {pageOptions.length}
|
|
||||||
</strong>{' '}
|
|
||||||
</Text>
|
|
||||||
{!isMobile && (
|
|
||||||
<TableSelectShow
|
|
||||||
value={pageSize}
|
|
||||||
onChange={e => {
|
|
||||||
setPageSize(Number(e.target.value));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
<Flex direction="row">
|
|
||||||
<TableIconButton
|
|
||||||
ml={2}
|
|
||||||
onClick={nextPage}
|
|
||||||
isDisabled={!canNextPage}
|
|
||||||
icon={<Icon as={ChevronRight} boxSize={3} />}
|
|
||||||
/>
|
|
||||||
<TableIconButton
|
|
||||||
ml={2}
|
|
||||||
isDisabled={!canNextPage}
|
|
||||||
icon={<Icon as={DoubleChevronRight} boxSize={4} />}
|
|
||||||
onClick={() => gotoPage(pageCount ? pageCount - 1 : 1)}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</CardFooter>
|
|
||||||
</CardBody>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import { Select } from '@chakra-ui/react';
|
|
||||||
import { SelectProps } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
export const TableSelectShow = (props: SelectProps) => {
|
|
||||||
const { value, ...rest } = props;
|
|
||||||
return (
|
|
||||||
<Select size="sm" {...rest}>
|
|
||||||
{[5, 10, 20, 30, 40, 50].map(value => (
|
|
||||||
<option key={value} value={value}>
|
|
||||||
Show {value}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
import { Box } from '@chakra-ui/react';
|
|
||||||
import { useColorValue } from '~/context';
|
|
||||||
import { useOpposingColor } from '~/hooks';
|
|
||||||
|
|
||||||
import type { TTableRow } from './types';
|
|
||||||
|
|
||||||
export const TableRow = (props: TTableRow) => {
|
|
||||||
const {
|
|
||||||
index = 0,
|
|
||||||
doStripe = false,
|
|
||||||
highlight = false,
|
|
||||||
highlightBg = 'primary',
|
|
||||||
doHorizontalBorders = false,
|
|
||||||
...rest
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const alpha = useColorValue('100', '200');
|
|
||||||
const alphaHover = useColorValue('200', '100');
|
|
||||||
const bgStripe = useColorValue('blackAlpha.50', 'whiteAlpha.50');
|
|
||||||
let hoverBg = useColorValue('blackAlpha.50', 'whiteAlpha.50');
|
|
||||||
const rowBorder = useColorValue(
|
|
||||||
{ borderTop: '1px', borderTopColor: 'blackAlpha.100' },
|
|
||||||
{ borderTop: '1px', borderTopColor: 'whiteAlpha.100' },
|
|
||||||
);
|
|
||||||
let bg;
|
|
||||||
|
|
||||||
if (highlight) {
|
|
||||||
bg = `${String(highlightBg)}.${alpha}`;
|
|
||||||
hoverBg = `${String(highlightBg)}.${alphaHover}`;
|
|
||||||
} else if (doStripe && index % 2 !== 0) {
|
|
||||||
bg = bgStripe;
|
|
||||||
}
|
|
||||||
const defaultBg = useColorValue('white', 'black');
|
|
||||||
const color = useOpposingColor(bg ?? defaultBg);
|
|
||||||
const borderProps = doHorizontalBorders && index !== 0 ? rowBorder : {};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
as="tr"
|
|
||||||
bg={bg}
|
|
||||||
css={{ '& > td': { color } }}
|
|
||||||
fontWeight={highlight ? 'bold' : undefined}
|
|
||||||
_hover={{
|
|
||||||
cursor: 'pointer',
|
|
||||||
backgroundColor: highlight ? `${String(highlightBg)}.${alphaHover}` : hoverBg,
|
|
||||||
}}
|
|
||||||
{...borderProps}
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
import type { BoxProps, IconButtonProps } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
import type { Theme, TColumn, TCellRender } from '~/types';
|
|
||||||
|
|
||||||
export interface TTable {
|
|
||||||
data: TRoute[];
|
|
||||||
striped?: boolean;
|
|
||||||
columns: TColumn[];
|
|
||||||
heading?: React.ReactNode;
|
|
||||||
bordersVertical?: boolean;
|
|
||||||
bordersHorizontal?: boolean;
|
|
||||||
Cell?: React.FC<TCellRender>;
|
|
||||||
rowHighlightProp?: keyof IRoute;
|
|
||||||
rowHighlightBg?: Theme.ColorNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TTableCell extends Omit<BoxProps, 'align'> {
|
|
||||||
bordersVertical?: [boolean, number];
|
|
||||||
align?: 'left' | 'right' | 'center';
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TTableRow extends BoxProps {
|
|
||||||
highlightBg?: Theme.ColorNames;
|
|
||||||
doHorizontalBorders?: boolean;
|
|
||||||
highlight?: boolean;
|
|
||||||
doStripe?: boolean;
|
|
||||||
index: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TTableIconButton = Omit<IconButtonProps, 'aria-label'>;
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
import type { TIf } from './types';
|
|
||||||
|
|
||||||
export const If = (props: TIf) => {
|
|
||||||
const { c, render, children, ...rest } = props;
|
|
||||||
return c ? (render ? render(rest) : children) : null;
|
|
||||||
};
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import { chakra } from '@chakra-ui/react';
|
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
|
|
||||||
export const AnimatedDiv = motion.custom(chakra.div);
|
|
||||||
export const AnimatedForm = motion.custom(chakra.form);
|
|
||||||
export const AnimatedH1 = motion.custom(chakra.h1);
|
|
||||||
export const AnimatedH3 = motion.custom(chakra.h3);
|
|
||||||
export const AnimatedButton = motion.custom(chakra.button);
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
export * from './animated';
|
|
||||||
export * from './if';
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
export interface TIf {
|
|
||||||
c: boolean;
|
|
||||||
render?: (rest: any) => JSX.Element;
|
|
||||||
[k: string]: any;
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue