Commit 3bff0002 authored by tom's avatar tom

accordion showcases

parent 5f663a7f
import { Accordion } from '@chakra-ui/react';
import * as React from 'react';
import IconSvg from 'ui/shared/IconSvg';
interface AccordionItemTriggerProps extends Accordion.ItemTriggerProps {
indicatorPlacement?: 'start' | 'end';
variant?: Accordion.RootProps['variant'];
}
export const AccordionItemTrigger = React.forwardRef<
HTMLButtonElement,
AccordionItemTriggerProps
>(function AccordionItemTrigger(props, ref) {
const { children, indicatorPlacement: indicatorPlacementProp, variant, ...rest } = props;
const indicatorPlacement = variant === 'faq' ? 'start' : (indicatorPlacementProp ?? 'end');
const indicator = variant === 'faq' ? (
<Accordion.ItemIndicator
rotate="0deg"
position="relative"
_before={{
content: '""',
position: 'absolute',
display: 'block',
bgColor: '{currentColor}',
w: '100%',
h: '2px',
borderRadius: '2px',
left: '0',
top: '50%',
transform: 'translateY(-50%)',
}}
_after={{
content: '""',
position: 'absolute',
display: 'block',
bgColor: '{currentColor}',
w: '2px',
h: '100%',
borderRadius: '2px',
left: '50%',
top: '0',
transform: 'translateX(-50%)',
transition: 'transform 0.2s ease-in-out',
}}
_open={{
_after: {
transform: 'translateX(-50%) rotate(90deg)',
},
}}
/>
) : (
<Accordion.ItemIndicator rotate={{ base: '180deg', _open: '270deg' }} display="flex">
<IconSvg name="arrows/east-mini"/>
</Accordion.ItemIndicator>
);
return (
<Accordion.ItemTrigger className="group" { ...rest } ref={ ref }>
{ indicatorPlacement === 'start' && indicator }
{ children }
{ indicatorPlacement === 'end' && indicator }
</Accordion.ItemTrigger>
);
});
interface AccordionItemContentProps extends Accordion.ItemContentProps {}
export const AccordionItemContent = React.forwardRef<
HTMLDivElement,
AccordionItemContentProps
>(function AccordionItemContent(props, ref) {
return (
<Accordion.ItemContent>
<Accordion.ItemBody { ...props } ref={ ref }/>
</Accordion.ItemContent>
);
});
export const AccordionRoot = (props: Accordion.RootProps) => {
const { multiple = true, ...rest } = props;
return <Accordion.Root multiple={ multiple } { ...rest }/>;
};
export const AccordionItem = Accordion.Item;
import { defineSlotRecipe } from '@chakra-ui/react';
export const recipe = defineSlotRecipe({
className: 'chakra-accordion',
slots: [ 'root', 'item', 'itemTrigger', 'itemContent', 'itemBody', 'itemIndicator' ],
base: {
root: {
width: 'full',
'--accordion-radius': 'none',
},
item: {
overflowAnchor: 'none',
borderColor: 'border.divider',
},
itemTrigger: {
display: 'flex',
alignItems: 'center',
width: 'full',
outline: '0',
gap: '1',
fontWeight: 'medium',
borderRadius: 'var(--accordion-radius)',
cursor: 'pointer',
_focusVisible: {
outline: '2px solid',
outlineColor: 'colorPalette.focusRing',
},
},
itemBody: {
pt: '0',
pb: 'var(--accordion-padding-y)',
},
itemContent: {
overflow: 'hidden',
borderRadius: 'var(--accordion-radius)',
_open: {
animationName: 'expand-height, fade-in',
animationDuration: 'moderate',
},
_closed: {
animationName: 'collapse-height, fade-out',
animationDuration: 'moderate',
},
},
itemIndicator: {
transition: 'rotate 0.2s ease-in-out',
transformOrigin: 'center',
},
},
variants: {
variant: {
outline: {
item: {
borderBottomWidth: '1px',
},
itemIndicator: {
color: 'gray.500',
},
},
faq: {
item: {
borderBottomWidth: '1px',
},
itemTrigger: {
textStyle: 'heading.md',
},
itemIndicator: {
color: 'link.primary',
_groupHover: {
color: 'link.primary.hover',
},
},
},
},
size: {
sm: {
root: {
'--accordion-padding-x': '0',
'--accordion-padding-y': 'spacing.2',
},
itemTrigger: {
textStyle: 'sm',
py: 'var(--accordion-padding-y)',
},
itemIndicator: {
boxSize: '5',
},
},
md: {
root: {
'--accordion-padding-x': '0',
'--accordion-padding-y': 'spacing.3',
},
itemTrigger: {
textStyle: 'md',
py: 'var(--accordion-padding-y)',
},
itemIndicator: {
boxSize: '5',
},
},
},
},
compoundVariants: [
{
variant: 'faq',
size: 'md',
css: {
itemIndicator: {
boxSize: '14px',
margin: '5px',
},
itemBody: {
paddingLeft: '36px',
},
itemTrigger: {
gap: '3',
},
},
},
],
defaultVariants: {
size: 'md',
variant: 'outline',
},
});
import { recipe as accordion } from './accordion.recipe';
import { recipe as alert } from './alert.recipe';
import { recipe as badge } from './badge.recipe';
import { recipe as button } from './button.recipe';
......@@ -34,6 +35,7 @@ export const recipes = {
};
export const slotRecipes = {
accordion,
alert,
dialog,
drawer,
......
......@@ -21,6 +21,7 @@ import { toaster } from 'toolkit/chakra/toaster';
import ContentLoader from 'ui/shared/ContentLoader';
import IconSvg from 'ui/shared/IconSvg';
import PageTitle from 'ui/shared/Page/PageTitle';
import AccordionsShowcase from 'ui/showcases/Accordion';
import AlertsShowcase from 'ui/showcases/Alerts';
import BadgesShowcase from 'ui/showcases/Badges';
import ButtonShowcase from 'ui/showcases/Button';
......@@ -53,6 +54,7 @@ const ChakraShowcases = () => {
<TabsRoot defaultValue="alerts">
<TabsList flexWrap="wrap">
<TabsTrigger value="accordions">Accordions</TabsTrigger>
<TabsTrigger value="alerts">Alerts</TabsTrigger>
<TabsTrigger value="badges">Badges</TabsTrigger>
<TabsTrigger value="buttons">Buttons</TabsTrigger>
......@@ -63,6 +65,7 @@ const ChakraShowcases = () => {
<TabsTrigger value="tooltips">Tooltips</TabsTrigger>
<TabsTrigger value="unsorted">Unsorted</TabsTrigger>
</TabsList>
<AccordionsShowcase/>
<AlertsShowcase/>
<BadgesShowcase/>
<ButtonShowcase/>
......
......@@ -17,7 +17,7 @@ interface Props extends HTMLChakraProps<'div'> {
const IconSvg = ({ name, isLoading = false, ...props }: Props, ref: React.ForwardedRef<HTMLDivElement>) => {
return (
<Skeleton loading={ isLoading } display="inline-block" { ...props } ref={ ref }>
<Skeleton loading={ isLoading } display="inline-block" asChild { ...props } ref={ ref }>
<chakra.svg w="100%" h="100%">
<use href={ `${ href }#${ name }` }/>
</chakra.svg>
......
import React from 'react';
import { AccordionItemContent, AccordionItemTrigger, AccordionItem, AccordionRoot } from 'toolkit/chakra/accordion';
import { Section, Container, SectionHeader, SamplesStack, Sample } from './parts';
const items = [
{ value: 'first-item', title: 'First Item', text: 'Some value 1...' },
{ value: 'second-item', title: 'Second Item', text: 'Some value 2...' },
{ value: 'third-item', title: 'Third Item', text: 'Some value 3...' },
];
// https://eth-sepolia.k8s-dev.blockscout.com/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC?tab=read_write_contract
// https://base.blockscout.com/token/0x8f9C456C928a33a3859Fa283fb57B23c908fE843/instance/1924977?tab=metadata
const AccordionsShowcase = () => {
return (
<Container value="accordions">
<Section>
<SectionHeader>Variant</SectionHeader>
<SamplesStack>
<Sample label="variant: outline">
<AccordionRoot w="400px">
{ items.map((item, index) => (
<AccordionItem key={ index } value={ item.value }>
<AccordionItemTrigger>{ item.title }</AccordionItemTrigger>
<AccordionItemContent>{ item.text }</AccordionItemContent>
</AccordionItem>
)) }
</AccordionRoot>
</Sample>
<Sample label="variant: faq">
<AccordionRoot w="400px" variant="faq">
{ items.map((item, index) => (
<AccordionItem key={ index } value={ item.value }>
<AccordionItemTrigger variant="faq">{ item.title }</AccordionItemTrigger>
<AccordionItemContent>{ item.text }</AccordionItemContent>
</AccordionItem>
)) }
</AccordionRoot>
</Sample>
</SamplesStack>
<SectionHeader>Size</SectionHeader>
<SamplesStack>
<Sample label="size: md">
<AccordionRoot w="400px">
{ items.map((item, index) => (
<AccordionItem key={ index } value={ item.value }>
<AccordionItemTrigger>{ item.title }</AccordionItemTrigger>
<AccordionItemContent>{ item.text }</AccordionItemContent>
</AccordionItem>
)) }
</AccordionRoot>
</Sample>
<Sample label="size: sm">
<AccordionRoot w="400px" size="sm">
{ items.map((item, index) => (
<AccordionItem key={ index } value={ item.value }>
<AccordionItemTrigger indicatorPlacement="start">{ item.title }</AccordionItemTrigger>
<AccordionItemContent>{ item.text }</AccordionItemContent>
</AccordionItem>
)) }
</AccordionRoot>
</Sample>
</SamplesStack>
</Section>
</Container>
);
};
export default React.memo(AccordionsShowcase);
......@@ -5,6 +5,7 @@ import { Tag } from 'toolkit/chakra/tag';
import { Section, Container, SectionHeader, SamplesStack, Sample } from './parts';
const TagsShowcase = () => {
// TODO @tom2drum CELO tags, public tags, filtered tags
return (
<Container value="tags">
<Section>
......
import { Accordion, Hide, Show, Text } from '@chakra-ui/react';
import { Hide, Show, Text } from '@chakra-ui/react';
import React from 'react';
import { TX_STATE_CHANGES } from 'stubs/txStateChanges';
......@@ -38,14 +38,14 @@ const TxState = ({ txQuery }: Props) => {
}
const content = data ? (
<Accordion allowMultiple defaultIndex={ [] }>
<>
<Hide below="lg" ssr={ false }>
<TxStateTable data={ data.items } isLoading={ isPlaceholderData } top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }/>
</Hide>
<Show below="lg" ssr={ false }>
<TxStateList data={ data.items } isLoading={ isPlaceholderData }/>
</Show>
</Accordion>
</>
) : null;
const actionBar = pagination.isVisible ? (
......
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