mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
accordion showcases
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
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;
|
||||
@@ -0,0 +1,130 @@
|
||||
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',
|
||||
},
|
||||
});
|
||||
@@ -1,3 +1,4 @@
|
||||
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>
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
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>
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
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 ? (
|
||||
|
||||
Reference in New Issue
Block a user