Files
ADS3-Design-System/src/components/atoms/List/List.tsx
Richie d915443b8c Align design system with ADS 3.0 and add new components
Token foundation: fix 16 palette colours to match official ADS_COLORS,
add 5 new palettes (teal, brown, purple, fuchsia, yellow), realign
semantic tokens (primary=navy, info=bright blue), fix border radii to
8px base, add responsive heading typography.

Component migration: swap primary/info references across all existing
components, update Button (44px/semibold), Switch (green/compact),
Chip (30px/8px radius + colour variants), SideNav (80px rail), Tag
(11 colours).

New components: SideNav, TopBar, Avatar, Tabs, PageHeader, Slider,
RangeSlider, FileInput, DataTable, List, Autocomplete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-03 14:24:23 +10:00

97 lines
2.4 KiB
TypeScript

import { forwardRef, type HTMLAttributes, type ReactNode } from 'react'
import { cn } from '@/lib/utils'
// --- List ---
export interface ListProps extends HTMLAttributes<HTMLUListElement> {}
export const List = forwardRef<HTMLUListElement, ListProps>(
({ className, children, ...props }, ref) => (
<ul
ref={ref}
role="list"
className={cn('flex flex-col bg-surface', className)}
{...props}
>
{children}
</ul>
),
)
List.displayName = 'List'
// --- ListItem ---
export interface ListItemProps extends HTMLAttributes<HTMLLIElement> {
icon?: ReactNode
active?: boolean
disabled?: boolean
href?: string
}
export const ListItem = forwardRef<HTMLLIElement, ListItemProps>(
({ icon, active = false, disabled = false, href, className, children, ...props }, ref) => {
const styles = cn(
'flex min-h-12 items-center gap-4 px-4 py-2 transition-colors',
active
? 'bg-info/12 text-info'
: 'text-text hover:bg-text/[0.04]',
disabled && 'pointer-events-none opacity-55',
className,
)
const content = (
<>
{icon && (
<span className={cn('size-6 shrink-0 [&>svg]:size-full', active ? 'text-info' : 'text-text-secondary')}>
{icon}
</span>
)}
<span className="flex-1 text-body">{children}</span>
</>
)
if (href) {
return (
<li ref={ref} {...props}>
<a href={href} className={styles}>{content}</a>
</li>
)
}
return (
<li ref={ref} role="listitem" className={styles} {...props}>
{content}
</li>
)
},
)
ListItem.displayName = 'ListItem'
// --- ListSubheader ---
export interface ListSubheaderProps extends HTMLAttributes<HTMLLIElement> {}
export const ListSubheader = forwardRef<HTMLLIElement, ListSubheaderProps>(
({ className, children, ...props }, ref) => (
<li
ref={ref}
className={cn('flex min-h-10 items-center px-4 text-small font-semibold text-text-secondary', className)}
{...props}
>
{children}
</li>
),
)
ListSubheader.displayName = 'ListSubheader'
// --- ListDivider ---
export interface ListDividerProps extends HTMLAttributes<HTMLLIElement> {}
export const ListDivider = forwardRef<HTMLLIElement, ListDividerProps>(
({ className, ...props }, ref) => (
<li ref={ref} role="separator" className={cn('border-t border-border', className)} {...props} />
),
)
ListDivider.displayName = 'ListDivider'