✨(frontend) introduce Tab-related components
Style react aria components and exposed them. Tabs are needed for the advanced settings component. Both orientations, horizontal and vertical, are supported.
This commit is contained in:
committed by
aleb_the_flash
parent
ce3a6dab12
commit
79f7fcab6e
102
src/frontend/src/primitives/Tabs.tsx
Normal file
102
src/frontend/src/primitives/Tabs.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import {
|
||||
Tabs as RACTabs,
|
||||
Tab as RACTab,
|
||||
TabPanel as RACTabPanel,
|
||||
TabList as RACTabList,
|
||||
TabProps as RACTabProps,
|
||||
TabsProps as RACTabsProps,
|
||||
TabListProps as RACTabListProps,
|
||||
TabPanelProps as RACTabPanelProps,
|
||||
} from 'react-aria-components'
|
||||
import { styled } from '@/styled-system/jsx'
|
||||
import { StyledVariantProps } from '@/styled-system/types'
|
||||
|
||||
const StyledTabs = styled(RACTabs, {
|
||||
base: {
|
||||
display: 'flex',
|
||||
color: 'colorPalette.text',
|
||||
'&[data-orientation=horizontal]': {
|
||||
flexDirection: 'column',
|
||||
'--horizontal': '3px',
|
||||
},
|
||||
'&[data-orientation=vertical]': {
|
||||
flexDirection: 'row',
|
||||
'--vertical': '3px',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export type TabsProps = RACTabsProps & StyledVariantProps<typeof StyledTabs>
|
||||
|
||||
export const Tabs = ({ children, ...props }: TabsProps) => {
|
||||
return <StyledTabs {...props}>{children}</StyledTabs>
|
||||
}
|
||||
|
||||
const StyledTab = styled(RACTab, {
|
||||
base: {
|
||||
padding: '10px',
|
||||
cursor: 'pointer',
|
||||
outline: 'none',
|
||||
position: 'relative',
|
||||
color: 'box.text',
|
||||
transition: 'color 200ms ease, backgroundColor 200ms ease',
|
||||
borderColor: 'transparent',
|
||||
forcedColorAdjust: 'none',
|
||||
'&[data-focused]': {},
|
||||
'&[data-selected]': {
|
||||
borderColor: 'primary',
|
||||
},
|
||||
borderBottom: 'var(--horizontal) solid',
|
||||
borderInlineEnd: 'var(--vertical) solid',
|
||||
},
|
||||
})
|
||||
|
||||
export type TabProps = RACTabProps & StyledVariantProps<typeof StyledTab>
|
||||
|
||||
export const Tab = ({ children, ...props }: TabProps) => {
|
||||
return <StyledTab {...props}>{children}</StyledTab>
|
||||
}
|
||||
|
||||
const StyledTabList = styled(RACTabList, {
|
||||
base: {
|
||||
display: 'flex',
|
||||
'&[data-orientation=horizontal]': {
|
||||
borderBottom: '1px solid',
|
||||
borderColor: 'gray.300',
|
||||
},
|
||||
'&[data-orientation=vertical]': {
|
||||
flexDirection: 'column',
|
||||
borderInlineEnd: '1px solid',
|
||||
borderColor: 'gray.300',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// @fixme type could be simplified to avoid redefining the children props
|
||||
export type TabListProps = {
|
||||
children: React.ReactNode
|
||||
} & RACTabListProps<typeof Tab> &
|
||||
StyledVariantProps<typeof StyledTabList>
|
||||
|
||||
export const TabList = ({ children, ...props }: TabListProps) => {
|
||||
return <StyledTabList {...props}>{children}</StyledTabList>
|
||||
}
|
||||
|
||||
const StyledTabPanel = styled(RACTabPanel, {
|
||||
base: {
|
||||
marginTop: '4px',
|
||||
padding: '10px',
|
||||
borderRadius: '4px',
|
||||
outline: 'none',
|
||||
'&[data-focus-visible]': {
|
||||
outline: '2px solid red',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export type TabPanelProps = RACTabPanelProps &
|
||||
StyledVariantProps<typeof StyledTabPanel>
|
||||
|
||||
export const TabPanel = ({ children, ...props }: TabPanelProps) => {
|
||||
return <StyledTabPanel {...props}>{children}</StyledTabPanel>
|
||||
}
|
||||
Reference in New Issue
Block a user