Commit 2b22bfc2 authored by tom's avatar tom

links refactoring and showcases

parent b740a53f
...@@ -26,6 +26,8 @@ const RESTRICTED_MODULES = { ...@@ -26,6 +26,8 @@ const RESTRICTED_MODULES = {
{ name: '@metamask/post-message-stream', message: 'Please lazy-load @metamask/post-message-stream or use useProvider hook instead' }, { name: '@metamask/post-message-stream', message: 'Please lazy-load @metamask/post-message-stream or use useProvider hook instead' },
{ name: 'playwright/TestApp', message: 'Please use render() fixture from test() function of playwright/lib module' }, { name: 'playwright/TestApp', message: 'Please use render() fixture from test() function of playwright/lib module' },
{ name: 'ui/shared/chakra/Skeleton', message: 'Please use Skeleton component from toolkit/chakra instead' }, { name: 'ui/shared/chakra/Skeleton', message: 'Please use Skeleton component from toolkit/chakra instead' },
{ name: 'ui/shared/links/LinkInternal', message: 'Please use Link component from toolkit/chakra instead' },
{ name: 'ui/shared/links/LinkExternal', message: 'Please use Link component from toolkit/chakra instead' },
{ {
name: '@chakra-ui/react', name: '@chakra-ui/react',
importNames: [ importNames: [
......
import type { LinkProps as ChakraLinkProps } from '@chakra-ui/react';
import { Link as ChakraLink } from '@chakra-ui/react';
import NextLink from 'next/link';
import type { LinkProps as NextLinkProps } from 'next/link';
import React from 'react';
import IconSvg from 'ui/shared/IconSvg';
import { Skeleton } from './skeleton';
export interface LinkProps extends ChakraLinkProps {
loading?: boolean;
external?: boolean;
scroll?: boolean;
iconColor?: ChakraLinkProps['color'];
}
export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
function Link(props, ref) {
const { external, loading, href, children, scroll = true, iconColor, ...rest } = props;
if (external) {
return (
<Skeleton loading={ loading } asChild>
<ChakraLink
ref={ ref }
href={ href }
className="group"
target="_blank"
rel="noopener noreferrer" { ...rest }
>
{ children }
<IconSvg
name="link_external"
boxSize={ 3 }
verticalAlign="middle"
color={ iconColor ?? 'icon.externalLink' }
_groupHover={{
color: 'inherit',
}}
flexShrink={ 0 }
/>
</ChakraLink>
</Skeleton>
);
}
return (
<Skeleton loading={ loading } asChild>
<ChakraLink asChild ref={ ref } { ...rest }>
{ href ? <NextLink href={ href as NextLinkProps['href'] } scroll={ scroll }>{ children }</NextLink> : <span>{ children }</span> }
</ChakraLink>
</Skeleton>
);
},
);
...@@ -47,6 +47,6 @@ export const SkeletonText = React.forwardRef<HTMLDivElement, SkeletonTextProps>( ...@@ -47,6 +47,6 @@ export const SkeletonText = React.forwardRef<HTMLDivElement, SkeletonTextProps>(
export const Skeleton = React.forwardRef<HTMLDivElement, ChakraSkeletonProps>( export const Skeleton = React.forwardRef<HTMLDivElement, ChakraSkeletonProps>(
function Skeleton(props, ref) { function Skeleton(props, ref) {
const { loading = false, ...rest } = props; const { loading = false, ...rest } = props;
return <ChakraSkeleton loading={ loading } { ...rest } ref={ ref }/>; return <ChakraSkeleton loading={ loading } { ...(loading ? { 'data-loading': true } : {}) } { ...rest } ref={ ref }/>;
}, },
); );
import React from 'react';
import { scroller, Element } from 'react-scroll';
import { Link } from 'toolkit/chakra/link';
interface Props {
children: React.ReactNode;
id?: string;
onClick?: () => void;
isLoading?: boolean;
}
const ID = 'CutLink';
const CutLink = (props: Props) => {
const { children, id = ID, onClick, isLoading } = props;
const [ isExpanded, setIsExpanded ] = React.useState(false);
const handleClick = React.useCallback(() => {
setIsExpanded((flag) => !flag);
scroller.scrollTo(id, {
duration: 500,
smooth: true,
});
onClick?.();
}, [ id, onClick ]);
return (
<>
<Element name={ id }>
<Link
textStyle="sm"
textDecorationLine="underline"
textDecorationStyle="dashed"
onClick={ handleClick }
loading={ isLoading }
>
{ isExpanded ? 'Hide details' : 'View details' }
</Link>
</Element>
{ isExpanded && children }
</>
);
};
export default React.memo(CutLink);
...@@ -89,6 +89,9 @@ const semanticTokens: ThemingConfig['semanticTokens'] = { ...@@ -89,6 +89,9 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
secondary: { secondary: {
DEFAULT: { value: { _light: '{colors.gray.400}', _dark: '{colors.gray.500}' } }, DEFAULT: { value: { _light: '{colors.gray.400}', _dark: '{colors.gray.500}' } },
}, },
underlaid: {
bg: { value: { _light: '{colors.gray.100}', _dark: '{colors.gray.800}' } },
},
subtle: { subtle: {
DEFAULT: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.gray.400}' } }, DEFAULT: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.gray.400}' } },
hover: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.gray.400}' } }, hover: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.gray.400}' } },
...@@ -306,6 +309,7 @@ const semanticTokens: ThemingConfig['semanticTokens'] = { ...@@ -306,6 +309,7 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
}, },
icon: { icon: {
backTo: { value: '{colors.gray.400}' }, backTo: { value: '{colors.gray.400}' },
externalLink: { value: { _light: '{colors.gray.400}', _dark: '{colors.gray.400}' } },
}, },
global: { global: {
body: { body: {
......
...@@ -5,7 +5,7 @@ export const recipe = defineRecipe({ ...@@ -5,7 +5,7 @@ export const recipe = defineRecipe({
gap: 0, gap: 0,
}, },
variants: { variants: {
visual: { variant: {
primary: { primary: {
color: 'link.primary', color: 'link.primary',
_hover: { _hover: {
...@@ -24,9 +24,27 @@ export const recipe = defineRecipe({ ...@@ -24,9 +24,27 @@ export const recipe = defineRecipe({
color: 'link.subtle', color: 'link.subtle',
_hover: { _hover: {
color: 'link.subtle.hover', color: 'link.subtle.hover',
textDecorationLine: 'underline',
textDecorationColor: 'link.subtle.hover', textDecorationColor: 'link.subtle.hover',
}, },
}, },
underlaid: {
color: 'link.primary',
// css-var to override bg property on loaded skeleton
'--layer-bg': '{colors.link.underlaid.bg}',
bgColor: 'link.underlaid.bg',
px: '8px',
py: '6px',
borderRadius: 'base',
textStyle: 'sm',
_hover: {
color: 'link.primary.hover',
textDecoration: 'none',
},
_loading: {
bgColor: 'transparent',
},
},
navigation: { navigation: {
color: 'link.navigation.fg', color: 'link.navigation.fg',
bg: 'link.navigation.bg', bg: 'link.navigation.bg',
...@@ -47,6 +65,6 @@ export const recipe = defineRecipe({ ...@@ -47,6 +65,6 @@ export const recipe = defineRecipe({
}, },
}, },
defaultVariants: { defaultVariants: {
visual: 'primary', variant: 'primary',
}, },
}); });
...@@ -19,7 +19,7 @@ export const recipe = defineRecipe({ ...@@ -19,7 +19,7 @@ export const recipe = defineRecipe({
}, },
}, },
'false': { 'false': {
background: 'unset', background: 'var(--layer-bg)',
animation: 'fade-in var(--fade-duration, 0.1s) ease-out !important', animation: 'fade-in var(--fade-duration, 0.1s) ease-out !important',
}, },
}, },
......
...@@ -72,6 +72,8 @@ export const recipe = defineSlotRecipe({ ...@@ -72,6 +72,8 @@ export const recipe = defineSlotRecipe({
boxShadow: 'popover', boxShadow: 'popover',
boxShadowColor: 'popover.shadow', boxShadowColor: 'popover.shadow',
borderRadius: 'md', borderRadius: 'md',
textAlign: 'left',
fontWeight: 'normal',
}, },
}, },
}, },
......
...@@ -31,6 +31,12 @@ const customConfig = defineConfig({ ...@@ -31,6 +31,12 @@ const customConfig = defineConfig({
fonts, fonts,
shadows, shadows,
zIndex, zIndex,
fontWeights: {
normal: { value: '400' },
medium: { value: '500' },
semibold: { value: '600' },
bold: { value: '700' },
},
}, },
}, },
// components, // components,
......
...@@ -25,6 +25,7 @@ import PageTitle from 'ui/shared/Page/PageTitle'; ...@@ -25,6 +25,7 @@ import PageTitle from 'ui/shared/Page/PageTitle';
import AlertsShowcase from 'ui/showcases/Alerts'; import AlertsShowcase from 'ui/showcases/Alerts';
import BadgesShowcase from 'ui/showcases/Badges'; import BadgesShowcase from 'ui/showcases/Badges';
import ButtonShowcase from 'ui/showcases/Button'; import ButtonShowcase from 'ui/showcases/Button';
import LinksShowcase from 'ui/showcases/Links';
import PaginationShowcase from 'ui/showcases/Pagination'; import PaginationShowcase from 'ui/showcases/Pagination';
import TabsShowcase from 'ui/showcases/Tabs'; import TabsShowcase from 'ui/showcases/Tabs';
...@@ -54,6 +55,7 @@ const ChakraShowcases = () => { ...@@ -54,6 +55,7 @@ const ChakraShowcases = () => {
<TabsTrigger value="alerts">Alerts</TabsTrigger> <TabsTrigger value="alerts">Alerts</TabsTrigger>
<TabsTrigger value="badges">Badges</TabsTrigger> <TabsTrigger value="badges">Badges</TabsTrigger>
<TabsTrigger value="buttons">Buttons</TabsTrigger> <TabsTrigger value="buttons">Buttons</TabsTrigger>
<TabsTrigger value="links">Links</TabsTrigger>
<TabsTrigger value="pagination">Pagination</TabsTrigger> <TabsTrigger value="pagination">Pagination</TabsTrigger>
<TabsTrigger value="tabs">Tabs</TabsTrigger> <TabsTrigger value="tabs">Tabs</TabsTrigger>
<TabsTrigger value="unsorted">Unsorted</TabsTrigger> <TabsTrigger value="unsorted">Unsorted</TabsTrigger>
...@@ -61,6 +63,7 @@ const ChakraShowcases = () => { ...@@ -61,6 +63,7 @@ const ChakraShowcases = () => {
<AlertsShowcase/> <AlertsShowcase/>
<BadgesShowcase/> <BadgesShowcase/>
<ButtonShowcase/> <ButtonShowcase/>
<LinksShowcase/>
<TabsShowcase/> <TabsShowcase/>
<PaginationShowcase/> <PaginationShowcase/>
......
...@@ -48,7 +48,7 @@ const CopyToClipboard = ({ text, className, isLoading, onClick, size = 5, type, ...@@ -48,7 +48,7 @@ const CopyToClipboard = ({ text, className, isLoading, onClick, size = 5, type,
}, [ onClick, copy ]); }, [ onClick, copy ]);
if (isLoading) { if (isLoading) {
return <Skeleton boxSize={ size } className={ className } borderRadius="sm" flexShrink={ 0 } ml={ 2 } display="inline-block"/>; return <Skeleton boxSize={ size } className={ className } borderRadius="sm" flexShrink={ 0 } ml={ 2 } display="inline-block" loading/>;
} }
return ( return (
......
...@@ -48,7 +48,7 @@ const Icon = (props: IconProps) => { ...@@ -48,7 +48,7 @@ const Icon = (props: IconProps) => {
}; };
if (props.isLoading) { if (props.isLoading) {
return <Skeleton { ...styles } borderRadius="full" flexShrink={ 0 }/>; return <Skeleton { ...styles } loading borderRadius="full" flexShrink={ 0 }/>;
} }
if (props.address.is_contract) { if (props.address.is_contract) {
......
import { Box } from '@chakra-ui/react'; import { Box, Flex } from '@chakra-ui/react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import React from 'react'; import React from 'react';
...@@ -53,7 +53,7 @@ const Icon = dynamic( ...@@ -53,7 +53,7 @@ const Icon = dynamic(
return (props: IconProps) => { return (props: IconProps) => {
const svg = GradientAvatar(props.hash, props.size, 'circle'); const svg = GradientAvatar(props.hash, props.size, 'circle');
return <div dangerouslySetInnerHTML={{ __html: svg }}/>; return <Flex dangerouslySetInnerHTML={{ __html: svg }}/>;
}; };
} }
......
...@@ -31,6 +31,7 @@ export interface EntityBaseProps { ...@@ -31,6 +31,7 @@ export interface EntityBaseProps {
tailLength?: number; tailLength?: number;
target?: React.HTMLAttributeAnchorTarget; target?: React.HTMLAttributeAnchorTarget;
truncation?: Truncation; truncation?: Truncation;
size?: 'md' | 'lg';
} }
export interface ContainerBaseProps extends Pick<EntityBaseProps, 'className'> { export interface ContainerBaseProps extends Pick<EntityBaseProps, 'className'> {
...@@ -165,9 +166,9 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna ...@@ -165,9 +166,9 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna
); );
}); });
export type CopyBaseProps = Pick<CopyToClipboardProps, 'isLoading' | 'text'> & Pick<EntityBaseProps, 'noCopy'>; export type CopyBaseProps = Pick<CopyToClipboardProps, 'isLoading' | 'text'> & Pick<EntityBaseProps, 'noCopy' | 'size'>;
const Copy = (props: CopyBaseProps) => { const Copy = ({ size, ...props }: CopyBaseProps) => {
if (props.noCopy) { if (props.noCopy) {
return null; return null;
} }
......
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
...@@ -76,7 +75,7 @@ const BlobEntity = (props: EntityProps) => { ...@@ -76,7 +75,7 @@ const BlobEntity = (props: EntityProps) => {
); );
}; };
export default React.memo(chakra<As, EntityProps>(BlobEntity)); export default React.memo(chakra(BlobEntity));
export { export {
Container, Container,
......
import type { As } from '@chakra-ui/react'; import { chakra, Flex, Text } from '@chakra-ui/react';
import { Box, chakra, Flex, Image, PopoverBody, PopoverContent, PopoverTrigger, Portal, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type * as bens from '@blockscout/bens-types'; import type * as bens from '@blockscout/bens-types';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import Popover from 'ui/shared/chakra/Popover'; import { Image } from 'toolkit/chakra/image';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Link as LinkToolkit } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tooltip } from 'toolkit/chakra/tooltip';
import * as EntityBase from 'ui/shared/entities/base/components'; import * as EntityBase from 'ui/shared/entities/base/components';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import LinkExternal from 'ui/shared/links/LinkExternal';
import TruncatedValue from 'ui/shared/TruncatedValue'; import TruncatedValue from 'ui/shared/TruncatedValue';
import { distributeEntityProps, getIconProps } from '../base/utils'; import { distributeEntityProps, getIconProps } from '../base/utils';
...@@ -39,28 +39,12 @@ const Icon = (props: IconProps) => { ...@@ -39,28 +39,12 @@ const Icon = (props: IconProps) => {
const styles = getIconProps(props.size); const styles = getIconProps(props.size);
if (props.isLoading) { if (props.isLoading) {
return <Skeleton boxSize={ styles.boxSize } borderRadius="sm" mr={ 2 }/>; return <Skeleton loading boxSize={ styles.boxSize } borderRadius="sm" mr={ 2 }/>;
} }
return ( const content = (
<Popover trigger="hover" isLazy placement="bottom-start"> <>
<PopoverTrigger> <Flex alignItems="center" textStyle="md">
<Box flexShrink={ 0 }>
<Image
src={ props.protocol.icon_url }
boxSize={ styles.boxSize }
borderRadius="sm"
mr={ 2 }
alt={ `${ props.protocol.title } protocol icon` }
fallback={ icon }
fallbackStrategy={ props.protocol.icon_url ? 'onError' : 'beforeLoadOrError' }
/>
</Box>
</PopoverTrigger>
<Portal>
<PopoverContent maxW={{ base: '100vw', lg: '440px' }} minW="250px" w="fit-content">
<PopoverBody display="flex" flexDir="column" rowGap={ 3 }>
<Flex alignItems="center">
<Image <Image
src={ props.protocol.icon_url } src={ props.protocol.icon_url }
boxSize={ 5 } boxSize={ 5 }
...@@ -68,29 +52,58 @@ const Icon = (props: IconProps) => { ...@@ -68,29 +52,58 @@ const Icon = (props: IconProps) => {
mr={ 2 } mr={ 2 }
alt={ `${ props.protocol.title } protocol icon` } alt={ `${ props.protocol.title } protocol icon` }
fallback={ icon } fallback={ icon }
fallbackStrategy={ props.protocol.icon_url ? 'onError' : 'beforeLoadOrError' } // fallbackStrategy={ props.protocol.icon_url ? 'onError' : 'beforeLoadOrError' }
/> />
<div> <div>
<span>{ props.protocol.short_name }</span> <span>{ props.protocol.short_name }</span>
<chakra.span color="text_secondary" whiteSpace="pre"> { props.protocol.tld_list.map((tld) => `.${ tld }`).join((' ')) }</chakra.span> <chakra.span color="text_secondary" whiteSpace="pre"> { props.protocol.tld_list.map((tld) => `.${ tld }`).join((' ')) }</chakra.span>
</div> </div>
</Flex> </Flex>
<Text fontSize="sm">{ props.protocol.description }</Text> <Text>{ props.protocol.description }</Text>
{ props.protocol.docs_url && ( { props.protocol.docs_url && (
<LinkExternal <LinkToolkit
href={ props.protocol.docs_url } href={ props.protocol.docs_url }
display="inline-flex" display="inline-flex"
alignItems="center" alignItems="center"
fontSize="sm" external
> >
<IconSvg name="docs" boxSize={ 5 } color="text_secondary" mr={ 2 }/> { /* TODO @tom2drum maybe refactor this to pass icon as a prop */ }
<IconSvg name="docs" boxSize={ 5 } color="text.secondary" mr={ 2 }/>
<span>Documentation</span> <span>Documentation</span>
</LinkExternal> </LinkToolkit>
) } ) }
</PopoverBody> </>
</PopoverContent> );
</Portal>
</Popover> return (
<Tooltip
content={ content }
visual="popover"
positioning={{
placement: 'bottom-start',
}}
contentProps={{
maxW: { base: '100vw', lg: '440px' },
minW: '250px',
w: 'fit-content',
display: 'flex',
flexDir: 'column',
rowGap: 3,
alignItems: 'flex-start',
}}
interactive
>
<Image
src={ props.protocol.icon_url }
boxSize={ styles.boxSize }
borderRadius="sm"
mr={ 2 }
flexShrink={ 0 }
alt={ `${ props.protocol.title } protocol icon` }
fallback={ icon }
// fallbackStrategy={ props.protocol.icon_url ? 'onError' : 'beforeLoadOrError' }
/>
</Tooltip>
); );
} }
...@@ -140,7 +153,7 @@ const EnsEntity = (props: EntityProps) => { ...@@ -140,7 +153,7 @@ const EnsEntity = (props: EntityProps) => {
); );
}; };
export default React.memo(chakra<As, EntityProps>(EnsEntity)); export default React.memo(chakra(EnsEntity));
export { export {
Container, Container,
......
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
...@@ -69,7 +68,7 @@ const NftEntity = (props: EntityProps) => { ...@@ -69,7 +68,7 @@ const NftEntity = (props: EntityProps) => {
); );
}; };
export default React.memo(chakra<As, EntityProps>(NftEntity)); export default React.memo(chakra(NftEntity));
export { export {
Container, Container,
......
import type { As } from '@chakra-ui/react'; import { Flex, chakra } from '@chakra-ui/react';
import { Flex, chakra, useColorModeValue } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { Pool } from 'types/api/pools'; import type { Pool } from 'types/api/pools';
...@@ -7,7 +6,7 @@ import type { Pool } from 'types/api/pools'; ...@@ -7,7 +6,7 @@ import type { Pool } from 'types/api/pools';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import { getPoolTitle } from 'lib/pools/getPoolTitle'; import { getPoolTitle } from 'lib/pools/getPoolTitle';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import * as EntityBase from 'ui/shared/entities/base/components'; import * as EntityBase from 'ui/shared/entities/base/components';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip'; import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
...@@ -32,8 +31,8 @@ const Link = chakra((props: LinkProps) => { ...@@ -32,8 +31,8 @@ const Link = chakra((props: LinkProps) => {
type IconProps = Pick<EntityProps, 'pool' | 'className'> & EntityBase.IconBaseProps; type IconProps = Pick<EntityProps, 'pool' | 'className'> & EntityBase.IconBaseProps;
const Icon = (props: IconProps) => { const Icon = (props: IconProps) => {
const bgColor = useColorModeValue('white', 'black'); const bgColor = { _light: 'white', _dark: 'black' };
const borderColor = useColorModeValue('whiteAlpha.800', 'blackAlpha.800'); const borderColor = { _light: 'whiteAlpha.800', _dark: 'blackAlpha.800' };
return ( return (
<Flex> <Flex>
<Flex <Flex
...@@ -87,7 +86,7 @@ const Content = chakra((props: ContentProps) => { ...@@ -87,7 +86,7 @@ const Content = chakra((props: ContentProps) => {
return ( return (
<TruncatedTextTooltip label={ nameString }> <TruncatedTextTooltip label={ nameString }>
<Skeleton <Skeleton
isLoaded={ !props.isLoading } loading={ props.isLoading }
display="inline-block" display="inline-block"
whiteSpace="nowrap" whiteSpace="nowrap"
overflow="hidden" overflow="hidden"
...@@ -119,7 +118,7 @@ const PoolEntity = (props: EntityProps) => { ...@@ -119,7 +118,7 @@ const PoolEntity = (props: EntityProps) => {
); );
}; };
export default React.memo(chakra<As, EntityProps>(PoolEntity)); export default React.memo(chakra(PoolEntity));
export { export {
Container, Container,
......
...@@ -43,7 +43,7 @@ const Icon = (props: IconProps) => { ...@@ -43,7 +43,7 @@ const Icon = (props: IconProps) => {
}; };
if (props.isLoading) { if (props.isLoading) {
return <Skeleton { ...styles } className={ props.className }/>; return <Skeleton { ...styles } loading className={ props.className }/>;
} }
return ( return (
......
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
...@@ -76,7 +75,7 @@ const UserOpEntity = (props: EntityProps) => { ...@@ -76,7 +75,7 @@ const UserOpEntity = (props: EntityProps) => {
); );
}; };
export default React.memo(chakra<As, EntityProps>(UserOpEntity)); export default React.memo(chakra(UserOpEntity));
export { export {
Container, Container,
......
...@@ -14,12 +14,11 @@ interface Props { ...@@ -14,12 +14,11 @@ interface Props {
children: React.ReactNode; children: React.ReactNode;
isLoading?: boolean; isLoading?: boolean;
variant?: Variants; variant?: Variants;
visual?: LinkProps['visual'];
iconColor?: LinkProps['color']; iconColor?: LinkProps['color'];
onClick?: LinkProps['onClick']; onClick?: LinkProps['onClick'];
} }
const LinkExternal = ({ href, children, className, isLoading, variant, visual, iconColor, onClick }: Props) => { const LinkExternal = ({ href, children, className, isLoading, variant, iconColor, onClick }: Props) => {
const commonProps = { const commonProps = {
display: 'inline-block', display: 'inline-block',
alignItems: 'center', alignItems: 'center',
...@@ -46,7 +45,7 @@ const LinkExternal = ({ href, children, className, isLoading, variant, visual, i ...@@ -46,7 +45,7 @@ const LinkExternal = ({ href, children, className, isLoading, variant, visual, i
} }
return ( return (
<Link className={ className } { ...styleProps } target="_blank" href={ href } onClick={ onClick } visual={ visual }> <Link className={ className } { ...styleProps } target="_blank" href={ href } onClick={ onClick } variant={ variant }>
{ children } { children }
<IconSvg name="link_external" boxSize={ 3 } verticalAlign="middle" color={ iconColor ?? 'icon_link_external' } flexShrink={ 0 }/> <IconSvg name="link_external" boxSize={ 3 } verticalAlign="middle" color={ iconColor ?? 'icon_link_external' } flexShrink={ 0 }/>
</Link> </Link>
......
This diff is collapsed.
import type { StackProps, TabsContentProps } from '@chakra-ui/react'; import type { StackProps, TabsContentProps } from '@chakra-ui/react';
import { Code, Grid, HStack } from '@chakra-ui/react'; import { Code, Grid, HStack, VStack } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Heading } from 'toolkit/chakra/heading'; import { Heading } from 'toolkit/chakra/heading';
...@@ -13,16 +13,28 @@ export const SamplesStack = ({ children }: { children: React.ReactNode }) => ( ...@@ -13,16 +13,28 @@ export const SamplesStack = ({ children }: { children: React.ReactNode }) => (
<Grid <Grid
rowGap={ 4 } rowGap={ 4 }
columnGap={ 8 } columnGap={ 8 }
gridTemplateColumns="fit-content(100%) fit-content(100%)" gridTemplateColumns="fit-content(100%) 1fr"
justifyItems="flex-start" justifyItems="flex-start"
alignItems="flex-start" alignItems="flex-start"
> >
{ children } { children }
</Grid> </Grid>
); );
export const Sample = ({ children, label, ...props }: { children: React.ReactNode; label?: string } & StackProps) => ( export const Sample = ({ children, label, vertical, ...props }: { children: React.ReactNode; vertical?: boolean; label?: string } & StackProps) => {
const Stack = vertical ? VStack : HStack;
return (
<> <>
{ label && <Code w="fit-content">{ label }</Code> } { label && <Code w="fit-content">{ label }</Code> }
<HStack gap={ 3 } whiteSpace="pre-wrap" flexWrap="wrap" columnSpan={ label ? '1' : '2' } { ...props }>{ children }</HStack> <Stack
gap={ 3 }
whiteSpace="pre-wrap"
flexWrap="wrap"
columnSpan={ label ? '1' : '2' }
alignItems={ vertical ? 'flex-start' : 'center' }
{ ...props }
>
{ children }
</Stack>
</> </>
); );
};
...@@ -19,7 +19,7 @@ const FooterLinkItem = ({ icon, iconSize, text, url, isLoading }: Props) => { ...@@ -19,7 +19,7 @@ const FooterLinkItem = ({ icon, iconSize, text, url, isLoading }: Props) => {
} }
return ( return (
<Link href={ url } display="flex" alignItems="center" h="30px" visual="subtle" target="_blank" textStyle="xs"> <Link href={ url } display="flex" alignItems="center" h="30px" variant="subtle" target="_blank" textStyle="xs">
{ icon && ( { icon && (
<Center minW={ 6 } mr={ 2 }> <Center minW={ 6 } mr={ 2 }>
<IconSvg boxSize={ iconSize || 5 } name={ icon }/> <IconSvg boxSize={ iconSize || 5 } name={ icon }/>
......
...@@ -37,7 +37,7 @@ const NavLink = ({ className, item, noIcon }: Props) => { ...@@ -37,7 +37,7 @@ const NavLink = ({ className, item, noIcon }: Props) => {
href={ href } href={ href }
display="flex" display="flex"
alignItems="center" alignItems="center"
visual="navigation" variant="navigation"
{ ...(isActive ? { 'data-selected': true } : {}) } { ...(isActive ? { 'data-selected': true } : {}) }
w="224px" w="224px"
px={ 2 } px={ 2 }
......
...@@ -50,7 +50,7 @@ const NavLinkGroup = ({ item }: Props) => { ...@@ -50,7 +50,7 @@ const NavLinkGroup = ({ item }: Props) => {
visual="popover" visual="popover"
content={ content } content={ content }
onOpenChange={ onOpenChange } onOpenChange={ onOpenChange }
lazyMount lazyMount={ false }
positioning={{ positioning={{
placement: 'bottom', placement: 'bottom',
offset: { mainAxis: 8 }, offset: { mainAxis: 8 },
...@@ -66,7 +66,7 @@ const NavLinkGroup = ({ item }: Props) => { ...@@ -66,7 +66,7 @@ const NavLinkGroup = ({ item }: Props) => {
py={ 1.5 } py={ 1.5 }
textStyle="sm" textStyle="sm"
fontWeight={ 500 } fontWeight={ 500 }
visual="navigation" variant="navigation"
{ ...(item.isActive ? { 'data-selected': true } : {}) } { ...(item.isActive ? { 'data-selected': true } : {}) }
{ ...(open ? { 'data-active': true } : {}) } { ...(open ? { 'data-active': true } : {}) }
borderRadius="base" borderRadius="base"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment