Segment Group
Organizes and navigates between sections in a view.
import { SegmentGroup } from '~/components/ui/segment-group'
export const Demo = (props: SegmentGroup.RootProps) => {
const options = [
{ id: 'overview', label: 'Overview' },
{ id: 'customers', label: 'Customers' },
{ id: 'premium', label: 'Premium' },
{ id: 'settings', label: 'Settings' },
]
return (
<SegmentGroup.Root defaultValue="customers" {...props}>
{options.map((option) => (
<SegmentGroup.Item key={option.id} value={option.id} disabled={option.id === 'premium'}>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemText>{option.label}</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
))}
<SegmentGroup.Indicator />
</SegmentGroup.Root>
)
}
import { For } from 'solid-js'
import { SegmentGroup } from '~/components/ui/segment-group'
export const Demo = (props: SegmentGroup.RootProps) => {
const options = [
{ id: 'overview', label: 'Overview' },
{ id: 'customers', label: 'Customers' },
{ id: 'premium', label: 'Premium' },
{ id: 'settings', label: 'Settings' },
]
return (
<SegmentGroup.Root defaultValue="customers" {...props}>
<For each={options}>
{(option) => (
<SegmentGroup.Item value={option.id} disabled={option.id === 'premium'}>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemText>{option.label}</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
)}
</For>
<SegmentGroup.Indicator />
</SegmentGroup.Root>
)
}
Usage
import { SegmentGroup } from '~/components/ui/segment-group'
Installation
npx @park-ui/cli components add segment-group
1
Add Styled Primitive
Copy the code snippet below into ~/components/ui/styled/segment-group.tsx
'use client'
import type { Assign } from '@ark-ui/react'
import { SegmentGroup } from '@ark-ui/react/segment-group'
import { type SegmentGroupVariantProps, segmentGroup } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(segmentGroup)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLDivElement,
Assign<
Assign<HTMLStyledProps<'div'>, SegmentGroup.RootProviderBaseProps>,
SegmentGroupVariantProps
>
>(SegmentGroup.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, SegmentGroup.RootBaseProps>, SegmentGroupVariantProps>
>(SegmentGroup.Root, 'root')
export const Indicator = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, SegmentGroup.IndicatorBaseProps>
>(SegmentGroup.Indicator, 'indicator')
export const ItemControl = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, SegmentGroup.ItemControlBaseProps>
>(SegmentGroup.ItemControl, 'itemControl')
export const Item = withContext<
HTMLLabelElement,
Assign<HTMLStyledProps<'label'>, SegmentGroup.ItemBaseProps>
>(SegmentGroup.Item, 'item')
export const ItemText = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, SegmentGroup.ItemTextBaseProps>
>(SegmentGroup.ItemText, 'itemText')
export const Label = withContext<
HTMLLabelElement,
Assign<HTMLStyledProps<'label'>, SegmentGroup.LabelBaseProps>
>(SegmentGroup.Label, 'label')
export {
SegmentGroupContext as Context,
SegmentGroupItemHiddenInput as ItemHiddenInput,
} from '@ark-ui/react/segment-group'
import { type Assign, SegmentGroup } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { type SegmentGroupVariantProps, segmentGroup } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(segmentGroup)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
Assign<
Assign<HTMLStyledProps<'div'>, SegmentGroup.RootProviderBaseProps>,
SegmentGroupVariantProps
>
>(SegmentGroup.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, SegmentGroup.RootBaseProps>, SegmentGroupVariantProps>
>(SegmentGroup.Root, 'root')
export const Indicator = withContext<
Assign<HTMLStyledProps<'div'>, SegmentGroup.IndicatorBaseProps>
>(SegmentGroup.Indicator, 'indicator')
export const ItemControl = withContext<
Assign<HTMLStyledProps<'div'>, SegmentGroup.ItemControlBaseProps>
>(SegmentGroup.ItemControl, 'itemControl')
export const Item = withContext<Assign<HTMLStyledProps<'label'>, SegmentGroup.ItemBaseProps>>(
SegmentGroup.Item,
'item',
)
export const ItemText = withContext<
Assign<HTMLStyledProps<'span'>, SegmentGroup.ItemTextBaseProps>
>(SegmentGroup.ItemText, 'itemText')
export const Label = withContext<Assign<HTMLStyledProps<'label'>, SegmentGroup.LabelBaseProps>>(
SegmentGroup.Label,
'label',
)
export {
SegmentGroupContext as Context,
SegmentGroupItemHiddenInput as ItemHiddenInput,
} from '@ark-ui/solid'
No snippet found
2
Add Re-Export
To improve the developer experience, re-export the styled primitives in~/components/ui/segment-group.tsx
.
export * as SegmentGroup from './styled/segment-group'
export * as SegmentGroup from './styled/segment-group'
3
Integrate Recipe
If you're not using @park-ui/preset
, add the following recipe to yourpanda.config.ts
:
import { segmentGroupAnatomy } from '@ark-ui/anatomy'
import { defineSlotRecipe } from '@pandacss/dev'
export const segmentGroup = defineSlotRecipe({
className: 'segmentGroup',
slots: segmentGroupAnatomy.keys(),
base: {
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: {
_horizontal: 'row',
_vertical: 'column',
},
gap: {
_horizontal: '4',
_vertical: '1',
},
borderBottomWidth: {
_horizontal: '1px',
},
borderLeftWidth: {
_vertical: '1px',
},
},
indicator: {
borderColor: 'colorPalette.default',
_horizontal: {
bottom: '0',
borderBottomWidth: '2px',
transform: 'translateY(1px)',
width: 'var(--width)',
},
_vertical: {
borderLeftWidth: '2px',
height: 'var(--height)',
transform: 'translateX(-1px)',
},
},
item: {
color: 'fg.muted',
cursor: 'pointer',
fontWeight: 'medium',
transitionDuration: 'normal',
transitionProperty: 'color',
transitionTimingFunction: 'default',
_hover: {
color: 'fg.default',
},
_checked: {
fontWeight: 'semibold',
color: 'fg.default',
_hover: {
color: 'fg.default',
},
},
_disabled: {
color: 'fg.disabled',
cursor: 'not-allowed',
_hover: {
color: 'fg.disabled',
},
},
px: {
_horizontal: '1',
_vertical: '3',
},
pb: {
_horizontal: '3',
},
py: {
_vertical: '1.5',
},
},
},
defaultVariants: {
size: 'md',
},
variants: {
size: {
sm: {
item: {
textStyle: 'sm',
},
},
md: {
item: {
textStyle: 'md',
},
},
},
},
})