mirror of
https://github.com/hanzoai/gui.git
synced 2026-10-25 02:31:41 +00:00
React passes ref as a prop, and a forwardRef over props with an index signature drops every named prop through Omit; the font extras are optional in a spread function's config. Co-authored-by: Hanzo Dev <[email protected]>
104 lines
2.2 KiB
TypeScript
104 lines
2.2 KiB
TypeScript
import { useStore, useStoreSelector } from '@hanzogui/use-store'
|
|
import type { TabsProps, TabsTabProps } from '@hanzo/gui'
|
|
import { Paragraph, Tabs, XStack, styled, withStaticProperties } from '@hanzo/gui'
|
|
import { type Href, router, useParams } from 'one'
|
|
|
|
class TabsStore {
|
|
active = 'styled'
|
|
}
|
|
|
|
function TabsComponent(props: TabsProps) {
|
|
const params = useParams()
|
|
const store = useStore(TabsStore)
|
|
|
|
const id = props.id || 'value'
|
|
|
|
const updateUrl = (newValue: string) => {
|
|
store.active = newValue
|
|
const url = new URL(location.href)
|
|
url.searchParams.set(id, newValue)
|
|
url.hash = '' // having this set messes with the scroll
|
|
router.replace(url as Href)
|
|
}
|
|
|
|
const value =
|
|
typeof params[id] === 'string' ? (params[id] as string) : (props.defaultValue ?? '')
|
|
|
|
return (
|
|
<Tabs
|
|
onValueChange={updateUrl}
|
|
unstyled
|
|
orientation="horizontal"
|
|
flexDirection="column"
|
|
borderWidth={0}
|
|
{...props}
|
|
value={value ?? ''}
|
|
/>
|
|
)
|
|
}
|
|
|
|
const Tab = (props: TabsTabProps) => {
|
|
const isActive = useStoreSelector(TabsStore, (x) => x.active === props.value)
|
|
|
|
return (
|
|
<Tabs.Tab
|
|
// disableActiveTheme
|
|
size="$3"
|
|
flex={1}
|
|
px="$5"
|
|
pointerEvents="auto"
|
|
{...props}
|
|
focusStyle={{
|
|
outlineColor: '$outlineColor',
|
|
outlineWidth: 2,
|
|
outlineStyle: 'solid',
|
|
}}
|
|
{...(isActive && {
|
|
bg: '$color7',
|
|
hoverStyle: {
|
|
bg: '$color7',
|
|
},
|
|
focusStyle: {
|
|
bg: '$color7',
|
|
},
|
|
})}
|
|
>
|
|
<Paragraph size="$3">{props.children}</Paragraph>
|
|
</Tabs.Tab>
|
|
)
|
|
}
|
|
|
|
const TabsListFrame = styled(XStack, {
|
|
pointerEvents: 'none',
|
|
maxW: '50%',
|
|
mt: -30,
|
|
justify: 'flex-end',
|
|
self: 'flex-end',
|
|
t: 70,
|
|
mr: 0,
|
|
mb: 0,
|
|
z: 10000,
|
|
position: 'sticky' as any,
|
|
r: 0,
|
|
|
|
$sm: {
|
|
minW: '100%',
|
|
self: 'stretch',
|
|
mt: 0,
|
|
},
|
|
})
|
|
|
|
const TabsList = (props) => {
|
|
return (
|
|
<TabsListFrame className="sticky">
|
|
<Tabs.List size="$4" width="100%" {...props} />
|
|
</TabsListFrame>
|
|
)
|
|
}
|
|
|
|
export const DocsTabs = withStaticProperties(TabsComponent, {
|
|
List: TabsList,
|
|
Tab,
|
|
Content: Tabs.Content,
|
|
})
|