update segmented

This commit is contained in:
Nate Kelley 2025-02-24 15:05:22 -07:00
parent bb7af41bf2
commit 290f9fde09
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
2 changed files with 71 additions and 6 deletions

View File

@ -8,7 +8,29 @@ const meta: Meta<typeof Segmented> = {
parameters: {
layout: 'centered'
},
tags: ['autodocs']
tags: ['autodocs'],
argTypes: {
size: {
control: 'radio',
options: ['default', 'large']
},
block: {
control: 'boolean'
},
value: {
control: 'text'
}
},
render: (args) => {
return (
<div className="flex w-full min-w-[500px] flex-col items-center justify-center gap-4">
<Segmented {...args} />
{/* <Segmented {...args} block />
<Segmented {...args} size="large" />
<Segmented {...args} block size="large" /> */}
</div>
);
}
};
export default meta;
@ -26,12 +48,40 @@ export const Default: Story = {
}
};
export const Large: Story = {
args: {
items: defaultItems,
size: 'large'
}
};
export const Block: Story = {
args: {
items: defaultItems,
block: true
},
parameters: {
layout: 'padded'
}
};
export const LargeBlock: Story = {
args: {
items: defaultItems,
size: 'large',
block: true
},
parameters: {
layout: 'padded'
}
};
export const WithIcons: Story = {
args: {
items: [
{ value: 'list', label: '📋 List' },
{ value: 'grid', label: '📱 Grid' },
{ value: 'gallery', label: '🖼️ Gallery' }
{ value: 'list', label: 'List' },
{ value: 'grid', label: 'Grid' },
{ value: 'gallery', label: 'Gallery' }
]
}
};
@ -43,6 +93,16 @@ export const Controlled: Story = {
}
};
export const WithDisabledItems: Story = {
args: {
items: [
{ value: 'tab1', label: 'Enabled' },
{ value: 'tab2', label: 'Disabled', disabled: true },
{ value: 'tab3', label: 'Enabled' }
]
}
};
export const CustomStyling: Story = {
args: {
items: defaultItems,

View File

@ -19,10 +19,11 @@ interface SegmentedProps {
onChange?: (value: string) => void;
className?: string;
size?: 'default' | 'large';
block?: boolean;
}
export const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>(
({ items, value, onChange, className, size = 'default' }, ref) => {
({ items, value, onChange, className, size = 'default', block = false }, ref) => {
const tabRefs = React.useRef<Map<string, HTMLButtonElement>>(new Map());
const [selectedValue, setSelectedValue] = useState(value || items[0]?.value);
const [hoveredValue, setHoveredValue] = useState<string | null>(null);
@ -66,6 +67,7 @@ export const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>(
'bg-item-select relative inline-flex items-center rounded-lg',
height,
padding,
block && 'w-full',
className
)}>
<motion.div
@ -81,7 +83,9 @@ export const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>(
damping: 35
}}
/>
<Tabs.List className="relative z-10 flex items-center gap-1" aria-label="Segmented Control">
<Tabs.List
className="relative z-10 flex w-full items-center gap-1"
aria-label="Segmented Control">
{items.map((item) => (
<Tabs.Trigger
key={item.value}
@ -96,6 +100,7 @@ export const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>(
'relative z-10 flex items-center justify-center gap-x-1.5 gap-y-1 rounded-md transition-colors',
size === 'default' ? 'px-2.5' : 'px-3',
innerHeight,
block && 'flex-1',
'focus-visible:ring-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
selectedValue === item.value
? 'text-foreground'