Commit df39f27f authored by tom's avatar tom

refactor chakra showcase page

parent ea01511b
...@@ -2,19 +2,26 @@ import type { BadgeProps as ChakraBadgeProps } from '@chakra-ui/react'; ...@@ -2,19 +2,26 @@ import type { BadgeProps as ChakraBadgeProps } from '@chakra-ui/react';
import { Badge as ChakraBadge } from '@chakra-ui/react'; import { Badge as ChakraBadge } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg';
import { Skeleton } from './skeleton'; import { Skeleton } from './skeleton';
export interface BadgeProps extends ChakraBadgeProps { export interface BadgeProps extends ChakraBadgeProps {
loading?: boolean; loading?: boolean;
iconStart?: IconName;
} }
export const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>( export const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
function Badge(props, ref) { function Badge(props, ref) {
const { loading, ...rest } = props; const { loading, iconStart, children, ...rest } = props;
return ( return (
<Skeleton loading={ loading }> <Skeleton loading={ loading }>
<ChakraBadge ref={ ref } { ...rest }/> <ChakraBadge ref={ ref } display="flex" alignItems="center" gap={ 1 } { ...rest }>
{ iconStart && <IconSvg name={ iconStart } boxSize="10px"/> }
{ children }
</ChakraBadge>
</Skeleton> </Skeleton>
); );
}); });
import { Tabs as ChakraTabs } from '@chakra-ui/react';
import * as React from 'react';
export interface TabsProps extends ChakraTabs.RootProps {}
export const TabsRoot = React.forwardRef<HTMLDivElement, TabsProps>(
function TabsRoot(props, ref) {
return <ChakraTabs.Root ref={ ref } { ...props }/>;
},
);
export const TabsList = ChakraTabs.List;
export const TabsTrigger = ChakraTabs.Trigger;
export const TabsContent = ChakraTabs.Content;
...@@ -257,6 +257,10 @@ const semanticTokens: ThemingConfig['semanticTokens'] = { ...@@ -257,6 +257,10 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
bg: { value: { _light: '{colors.purple.50}', _dark: '{colors.purple.800}' } }, bg: { value: { _light: '{colors.purple.50}', _dark: '{colors.purple.800}' } },
fg: { value: { _light: '{colors.purple.500}', _dark: '{colors.purple.100}' } }, fg: { value: { _light: '{colors.purple.500}', _dark: '{colors.purple.100}' } },
}, },
purple_alt: {
bg: { value: { _light: '{colors.purple.100}', _dark: '{colors.purple.800}' } },
fg: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } },
},
orange: { orange: {
bg: { value: { _light: '{colors.orange.50}', _dark: '{colors.orange.800}' } }, bg: { value: { _light: '{colors.orange.50}', _dark: '{colors.orange.800}' } },
fg: { value: { _light: '{colors.orange.500}', _dark: '{colors.orange.100}' } }, fg: { value: { _light: '{colors.orange.500}', _dark: '{colors.orange.100}' } },
...@@ -265,6 +269,10 @@ const semanticTokens: ThemingConfig['semanticTokens'] = { ...@@ -265,6 +269,10 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
bg: { value: { _light: '{colors.blue.50}', _dark: '{colors.blue.800}' } }, bg: { value: { _light: '{colors.blue.50}', _dark: '{colors.blue.800}' } },
fg: { value: { _light: '{colors.blue.500}', _dark: '{colors.blue.100}' } }, fg: { value: { _light: '{colors.blue.500}', _dark: '{colors.blue.100}' } },
}, },
blue_alt: {
bg: { value: { _light: '{colors.blue.50}', _dark: '{colors.blue.800}' } },
fg: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } },
},
yellow: { yellow: {
bg: { value: { _light: '{colors.yellow.50}', _dark: '{colors.yellow.800}' } }, bg: { value: { _light: '{colors.yellow.50}', _dark: '{colors.yellow.800}' } },
fg: { value: { _light: '{colors.yellow.500}', _dark: '{colors.yellow.100}' } }, fg: { value: { _light: '{colors.yellow.500}', _dark: '{colors.yellow.100}' } },
...@@ -273,6 +281,10 @@ const semanticTokens: ThemingConfig['semanticTokens'] = { ...@@ -273,6 +281,10 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
bg: { value: { _light: '{colors.teal.50}', _dark: '{colors.teal.800}' } }, bg: { value: { _light: '{colors.teal.50}', _dark: '{colors.teal.800}' } },
fg: { value: { _light: '{colors.teal.500}', _dark: '{colors.teal.100}' } }, fg: { value: { _light: '{colors.teal.500}', _dark: '{colors.teal.100}' } },
}, },
cyan: {
bg: { value: { _light: '{colors.cyan.50}', _dark: '{colors.cyan.800}' } },
fg: { value: { _light: '{colors.cyan.500}', _dark: '{colors.cyan.100}' } },
},
}, },
heading: { heading: {
DEFAULT: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } }, DEFAULT: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } },
......
...@@ -47,6 +47,18 @@ export const recipe = defineRecipe({ ...@@ -47,6 +47,18 @@ export const recipe = defineRecipe({
bg: 'badge.teal.bg', bg: 'badge.teal.bg',
color: 'badge.teal.fg', color: 'badge.teal.fg',
}, },
cyan: {
bg: 'badge.cyan.bg',
color: 'badge.cyan.fg',
},
purple_alt: {
bg: 'badge.purple_alt.bg',
color: 'badge.purple_alt.fg',
},
blue_alt: {
bg: 'badge.blue_alt.bg',
color: 'badge.blue_alt.fg',
},
}, },
size: { size: {
md: { md: {
......
/* eslint-disable max-len */ /* eslint-disable max-len */
/* eslint-disable react/jsx-no-bind */ /* eslint-disable react/jsx-no-bind */
import { createListCollection, HStack, Link, Spinner, Tabs, VStack } from '@chakra-ui/react'; import { createListCollection, HStack, Link, Spinner, VStack } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Alert } from 'toolkit/chakra/alert';
import { Badge } from 'toolkit/chakra/badge';
import { Button } from 'toolkit/chakra/button'; import { Button } from 'toolkit/chakra/button';
import { useColorMode } from 'toolkit/chakra/color-mode'; import { useColorMode } from 'toolkit/chakra/color-mode';
import { Field } from 'toolkit/chakra/field'; import { Field } from 'toolkit/chakra/field';
...@@ -17,12 +15,15 @@ import { ProgressCircleRing, ProgressCircleRoot } from 'toolkit/chakra/progress- ...@@ -17,12 +15,15 @@ import { ProgressCircleRing, ProgressCircleRoot } from 'toolkit/chakra/progress-
import { SelectContent, SelectItem, SelectRoot, SelectTrigger, SelectValueText } from 'toolkit/chakra/select'; import { SelectContent, SelectItem, SelectRoot, SelectTrigger, SelectValueText } from 'toolkit/chakra/select';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import { Switch } from 'toolkit/chakra/switch'; import { Switch } from 'toolkit/chakra/switch';
import { TabsContent, TabsList, TabsRoot, TabsTrigger } from 'toolkit/chakra/tabs';
import { Textarea } from 'toolkit/chakra/textarea'; import { Textarea } from 'toolkit/chakra/textarea';
import { toaster } from 'toolkit/chakra/toaster'; import { toaster } from 'toolkit/chakra/toaster';
import { Tooltip } from 'toolkit/chakra/tooltip'; import { Tooltip } from 'toolkit/chakra/tooltip';
import ContentLoader from 'ui/shared/ContentLoader'; import ContentLoader from 'ui/shared/ContentLoader';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import AlertsShowcase from 'ui/showcases/Alerts';
import BadgesShowcase from 'ui/showcases/Badges';
const TEXT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; const TEXT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
...@@ -45,6 +46,16 @@ const ChakraShowcases = () => { ...@@ -45,6 +46,16 @@ const ChakraShowcases = () => {
Color mode: { colorMode.colorMode } Color mode: { colorMode.colorMode }
</Switch> </Switch>
<TabsRoot defaultValue="alerts">
<TabsList>
<TabsTrigger value="alerts">Alerts</TabsTrigger>
<TabsTrigger value="badges">Badges</TabsTrigger>
<TabsTrigger value="unsorted">Unsorted</TabsTrigger>
</TabsList>
<AlertsShowcase/>
<BadgesShowcase/>
<TabsContent value="unsorted">
<VStack align="flex-start" gap={ 6 }> <VStack align="flex-start" gap={ 6 }>
<section> <section>
<Heading textStyle="heading.md" mb={ 2 }>Buttons</Heading> <Heading textStyle="heading.md" mb={ 2 }>Buttons</Heading>
...@@ -196,47 +207,22 @@ const ChakraShowcases = () => { ...@@ -196,47 +207,22 @@ const ChakraShowcases = () => {
<section> <section>
<Heading textStyle="heading.md" mb={ 2 }>Tabs</Heading> <Heading textStyle="heading.md" mb={ 2 }>Tabs</Heading>
<HStack gap={ 4 }> <HStack gap={ 4 }>
<Tabs.Root defaultValue="tab1" variant="solid"> <TabsRoot defaultValue="tab1" variant="solid">
<Tabs.List> <TabsList>
<Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger> <TabsTrigger value="tab1">Tab 1</TabsTrigger>
<Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger> <TabsTrigger value="tab2">Tab 2</TabsTrigger>
</Tabs.List> </TabsList>
<Tabs.Content value="tab1">Content 1</Tabs.Content> <TabsContent value="tab1">Content 1</TabsContent>
<Tabs.Content value="tab2">Content 2</Tabs.Content> <TabsContent value="tab2">Content 2</TabsContent>
</Tabs.Root> </TabsRoot>
<Tabs.Root defaultValue="tab1" variant="secondary" size="sm"> <TabsRoot defaultValue="tab1" variant="secondary" size="sm">
<Tabs.List> <TabsList>
<Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger> <TabsTrigger value="tab1">Tab 1</TabsTrigger>
<Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger> <TabsTrigger value="tab2">Tab 2</TabsTrigger>
</Tabs.List> </TabsList>
<Tabs.Content value="tab1">Content 1</Tabs.Content> <TabsContent value="tab1">Content 1</TabsContent>
<Tabs.Content value="tab2">Content 2</Tabs.Content> <TabsContent value="tab2">Content 2</TabsContent>
</Tabs.Root> </TabsRoot>
</HStack>
</section>
<section>
<Heading textStyle="heading.md" mb={ 2 }>Alerts</Heading>
<HStack gap={ 4 } whiteSpace="nowrap" flexWrap="wrap">
<Alert visual="info" title="Info" maxWidth="300px"> Alert content </Alert>
<Alert visual="neutral" title="Neutral" maxWidth="300px"> Alert content </Alert>
<Alert visual="warning" title="Warning" maxWidth="300px"> Alert content </Alert>
<Alert visual="success" title="Success" maxWidth="300px"> Alert content </Alert>
<Alert visual="error" title="Error" startElement={ null } maxWidth="300px"> Alert content </Alert>
</HStack>
</section>
<section>
<Heading textStyle="heading.md" mb={ 2 }>Badges</Heading>
<HStack gap={ 4 } whiteSpace="nowrap" flexWrap="wrap">
<Badge colorPalette="gray">Gray</Badge>
<Badge colorPalette="green">Green</Badge>
<Badge colorPalette="red">Red</Badge>
<Badge colorPalette="purple">Purple</Badge>
<Badge colorPalette="orange">Orange</Badge>
<Badge colorPalette="blue">Blue</Badge>
<Badge colorPalette="yellow">Yellow</Badge>
<Badge colorPalette="teal">Teal</Badge>
</HStack> </HStack>
</section> </section>
...@@ -271,6 +257,8 @@ const ChakraShowcases = () => { ...@@ -271,6 +257,8 @@ const ChakraShowcases = () => {
</HStack> </HStack>
</section> </section>
</VStack> </VStack>
</TabsContent>
</TabsRoot>
</> </>
); );
}; };
......
...@@ -6,7 +6,6 @@ import type { BadgeProps } from 'toolkit/chakra/badge'; ...@@ -6,7 +6,6 @@ import type { BadgeProps } from 'toolkit/chakra/badge';
import { Badge } from 'toolkit/chakra/badge'; import { Badge } from 'toolkit/chakra/badge';
import { Tooltip } from 'toolkit/chakra/tooltip'; import { Tooltip } from 'toolkit/chakra/tooltip';
import type { IconName } from 'ui/shared/IconSvg'; import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg';
export type StatusTagType = 'ok' | 'error' | 'pending'; export type StatusTagType = 'ok' | 'error' | 'pending';
...@@ -41,9 +40,8 @@ const StatusTag = ({ type, text, errorText, isLoading, className }: Props) => { ...@@ -41,9 +40,8 @@ const StatusTag = ({ type, text, errorText, isLoading, className }: Props) => {
return ( return (
<Tooltip content={ errorText } disabled={ !errorText }> <Tooltip content={ errorText } disabled={ !errorText }>
<Badge colorPalette={ colorPalette } loading={ isLoading } className={ className }> <Badge colorPalette={ colorPalette } loading={ isLoading } className={ className } iconStart={ icon }>
<IconSvg boxSize={ 2.5 } name={ icon } mr={ 1 } flexShrink={ 0 }/> { capitalizedText }
<span>{ capitalizedText }</span>
</Badge> </Badge>
</Tooltip> </Tooltip>
); );
......
import { Box, Table } from '@chakra-ui/react';
import React from 'react';
import { Alert } from 'toolkit/chakra/alert';
import * as SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import { Section, Container, SectionHeader, SamplesStack, Sample, SectionSubHeader } from './parts';
const AlertsShowcase = () => {
return (
<Container value="alerts">
<Section>
<SectionHeader>Status</SectionHeader>
<SamplesStack>
<Sample label="visual: info">
<Alert visual="info" title="Info"> Alert content </Alert>
</Sample>
<Sample label="visual: neutral">
<Alert visual="neutral" title="Neutral"> Alert content </Alert>
</Sample>
<Sample label="visual: warning">
<Alert visual="warning" title="Warning"> Alert content </Alert>
</Sample>
<Sample label="visual: success">
<Alert visual="success" title="Success"> Alert content </Alert>
</Sample>
<Sample label="visual: error">
<Alert visual="error" title="Error"> Alert content </Alert>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Variant</SectionHeader>
<SamplesStack>
<Sample label="variant: subtle">
<Alert visual="info" title="Info"> Alert content </Alert>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Examples</SectionHeader>
<SectionSubHeader>Inside table (SocketNewItemsNotice)</SectionSubHeader>
<SamplesStack>
<Sample label="loading">
<Table.Root>
<Table.Header>
<Table.Row>
<Table.ColumnHeader w="100px">Block</Table.ColumnHeader>
<Table.ColumnHeader w="100px">Age</Table.ColumnHeader>
<Table.ColumnHeader w="100px">Gas used</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<SocketNewItemsNotice.Desktop
url={ window.location.href }
num={ 1234 }
type="block"
isLoading
/>
</Table.Body>
</Table.Root>
</Sample>
<Sample label="success">
<Table.Root>
<Table.Header>
<Table.Row>
<Table.ColumnHeader w="100px">Block</Table.ColumnHeader>
<Table.ColumnHeader w="100px">Age</Table.ColumnHeader>
<Table.ColumnHeader w="100px">Gas used</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<SocketNewItemsNotice.Desktop
url={ window.location.href }
num={ 1234 }
type="block"
isLoading={ false }
/>
</Table.Body>
</Table.Root>
</Sample>
</SamplesStack>
<SectionSubHeader>Multiple lines</SectionSubHeader>
<SamplesStack>
<Sample label="multiple lines, with title, inline=false">
<Alert visual="warning" title="Warning" inline={ false } maxWidth="500px">
<Box>
Participated in our recent Blockscout activities? Check your eligibility and claim your NFT Scout badges. More exciting things are coming soon!
</Box>
</Alert>
</Sample>
<Sample label="multiple lines, no title">
<Alert visual="warning" maxWidth="500px">
<Box>
Participated in our recent Blockscout activities? Check your eligibility and claim your NFT Scout badges. More exciting things are coming soon!
</Box>
</Alert>
</Sample>
</SamplesStack>
</Section>
</Container>
);
};
export default React.memo(AlertsShowcase);
import React from 'react';
import { Badge } from 'toolkit/chakra/badge';
import StatusTag from 'ui/shared/statusTag/StatusTag';
import { Section, Container, SectionHeader, SamplesStack, Sample, SectionSubHeader } from './parts';
const BadgesShowcase = () => {
return (
<Container value="badges">
<Section>
<SectionHeader>Color palette</SectionHeader>
<SamplesStack>
<Sample label="colorPalette: gray">
<Badge colorPalette="gray">Pending</Badge>
</Sample>
<Sample label="colorPalette: green">
<Badge colorPalette="green">Success</Badge>
</Sample>
<Sample label="colorPalette: red">
<Badge colorPalette="red">Failed</Badge>
</Sample>
<Sample label="colorPalette: purple">
<Badge colorPalette="purple">Transaction</Badge>
</Sample>
<Sample label="colorPalette: orange">
<Badge colorPalette="orange">Token transfer</Badge>
</Sample>
<Sample label="colorPalette: blue">
<Badge colorPalette="blue">Contract call</Badge>
</Sample>
<Sample label="colorPalette: yellow">
<Badge colorPalette="yellow">Blob txn</Badge>
</Sample>
<Sample label="colorPalette: teal">
<Badge colorPalette="teal">Multicall</Badge>
</Sample>
<Sample label="colorPalette: cyan">
<Badge colorPalette="cyan">Internal txn</Badge>
</Sample>
<Sample label="colorPalette: purple_alt">
<Badge colorPalette="purple_alt">read</Badge>
</Sample>
<Sample label="colorPalette: blue_alt">
<Badge colorPalette="blue_alt">write</Badge>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Size</SectionHeader>
<SamplesStack>
<Sample label="size: md">
<Badge size="md">Content</Badge>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Variant</SectionHeader>
<SamplesStack>
<Sample label="variant: subtle">
<Badge variant="subtle">Content</Badge>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Icon</SectionHeader>
<SamplesStack>
<Sample label="iconStart: status/success">
<Badge iconStart="status/success">
Content
</Badge>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Examples</SectionHeader>
<SectionSubHeader>Status tag (StatusTag)</SectionSubHeader>
<SamplesStack>
<Sample label="status: ok">
<StatusTag type="ok" text="Text"/>
</Sample>
<Sample label="status: error">
<StatusTag type="error" text="Text"/>
</Sample>
<Sample label="status: pending">
<StatusTag type="pending" text="Text"/>
</Sample>
</SamplesStack>
</Section>
</Container>
);
};
export default React.memo(BadgesShowcase);
import type { TabsContentProps } from '@chakra-ui/react';
import { Code, Grid, HStack } from '@chakra-ui/react';
import React from 'react';
import { Heading } from 'toolkit/chakra/heading';
import { TabsContent } from 'toolkit/chakra/tabs';
export const Container = (props: TabsContentProps) => <TabsContent display="flex" flexDirection="column" gap={ 6 } { ...props }/>;
export const Section = ({ children }: { children: React.ReactNode }) => <section>{ children }</section>;
export const SectionHeader = ({ children }: { children: React.ReactNode }) => <Heading level="2" mb={ 4 }>{ children }</Heading>;
export const SectionSubHeader = ({ children }: { children: React.ReactNode }) => <Heading level="3" mb={ 3 } _notFirst={{ mt: 4 }}>{ children }</Heading>;
export const SamplesStack = ({ children }: { children: React.ReactNode }) => (
<Grid
rowGap={ 4 }
columnGap={ 8 }
gridTemplateColumns="fit-content(100%) fit-content(100%)"
justifyItems="flex-start"
alignItems="flex-start"
>
{ children }
</Grid>
);
export const Sample = ({ children, label }: { children: React.ReactNode; label: string }) => (
<>
<Code w="fit-content">{ label }</Code>
<HStack gap={ 3 } whiteSpace="pre-wrap" flexWrap="wrap">{ children }</HStack>
</>
);
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