mirror of
https://github.com/checktheroads/hyperglass
synced 2024-05-11 05:55:08 +00:00
continue typescript & chakra v1 migrations [skip ci]
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import { Button, useColorMode } from '@chakra-ui/core';
|
||||
|
||||
const Sun = ({ color, size = '1.5rem', ...props }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
style={{
|
||||
height: size,
|
||||
width: size,
|
||||
}}
|
||||
strokeWidth={0}
|
||||
stroke="currentColor"
|
||||
fill="currentColor"
|
||||
{...props}>
|
||||
<path
|
||||
d="M256 32a224 224 0 00-161.393 69.035h323.045A224 224 0 00256 32zM79.148 118.965a224 224 0 00-16.976 25.16H449.74a224 224 0 00-16.699-25.16H79.148zm-27.222 45.16A224 224 0 0043.3 186.25h425.271a224 224 0 00-8.586-22.125H51.926zM36.783 210.25a224 224 0 00-3.02 19.125h444.368a224 224 0 00-3.113-19.125H36.783zm-4.752 45.125A224 224 0 0032 256a224 224 0 00.64 16.5h446.534A224 224 0 00480 256a224 224 0 00-.021-.625H32.03zm4.67 45.125a224 224 0 003.395 15.125h431.578a224 224 0 003.861-15.125H36.701zm14.307 45.125a224 224 0 006.017 13.125H454.82a224 224 0 006.342-13.125H51.008zm26.316 45.125a224 224 0 009.04 11.125H425.86a224 224 0 008.727-11.125H77.324zm45.62 45.125A224 224 0 00136.247 445h239.89a224 224 0 0012.936-9.125h-266.13z"
|
||||
fill={color || 'currentColor'}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const Moon = ({ color, size = '1.5rem', ...props }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
style={{
|
||||
height: size,
|
||||
width: size,
|
||||
}}
|
||||
strokeWidth={0}
|
||||
stroke="currentColor"
|
||||
fill="currentColor"
|
||||
{...props}>
|
||||
<path
|
||||
d="M14.53 10.53a7 7 0 01-9.058-9.058A7.003 7.003 0 008 15a7.002 7.002 0 006.53-4.47z"
|
||||
fill={color || 'currentColor'}
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const iconMap = { dark: Moon, light: Sun };
|
||||
const outlineColor = { dark: 'primary.300', light: 'primary.600' };
|
||||
|
||||
export const ColorModeToggle = forwardRef((props, ref) => {
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
const Icon = iconMap[colorMode];
|
||||
|
||||
const label = `Switch to ${colorMode === 'light' ? 'dark' : 'light'} mode`;
|
||||
|
||||
return (
|
||||
<Button
|
||||
ref={ref}
|
||||
aria-label={label}
|
||||
title={label}
|
||||
onClick={toggleColorMode}
|
||||
variant="ghost"
|
||||
borderWidth="1px"
|
||||
borderColor="transparent"
|
||||
_hover={{
|
||||
backgroundColor: 'unset',
|
||||
borderColor: outlineColor[colorMode],
|
||||
}}
|
||||
color="current"
|
||||
px={4}
|
||||
{...props}>
|
||||
<Icon />
|
||||
</Button>
|
||||
);
|
||||
});
|
@@ -1,55 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Flex, FormControl, FormLabel, FormErrorMessage, useColorMode } from '@chakra-ui/core';
|
||||
|
||||
const labelColor = { dark: 'whiteAlpha.700', light: 'blackAlpha.700' };
|
||||
|
||||
export const FormField = ({
|
||||
label,
|
||||
name,
|
||||
error,
|
||||
hiddenLabels,
|
||||
helpIcon,
|
||||
targetInfo,
|
||||
setTarget,
|
||||
labelAddOn,
|
||||
fieldAddOn,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const { colorMode } = useColorMode();
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
as={Flex}
|
||||
flexDirection="column"
|
||||
flex={['1 0 100%', '1 0 100%', '1 0 33.33%', '1 0 33.33%']}
|
||||
w="100%"
|
||||
maxW="100%"
|
||||
mx={2}
|
||||
my={[2, 2, 4, 4]}
|
||||
isInvalid={error && error.message}
|
||||
{...props}>
|
||||
<FormLabel
|
||||
htmlFor={name}
|
||||
color={labelColor[colorMode]}
|
||||
pl={1}
|
||||
opacity={hiddenLabels ? 0 : null}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
pr={0}>
|
||||
{label}
|
||||
{labelAddOn || null}
|
||||
</FormLabel>
|
||||
{children}
|
||||
{fieldAddOn && (
|
||||
<Flex justifyContent="flex-end" pt={3}>
|
||||
{fieldAddOn}
|
||||
</Flex>
|
||||
)}
|
||||
<FormErrorMessage opacity={hiddenLabels ? 0 : null}>
|
||||
{error && error.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
@@ -1,67 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalFooter,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
useColorMode,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/core';
|
||||
import { Markdown } from 'app/components';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
const bg = { light: 'white', dark: 'black' };
|
||||
const color = { light: 'black', dark: 'white' };
|
||||
|
||||
const AnimatedModalContent = motion.custom(ModalContent);
|
||||
const AnimatedModalOverlay = motion.custom(ModalOverlay);
|
||||
|
||||
export const Greeting = ({ greetingConfig, content, onClickThrough }) => {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure(true);
|
||||
const { colorMode } = useColorMode();
|
||||
|
||||
const handleClick = () => {
|
||||
onClickThrough(true);
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
onClose={handleClick}
|
||||
isOpen={isOpen}
|
||||
size="full"
|
||||
isCentered
|
||||
closeOnOverlayClick={!greetingConfig.required}
|
||||
closeOnEsc={!greetingConfig.required}>
|
||||
<AnimatedModalOverlay
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.3, delay: 0.7 }}
|
||||
/>
|
||||
<AnimatedModalContent
|
||||
initial={{ scale: 0.5, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
transition={{ duration: 0.3, delay: 0.7 }}
|
||||
bg={bg[colorMode]}
|
||||
color={color[colorMode]}
|
||||
py={4}
|
||||
borderRadius="md"
|
||||
maxW={['95%', '75%', '75%', '75%']}>
|
||||
<ModalHeader>{greetingConfig.title}</ModalHeader>
|
||||
{!greetingConfig.required && <ModalCloseButton />}
|
||||
<ModalBody>
|
||||
<Markdown content={content} />
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button variantColor="primary" onClick={handleClick}>
|
||||
{greetingConfig.button}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</AnimatedModalContent>
|
||||
</Modal>
|
||||
);
|
||||
};
|
@@ -1,58 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { useRef } from 'react';
|
||||
import { Flex, useColorMode } from '@chakra-ui/core';
|
||||
import { useConfig, useHyperglassState } from 'app/context';
|
||||
import { Debugger, Greeting, Footer, Header } from 'app/components';
|
||||
|
||||
const bg = { light: 'white', dark: 'black' };
|
||||
const color = { light: 'black', dark: 'white' };
|
||||
|
||||
export const Layout = ({ children }) => {
|
||||
const config = useConfig();
|
||||
const { colorMode } = useColorMode();
|
||||
const { greetingAck, setGreetingAck, setSubmitting, setFormData } = useHyperglassState();
|
||||
const containerRef = useRef(null);
|
||||
|
||||
const resetForm = () => {
|
||||
containerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
setSubmitting(false);
|
||||
setFormData({});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
w="100%"
|
||||
ref={containerRef}
|
||||
minHeight="100vh"
|
||||
bg={bg[colorMode]}
|
||||
flexDirection="column"
|
||||
color={color[colorMode]}>
|
||||
<Flex px={2} flex="0 1 auto" flexDirection="column">
|
||||
<Header resetForm={resetForm} />
|
||||
</Flex>
|
||||
<Flex
|
||||
px={2}
|
||||
py={0}
|
||||
w="100%"
|
||||
as="main"
|
||||
flex="1 1 auto"
|
||||
textAlign="center"
|
||||
alignItems="center"
|
||||
justifyContent="start"
|
||||
flexDirection="column">
|
||||
{children}
|
||||
</Flex>
|
||||
<Footer />
|
||||
{config.developer_mode && <Debugger />}
|
||||
</Flex>
|
||||
{config.web.greeting.enable && !greetingAck && (
|
||||
<Greeting
|
||||
greetingConfig={config.web.greeting}
|
||||
content={config.content.greeting}
|
||||
onClickThrough={setGreetingAck}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
@@ -1,10 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Button, Icon, Tooltip } from '@chakra-ui/core';
|
||||
|
||||
export const RequeryButton = ({ requery, bg = 'secondary', ...props }) => (
|
||||
<Tooltip hasArrow label="Reload Query" placement="top">
|
||||
<Button mx={1} as="a" size="sm" zIndex="1" variantColor={bg} onClick={requery} {...props}>
|
||||
<Icon size="16px" name="repeat" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
@@ -1 +1,2 @@
|
||||
export * from './animated';
|
||||
export * from './if';
|
||||
|
44
hyperglass/ui/components/buttons/colorMode.tsx
Normal file
44
hyperglass/ui/components/buttons/colorMode.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { forwardRef } from 'react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Button, Icon } from '@chakra-ui/react';
|
||||
import { If } from '~/components';
|
||||
import { useColorMode, useColorValue } from '~/context';
|
||||
|
||||
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));
|
||||
|
||||
const outlineColor = { dark: 'primary.300', light: 'primary.600' };
|
||||
|
||||
export const ColorModeToggle = forwardRef<HTMLButtonElement, TColorModeToggle>((props, ref) => {
|
||||
const { size = '1.5rem', ...rest } = props;
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
|
||||
const label = useColorValue('Switch to dark mode', 'Switch to light mode');
|
||||
|
||||
return (
|
||||
<Button
|
||||
ref={ref}
|
||||
aria-label={label}
|
||||
title={label}
|
||||
onClick={toggleColorMode}
|
||||
variant="ghost"
|
||||
borderWidth="1px"
|
||||
borderColor="transparent"
|
||||
_hover={{
|
||||
backgroundColor: 'unset',
|
||||
borderColor: outlineColor[colorMode],
|
||||
}}
|
||||
color="currentColor"
|
||||
px={4}
|
||||
{...rest}>
|
||||
<If c={colorMode === 'light'}>
|
||||
<Icon as={Moon} boxSize={size} />
|
||||
</If>
|
||||
<If c={colorMode === 'dark'}>
|
||||
<Icon as={Sun} boxSize={size} />
|
||||
</If>
|
||||
</Button>
|
||||
);
|
||||
});
|
5
hyperglass/ui/components/buttons/index.ts
Normal file
5
hyperglass/ui/components/buttons/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from './colorMode';
|
||||
export * from './copy';
|
||||
export * from './requery';
|
||||
export * from './reset';
|
||||
export * from './submit';
|
17
hyperglass/ui/components/buttons/requery.tsx
Normal file
17
hyperglass/ui/components/buttons/requery.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Button, Icon, Tooltip } from '@chakra-ui/react';
|
||||
|
||||
import type { TRequeryButton } from './types';
|
||||
|
||||
const Repeat = dynamic<MeronexIcon>(() => import('@meronex/icons/fi').then(i => i.FiRepeat));
|
||||
|
||||
export const RequeryButton = (props: TRequeryButton) => {
|
||||
const { requery, bg = 'secondary', ...rest } = props;
|
||||
return (
|
||||
<Tooltip hasArrow label="Reload Query" placement="top">
|
||||
<Button mx={1} as="a" size="sm" zIndex="1" variantColor={bg} onClick={requery} {...rest}>
|
||||
<Icon as={Repeat} boxSize="16px" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
@@ -1,5 +1,12 @@
|
||||
import { BoxProps } from '@chakra-ui/react';
|
||||
import type { BoxProps, ButtonProps } from '@chakra-ui/react';
|
||||
|
||||
export interface TCopyButton extends ButtonProps {
|
||||
copyValue: string;
|
||||
}
|
||||
|
||||
export interface TColorModeToggle extends ButtonProps {
|
||||
size?: string;
|
||||
}
|
||||
export type TButtonSizeMap = {
|
||||
xs: BoxProps;
|
||||
sm: BoxProps;
|
||||
@@ -15,3 +22,7 @@ export interface TSubmitButton extends BoxProps {
|
||||
size: keyof TButtonSizeMap;
|
||||
loadingText: string;
|
||||
}
|
||||
|
||||
export interface TRequeryButton extends ButtonProps {
|
||||
requery(): void;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
export * from './copyButton';
|
@@ -1,5 +0,0 @@
|
||||
import type { ButtonProps } from '@chakra-ui/react';
|
||||
|
||||
export interface TCopyButton extends ButtonProps {
|
||||
copyValue: string;
|
||||
}
|
@@ -1,55 +1,48 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Button,
|
||||
Tag,
|
||||
Modal,
|
||||
Stack,
|
||||
Button,
|
||||
useTheme,
|
||||
ModalBody,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
Stack,
|
||||
Tag,
|
||||
useDisclosure,
|
||||
useColorMode,
|
||||
useTheme,
|
||||
} from '@chakra-ui/core';
|
||||
import { useConfig, useMedia } from 'app/context';
|
||||
import { CodeBlock } from 'app/components';
|
||||
|
||||
const prettyMediaSize = {
|
||||
sm: 'SMALL',
|
||||
md: 'MEDIUM',
|
||||
lg: 'LARGE',
|
||||
xl: 'X-LARGE',
|
||||
};
|
||||
useDisclosure,
|
||||
ModalCloseButton,
|
||||
} from '@chakra-ui/react';
|
||||
import { useConfig, useColorValue, useBreakpointValue } from '~/context';
|
||||
import { CodeBlock } from '~/components';
|
||||
|
||||
export const Debugger = () => {
|
||||
const { isOpen: configOpen, onOpen: onConfigOpen, onClose: configClose } = useDisclosure();
|
||||
const { isOpen: themeOpen, onOpen: onThemeOpen, onClose: themeClose } = useDisclosure();
|
||||
const { colorMode } = useColorMode();
|
||||
const config = useConfig();
|
||||
const theme = useTheme();
|
||||
const bg = { light: 'white', dark: 'black' };
|
||||
const color = { light: 'black', dark: 'white' };
|
||||
const { colorMode } = useColorMode();
|
||||
const { mediaSize } = useMedia();
|
||||
const borderColor = { light: 'gray.100', dark: 'gray.600' };
|
||||
const bg = useColorValue('white', 'black');
|
||||
const color = useColorValue('black', 'white');
|
||||
const borderColor = useColorValue('gray.100', 'gray.600');
|
||||
const mediaSize =
|
||||
useBreakpointValue({ base: 'SMALL', md: 'MEDIUM', lg: 'LARGE', xl: 'X-LARGE' }) ?? 'UNKNOWN';
|
||||
return (
|
||||
<>
|
||||
<Stack
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor[colorMode]}
|
||||
py={4}
|
||||
px={4}
|
||||
isInline
|
||||
position="relative"
|
||||
left={0}
|
||||
right={0}
|
||||
bottom={0}
|
||||
justifyContent="center"
|
||||
maxW="100%"
|
||||
zIndex={1000}
|
||||
maxW="100%">
|
||||
borderWidth="1px"
|
||||
position="relative"
|
||||
justifyContent="center"
|
||||
borderColor={borderColor}>
|
||||
<Tag variantColor="gray">{colorMode.toUpperCase()}</Tag>
|
||||
<Tag variantColor="teal">{prettyMediaSize[mediaSize]}</Tag>
|
||||
<Tag variantColor="teal">{mediaSize}</Tag>
|
||||
<Button size="sm" variantColor="cyan" onClick={onConfigOpen}>
|
||||
View Config
|
||||
</Button>
|
||||
@@ -59,12 +52,7 @@ export const Debugger = () => {
|
||||
</Stack>
|
||||
<Modal isOpen={configOpen} onClose={configClose} size="full">
|
||||
<ModalOverlay />
|
||||
<ModalContent
|
||||
bg={bg[colorMode]}
|
||||
color={color[colorMode]}
|
||||
py={4}
|
||||
borderRadius="md"
|
||||
maxW="90%">
|
||||
<ModalContent bg={bg} color={color} py={4} borderRadius="md" maxW="90%">
|
||||
<ModalHeader>Loaded Configuration</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
@@ -74,12 +62,7 @@ export const Debugger = () => {
|
||||
</Modal>
|
||||
<Modal isOpen={themeOpen} onClose={themeClose} size="full">
|
||||
<ModalOverlay />
|
||||
<ModalContent
|
||||
bg={bg[colorMode]}
|
||||
color={color[colorMode]}
|
||||
py={4}
|
||||
borderRadius="md"
|
||||
maxW="90%">
|
||||
<ModalContent bg={bg} color={color} py={4} borderRadius="md" maxW="90%">
|
||||
<ModalHeader>Loaded Theme</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
44
hyperglass/ui/components/form/field.tsx
Normal file
44
hyperglass/ui/components/form/field.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Flex, FormControl, FormLabel, FormErrorMessage } from '@chakra-ui/react';
|
||||
import { If } from '~/components';
|
||||
import { useColorValue } from '~/context';
|
||||
import { useBooleanValue } from '~/hooks';
|
||||
|
||||
import { TField } from './types';
|
||||
|
||||
export const FormField = (props: TField) => {
|
||||
const { label, name, error, hiddenLabels, labelAddOn, fieldAddOn, children, ...rest } = props;
|
||||
const labelColor = useColorValue('blackAlpha.700', 'whiteAlpha.700');
|
||||
const opacity = useBooleanValue(hiddenLabels, 0, undefined);
|
||||
return (
|
||||
<FormControl
|
||||
mx={2}
|
||||
d="flex"
|
||||
w="100%"
|
||||
maxW="100%"
|
||||
flexDir="column"
|
||||
my={{ base: 2, lg: 4 }}
|
||||
isInvalid={typeof error !== 'undefined'}
|
||||
flex={{ base: '1 0 100%', lg: '1 0 33.33%' }}
|
||||
{...rest}>
|
||||
<FormLabel
|
||||
pl={1}
|
||||
pr={0}
|
||||
htmlFor={name}
|
||||
display="flex"
|
||||
opacity={opacity}
|
||||
color={labelColor}
|
||||
alignItems="center"
|
||||
justifyContent="space-between">
|
||||
{label}
|
||||
<If c={typeof labelAddOn !== 'undefined'}>{labelAddOn}</If>
|
||||
</FormLabel>
|
||||
{children}
|
||||
<If c={typeof fieldAddOn !== 'undefined'}>
|
||||
<Flex justify="flex-end" pt={3}>
|
||||
{fieldAddOn}
|
||||
</Flex>
|
||||
</If>
|
||||
<FormErrorMessage opacity={opacity}>{error && error.message}</FormErrorMessage>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
1
hyperglass/ui/components/form/index.ts
Normal file
1
hyperglass/ui/components/form/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './field';
|
11
hyperglass/ui/components/form/types.ts
Normal file
11
hyperglass/ui/components/form/types.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { FormControlProps } from '@chakra-ui/react';
|
||||
import type { FieldError } from 'react-hook-form';
|
||||
|
||||
export interface TField extends FormControlProps {
|
||||
name: string;
|
||||
label: string;
|
||||
error?: FieldError;
|
||||
hiddenLabels: boolean;
|
||||
labelAddOn?: React.ReactNode;
|
||||
fieldAddOn?: React.ReactNode;
|
||||
}
|
62
hyperglass/ui/components/greeting/greeting.tsx
Normal file
62
hyperglass/ui/components/greeting/greeting.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import {
|
||||
Modal,
|
||||
Button,
|
||||
ModalBody,
|
||||
ModalHeader,
|
||||
ModalFooter,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
useDisclosure,
|
||||
ModalCloseButton,
|
||||
} from '@chakra-ui/react';
|
||||
import { If, Markdown } from '~/components';
|
||||
import { useConfig, useColorValue } from '~/context';
|
||||
|
||||
import type { TGreeting } from './types';
|
||||
|
||||
export const Greeting = (props: TGreeting) => {
|
||||
const { onClickThrough, ...rest } = props;
|
||||
const { web, content } = useConfig();
|
||||
const { isOpen, onClose } = useDisclosure();
|
||||
|
||||
const bg = useColorValue('white', 'black');
|
||||
const color = useColorValue('black', 'white');
|
||||
|
||||
function handleClick(): void {
|
||||
onClickThrough();
|
||||
onClose();
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isCentered
|
||||
size="full"
|
||||
isOpen={isOpen}
|
||||
onClose={handleClick}
|
||||
closeOnEsc={!web.greeting.required}
|
||||
closeOnOverlayClick={!web.greeting.required}>
|
||||
<ModalOverlay />
|
||||
<ModalContent
|
||||
py={4}
|
||||
bg={bg}
|
||||
color={color}
|
||||
borderRadius="md"
|
||||
maxW={{ base: '95%', md: '75%' }}
|
||||
{...rest}>
|
||||
<ModalHeader>{web.greeting.title}</ModalHeader>
|
||||
<If c={!web.greeting.required}>
|
||||
<ModalCloseButton />
|
||||
</If>
|
||||
<ModalBody>
|
||||
<Markdown content={content.greeting} />
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button colorScheme="primary" onClick={handleClick}>
|
||||
{web.greeting.button}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
};
|
1
hyperglass/ui/components/greeting/index.ts
Normal file
1
hyperglass/ui/components/greeting/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './greeting';
|
5
hyperglass/ui/components/greeting/types.ts
Normal file
5
hyperglass/ui/components/greeting/types.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { BoxProps } from '@chakra-ui/react';
|
||||
|
||||
export interface TGreeting extends BoxProps {
|
||||
onClickThrough(): void;
|
||||
}
|
@@ -1,35 +1,29 @@
|
||||
export * from './animated';
|
||||
export * from './bgpTable';
|
||||
export * from './buttons';
|
||||
export * from './card';
|
||||
export * from './ChakraSelect';
|
||||
export * from './codeBlock';
|
||||
export * from './ColorModeToggle';
|
||||
export * from './CommunitySelect';
|
||||
export * from './copyButton';
|
||||
export * from './countdown';
|
||||
export * from './Debugger';
|
||||
export * from './debugger';
|
||||
export * from './footer';
|
||||
export * from './FormField';
|
||||
export * from './Greeting';
|
||||
export * from './form';
|
||||
export * from './greeting';
|
||||
export * from './header';
|
||||
export * from './HelpModal';
|
||||
export * from './HyperglassForm';
|
||||
export * from './label';
|
||||
export * from './Layout';
|
||||
export * from './layout';
|
||||
export * from './loading';
|
||||
export * from './LookingGlass';
|
||||
export * from './markdown';
|
||||
export * from './meta';
|
||||
export * from './output';
|
||||
export * from './QueryLocation';
|
||||
export * from './QueryTarget';
|
||||
export * from './QueryType';
|
||||
export * from './QueryVrf';
|
||||
export * from './RequeryButton';
|
||||
export * from './resetButton';
|
||||
export * from './ResolvedTarget';
|
||||
export * from './results';
|
||||
export * from './submitButton';
|
||||
export * from './table';
|
||||
export * from './textOutput';
|
||||
export * from './Title';
|
||||
export * from './util';
|
||||
|
58
hyperglass/ui/components/layout.tsx
Normal file
58
hyperglass/ui/components/layout.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import { useRef } from 'react';
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { useConfig, useColorValue, useGlobalState } from '~/context';
|
||||
import { If, Debugger, Greeting, Footer, Header } from '~/components';
|
||||
import { useGreeting } from '~/hooks';
|
||||
|
||||
export const Layout: React.FC = props => {
|
||||
const { web, developer_mode } = useConfig();
|
||||
const { isSubmitting, formData } = useGlobalState();
|
||||
const [greetingAck, setGreetingAck] = useGreeting();
|
||||
|
||||
const bg = useColorValue('white', 'black');
|
||||
const color = useColorValue('black', 'white');
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>({} as HTMLDivElement);
|
||||
|
||||
function resetForm(): void {
|
||||
containerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
isSubmitting.set(false);
|
||||
formData.set({ query_location: [], query_target: '', query_type: '', query_vrf: '' });
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
bg={bg}
|
||||
w="100%"
|
||||
color={color}
|
||||
minHeight="100vh"
|
||||
ref={containerRef}
|
||||
flexDirection="column">
|
||||
<Flex px={2} flex="0 1 auto" flexDirection="column">
|
||||
<Header resetForm={resetForm} />
|
||||
</Flex>
|
||||
<Flex
|
||||
px={2}
|
||||
py={0}
|
||||
w="100%"
|
||||
as="main"
|
||||
align="center"
|
||||
flex="1 1 auto"
|
||||
justify="start"
|
||||
flexDir="column"
|
||||
textAlign="center"
|
||||
{...props}
|
||||
/>
|
||||
<Footer />
|
||||
<If c={developer_mode}>
|
||||
<Debugger />
|
||||
</If>
|
||||
</Flex>
|
||||
<If c={web.greeting.enable && !greetingAck}>
|
||||
<Greeting onClickThrough={setGreetingAck} />
|
||||
</If>
|
||||
</>
|
||||
);
|
||||
};
|
@@ -1 +1,2 @@
|
||||
export * from './table';
|
||||
export * from './text';
|
@@ -1,6 +1,10 @@
|
||||
import type { FlexProps, TextProps } from '@chakra-ui/react';
|
||||
import type { BoxProps, FlexProps, TextProps } from '@chakra-ui/react';
|
||||
import type { CellProps } from 'react-table';
|
||||
|
||||
export interface TTextOutput extends Omit<BoxProps, 'children'> {
|
||||
children: string;
|
||||
}
|
||||
|
||||
export interface TActive {
|
||||
isActive: boolean;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
export * from './submitButton';
|
@@ -1 +0,0 @@
|
||||
export * from './textOutput';
|
@@ -1,5 +0,0 @@
|
||||
import type { BoxProps } from '@chakra-ui/react';
|
||||
|
||||
export interface TTextOutput extends Omit<BoxProps, 'children'> {
|
||||
children: string;
|
||||
}
|
@@ -34,4 +34,8 @@ export const useMobile = (): boolean =>
|
||||
export const useColorToken = (light: string, dark: string): ValueOf<ITheme['colors']> =>
|
||||
useColorModeValue(useToken('colors', light), useToken('colors', dark));
|
||||
|
||||
export { useColorModeValue as useColorValue, useBreakpointValue } from '@chakra-ui/react';
|
||||
export {
|
||||
useColorMode,
|
||||
useBreakpointValue,
|
||||
useColorModeValue as useColorValue,
|
||||
} from '@chakra-ui/react';
|
||||
|
@@ -1,5 +1,6 @@
|
||||
export * from './useStrf';
|
||||
export * from './useBooleanValue';
|
||||
export * from './useGreeting';
|
||||
export * from './useOpposingColor';
|
||||
export * from './useTableToString';
|
||||
export * from './useSessionStorage';
|
||||
export * from './useStrf';
|
||||
export * from './useTableToString';
|
||||
|
@@ -6,3 +6,5 @@ export interface TOpposingOptions {
|
||||
export interface TStringTableData extends Omit<TQueryResponse, 'output'> {
|
||||
output: TStructuredResponse;
|
||||
}
|
||||
|
||||
export type TUseGreetingReturn = [boolean, () => void];
|
||||
|
18
hyperglass/ui/hooks/useGreeting.ts
Normal file
18
hyperglass/ui/hooks/useGreeting.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { useState } from '@hookstate/core';
|
||||
import { Persistence } from '@hookstate/persistence';
|
||||
|
||||
import type { TUseGreetingReturn } from './types';
|
||||
|
||||
export function useGreeting(): TUseGreetingReturn {
|
||||
const state = useState<boolean>(false);
|
||||
state.attach(Persistence('plugin-persisted-data-key'));
|
||||
|
||||
function setAck(): void {
|
||||
if (!state.get()) {
|
||||
state.set(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return [state.value, setAck];
|
||||
}
|
1
hyperglass/ui/package.json
vendored
1
hyperglass/ui/package.json
vendored
@@ -19,6 +19,7 @@
|
||||
"@emotion/react": "^11.1.1",
|
||||
"@emotion/styled": "^11.0.0",
|
||||
"@hookstate/core": "^3.0.1",
|
||||
"@hookstate/persistence": "^3.0.0",
|
||||
"@meronex/icons": "^4.0.0",
|
||||
"add": "^2.0.6",
|
||||
"axios": "^0.19.2",
|
||||
|
@@ -42,11 +42,18 @@ export interface IConfigWebText {
|
||||
rpki_unverified: string;
|
||||
}
|
||||
|
||||
export interface TConfigGreeting {
|
||||
enable: boolean;
|
||||
title: string;
|
||||
button: string;
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export interface IConfigWeb {
|
||||
credit: { enable: boolean };
|
||||
dns_provider: { name: string; url: string };
|
||||
external_link: { enable: boolean; title: string; url: string };
|
||||
greeting: { enable: boolean; title: string; button: string; required: boolean };
|
||||
greeting: TConfigGreeting;
|
||||
help_menu: { enable: boolean; title: string };
|
||||
logo: { width: string; height: string | null; light_format: string; dark_format: string };
|
||||
terms: { enable: boolean; title: string };
|
||||
|
5
hyperglass/ui/yarn.lock
vendored
5
hyperglass/ui/yarn.lock
vendored
@@ -1790,6 +1790,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@hookstate/core/-/core-3.0.1.tgz#dc46ea71e3bf0ab5c2dc024029c9210ed12fbb84"
|
||||
integrity sha512-buRie83l3FYPLCuaBE68puE3XS19r2O+jwC/kH2ikIW7ww8AavndR3MspzMMkNpq2zL8pZtIcpiWJBbn4Uq2Vw==
|
||||
|
||||
"@hookstate/persistence@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@hookstate/persistence/-/persistence-3.0.0.tgz#973b30d3a3bb1b29f4f59b1afe0d914e71a23882"
|
||||
integrity sha512-xiN22IW0Wjw/uTV1OEUpTtqB8DAJyRobYR3+iv1TyMf72o98KpaZqQrLPvXkfrjlZac5s052BypjpkttX/Cmhw==
|
||||
|
||||
"@meronex/icons@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@meronex/icons/-/icons-4.0.0.tgz#26e089a8a4ec176a5b6778fd54fcdd25b4746c67"
|
||||
|
Reference in New Issue
Block a user