Splitter
A component that divides your interface into resizable sections
import { Splitter } from '~/components/ui/splitter'
export const Demo = (props: Splitter.RootProps) => {
return (
<Splitter.Root
size={[
{ id: 'a', size: 50 },
{ id: 'b', size: 50 },
]}
{...props}
>
<Splitter.Panel id="a">A</Splitter.Panel>
<Splitter.ResizeTrigger id="a:b" />
<Splitter.Panel id="b">B</Splitter.Panel>
</Splitter.Root>
)
}
import { Splitter } from '~/components/ui/splitter'
export const Demo = (props: Splitter.RootProps) => {
return (
<Splitter.Root
size={[
{ id: 'a', size: 50 },
{ id: 'b', size: 50 },
]}
{...props}
>
<Splitter.Panel id="a">A</Splitter.Panel>
<Splitter.ResizeTrigger id="a:b" />
<Splitter.Panel id="b">B</Splitter.Panel>
</Splitter.Root>
)
}
Usage
import { Splitter } from '~/components/ui/splitter'
Installation
npx @park-ui/cli components add splitter
1
Add Styled Primitive
Copy the code snippet below into ~/components/ui/styled/splitter.tsx
'use client'
import type { Assign } from '@ark-ui/react'
import { Splitter } from '@ark-ui/react/splitter'
import { type SplitterVariantProps, splitter } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(splitter)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Splitter.RootProviderBaseProps>, SplitterVariantProps>
>(Splitter.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Splitter.RootBaseProps>, SplitterVariantProps>
>(Splitter.Root, 'root')
export const Panel = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Splitter.PanelBaseProps>
>(Splitter.Panel, 'panel')
export const ResizeTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, Splitter.ResizeTriggerBaseProps>
>(Splitter.ResizeTrigger, 'resizeTrigger')
export { SplitterContext as Context } from '@ark-ui/react/splitter'
import { type Assign, Splitter } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { type SplitterVariantProps, splitter } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(splitter)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, Splitter.RootProviderBaseProps>, SplitterVariantProps>
>(Splitter.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, Splitter.RootBaseProps>, SplitterVariantProps>
>(Splitter.Root, 'root')
export const Panel = withContext<Assign<HTMLStyledProps<'div'>, Splitter.PanelBaseProps>>(
Splitter.Panel,
'panel',
)
export const ResizeTrigger = withContext<
Assign<HTMLStyledProps<'button'>, Splitter.ResizeTriggerBaseProps>
>(Splitter.ResizeTrigger, 'resizeTrigger')
export { SplitterContext as Context } from '@ark-ui/solid'
No snippet found
2
Add Re-Export
To improve the developer experience, re-export the styled primitives in~/components/ui/splitter.tsx
.
export * as Splitter from './styled/splitter'
export * as Splitter from './styled/splitter'
3
Integrate Recipe
If you're not using @park-ui/preset
, add the following recipe to yourpanda.config.ts
:
import { splitterAnatomy } from '@ark-ui/anatomy'
import { defineSlotRecipe } from '@pandacss/dev'
export const splitter = defineSlotRecipe({
className: 'splitter',
slots: splitterAnatomy.keys(),
base: {
root: {
display: 'flex',
gap: '2',
},
panel: {
borderWidth: '1px',
background: 'bg.default',
borderRadius: 'l2',
color: 'fg.muted',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
resizeTrigger: {
borderRadius: 'full',
transitionDuration: 'normal',
transitionProperty: 'background',
transitionTimingFunction: 'default',
outline: '0',
background: 'gray.7',
_hover: {
background: 'gray.8',
},
_active: {
background: 'gray.8',
},
_horizontal: {
minWidth: '1.5',
margin: 'min(1rem, 20%) 0',
},
_vertical: {
minHeight: '1.5',
margin: '0 min(1rem, 20%)',
},
},
},
})