From 7422c25b74c92fc0a61c2c1fc777ff0aec2d863e Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Mon, 24 Feb 2025 15:28:15 -0700 Subject: [PATCH] glider variants --- .../ui/segmented/Segmented.stories.tsx | 4 +++ web/src/components/ui/segmented/Segmented.tsx | 33 +++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/web/src/components/ui/segmented/Segmented.stories.tsx b/web/src/components/ui/segmented/Segmented.stories.tsx index dd9536356..3e9cf31b8 100644 --- a/web/src/components/ui/segmented/Segmented.stories.tsx +++ b/web/src/components/ui/segmented/Segmented.stories.tsx @@ -19,6 +19,10 @@ const meta: Meta = { }, value: { control: 'text' + }, + type: { + control: 'radio', + options: ['button', 'track'] } }, render: (args) => { diff --git a/web/src/components/ui/segmented/Segmented.tsx b/web/src/components/ui/segmented/Segmented.tsx index 430e9f56a..3c4b487f6 100644 --- a/web/src/components/ui/segmented/Segmented.tsx +++ b/web/src/components/ui/segmented/Segmented.tsx @@ -6,6 +6,7 @@ import { motion } from 'framer-motion'; import { cn } from '@/lib/classMerge'; import { useEffect, useState } from 'react'; import { cva } from 'class-variance-authority'; +import { useMemoizedFn } from 'ahooks'; export interface SegmentedItem { value: string; @@ -21,6 +22,7 @@ interface SegmentedProps { className?: string; size?: 'default' | 'large'; block?: boolean; + type?: 'button' | 'track'; } const segmentedVariants = cva('relative inline-flex items-center rounded-md', { @@ -32,6 +34,10 @@ const segmentedVariants = cva('relative inline-flex items-center rounded-md', { size: { default: '', large: '' + }, + type: { + button: 'bg-transparent', + track: 'bg-item-select' } } }); @@ -60,19 +66,20 @@ const triggerVariants = cva( true: '', false: '' } - }, - compoundVariants: [ - { - hovered: true, - selected: false, - className: 'bg-gray-50/50' - } - ] + } } ); +const gliderVariants = cva('absolute border-border rounded-md border', { + variants: { + type: { + button: 'bg-item-select', + track: 'bg-background' + } + } +}); export const Segmented = React.forwardRef( - ({ items, value, onChange, className, size = 'default', block = false }, ref) => { + ({ items, type = 'track', value, onChange, className, size = 'default', block = false }, ref) => { const tabRefs = React.useRef>(new Map()); const [selectedValue, setSelectedValue] = useState(value || items[0]?.value); const [hoveredValue, setHoveredValue] = useState(null); @@ -100,19 +107,19 @@ export const Segmented = React.forwardRef( } }, [selectedValue]); - const handleValueChange = (newValue: string) => { + const handleValueChange = useMemoizedFn((newValue: string) => { setSelectedValue(newValue); onChange?.(newValue); - }; + }); return ( + className={cn(segmentedVariants({ block, type }), height, className)}>