feat (v1.0.0): initial refactor and redesign
This commit is contained in:
parent
3058aa1ab4
commit
fe9b50b30e
134 changed files with 17792 additions and 3670 deletions
71
app/ai/usage/components/SegmentedControl.tsx
Normal file
71
app/ai/usage/components/SegmentedControl.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
"use client"
|
||||
|
||||
import { type ReactNode } from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface SegmentedOption<T extends string> {
|
||||
id: T
|
||||
label: string
|
||||
icon?: ReactNode
|
||||
disabled?: boolean
|
||||
accentColor?: string
|
||||
}
|
||||
|
||||
interface SegmentedControlProps<T extends string> {
|
||||
options: SegmentedOption<T>[]
|
||||
value: T
|
||||
onChange?: (value: T) => void
|
||||
disabled?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function SegmentedControl<T extends string>({
|
||||
options,
|
||||
value,
|
||||
onChange,
|
||||
disabled = false,
|
||||
className,
|
||||
}: SegmentedControlProps<T>) {
|
||||
return (
|
||||
<div className={cn('inline-flex rounded-xl border border-gray-800 bg-gray-900/60 p-1', className)}>
|
||||
{options.map((option, index) => {
|
||||
const isSelected = option.id === value
|
||||
const isDisabled = disabled || option.disabled
|
||||
const accent = option.accentColor ?? '#f9fafb'
|
||||
|
||||
return (
|
||||
<button
|
||||
key={option.id}
|
||||
type="button"
|
||||
aria-pressed={isSelected}
|
||||
disabled={isDisabled}
|
||||
onClick={() => {
|
||||
if (!isDisabled && option.id !== value) onChange?.(option.id)
|
||||
}}
|
||||
className={cn(
|
||||
'flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all duration-200',
|
||||
isSelected && 'bg-gray-800 text-gray-100',
|
||||
!isSelected && !isDisabled && 'text-gray-400 hover:text-gray-200 hover:bg-gray-800/50',
|
||||
isDisabled && 'text-gray-600 cursor-not-allowed opacity-50',
|
||||
index > 0 && 'ml-1'
|
||||
)}
|
||||
style={isSelected ? { boxShadow: `0 0 0 1px ${accent}`, color: accent } : undefined}
|
||||
>
|
||||
{option.icon && (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="flex items-center"
|
||||
style={{
|
||||
color: isSelected ? accent : isDisabled ? '#4b5563' : '#9ca3af',
|
||||
}}
|
||||
>
|
||||
{option.icon}
|
||||
</span>
|
||||
)}
|
||||
{option.label}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue