diff --git a/.claude/skills/api-reference/SKILL.md b/.claude/skills/api-reference/SKILL.md index ebf0a95e..88de6a6d 100644 --- a/.claude/skills/api-reference/SKILL.md +++ b/.claude/skills/api-reference/SKILL.md @@ -80,8 +80,8 @@ Create at least a BasicUsage demo in both HTML and React. Load `references/demo- - Follow BEM naming: `{framework}-{component}-{variant}__{element}` - CSS uses data-attribute selectors for state-based styling - React uses `render` prop for state-based rendering -- Video source: `https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/highest.mp4` -- Poster image: `https://image.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/thumbnail.jpg` +- Video source: `https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4` +- Poster image: `https://image.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/thumbnail.jpg` - Consider additional demos for features not covered by BasicUsage ### Step 5: Create MDX reference page diff --git a/.claude/skills/api-reference/references/demo-patterns.md b/.claude/skills/api-reference/references/demo-patterns.md index 56535131..5f599d7d 100644 --- a/.claude/skills/api-reference/references/demo-patterns.md +++ b/.claude/skills/api-reference/references/demo-patterns.md @@ -52,7 +52,7 @@ The `.astro` wrapper is required because only Astro ` diff --git a/site/src/components/Search/Search.tsx b/site/src/components/Search/Search.tsx index 6c58483b..e766865f 100644 --- a/site/src/components/Search/Search.tsx +++ b/site/src/components/Search/Search.tsx @@ -72,12 +72,12 @@ export default function Search({ children, className, baseUrl, bundlePath, searc {children} - + { value: T | null; @@ -31,7 +32,7 @@ export function Select({ ({   - + @@ -49,7 +50,7 @@ export function Select({ ({ 'flex items-center gap-2 p-2', option.disabled ? 'opacity-50 cursor-default' - : 'cursor-pointer intent:bg-light-80 dark:intent:bg-dark-100', - option.value === value && 'bg-light-80 dark:bg-dark-100' + : 'cursor-pointer intent:bg-manila-75 dark:intent:bg-warm-gray', + option.value === value && 'bg-manila-75 dark:bg-warm-gray' )} > {option.label} - + ))} diff --git a/site/src/components/Tabs.tsx b/site/src/components/Tabs.tsx index 20c94500..3fa701d6 100644 --- a/site/src/components/Tabs.tsx +++ b/site/src/components/Tabs.tsx @@ -16,21 +16,25 @@ import clsx from 'clsx'; -import { Check, Copy } from 'lucide-react'; +import { Check } from 'lucide-react'; import { useEffect, useRef, useState } from 'react'; -import { twMerge } from 'tailwind-merge'; +import { twMerge } from '@/utils/twMerge'; import useIsHydrated from '@/utils/useIsHydrated'; import CopyButton from './CopyButton'; +import CopyIcon from './icons/copy-icon.svg?react'; + +export type TabsVariant = 'expanded' | 'compact'; interface TabsRootProps { children: React.ReactNode; maxWidth?: boolean; className?: string; id?: string; + variant?: TabsVariant; } -export function TabsRoot({ children, maxWidth = true, className, id: propId }: TabsRootProps) { +export function TabsRoot({ children, maxWidth = true, className, id: propId, variant = 'compact' }: TabsRootProps) { const ref = useRef(null); const isHydrated = useIsHydrated(); /** @@ -71,9 +75,8 @@ export function TabsRoot({ children, maxWidth = true, className, id: propId }: T ref={ref} className={twMerge( clsx( - 'rounded-lg overflow-hidden border border-light-40 dark:border-dark-80', - 'bg-light-100 dark:bg-dark-110 flex flex-col', - 'my-6', + 'overflow-hidden flex flex-col my-6 border border-faded-black dark:border-manila-dark rounded-xs bg-manila-light dark:bg-faded-black', + variant === 'compact' && 'border px-2.5 pb-2.5', maxWidth && 'w-full max-w-3xl mx-auto', className ) @@ -88,11 +91,19 @@ export function TabsRoot({ children, maxWidth = true, className, id: propId }: T interface TabsListProps { label: string; children: React.ReactNode; + variant?: TabsVariant; } -export function TabsList({ label, children }: TabsListProps) { +export function TabsList({ label, children, variant = 'compact' }: TabsListProps) { return ( -
-
    +
    +
      {children}
    } + className={clsx( + 'ml-auto sticky right-0 h-7 px-2.5 flex items-center justify-center cursor-pointer disabled:cursor-wait intent:bg-warm-gray rounded-xs' + )} + copied={} > - +
    ); @@ -113,8 +126,9 @@ interface TabProps { value: string; children: React.ReactNode; initial?: boolean; + variant?: TabsVariant; } -export function Tab({ value, children, initial }: TabProps) { +export function Tab({ value, children, initial, variant = 'compact' }: TabProps) { const isHydrated = useIsHydrated(); const ref = useRef(null); const [isActive, setIsActive] = useState(initial); @@ -207,7 +221,7 @@ export function Tab({ value, children, initial }: TabProps) { }, []); return ( -
  • +
  • ); @@ -236,8 +267,9 @@ interface TabsPanelProps { children: React.ReactNode; initial?: boolean; className?: string; + variant?: TabsVariant; } -export function TabsPanel({ value, children, initial, className }: TabsPanelProps) { +export function TabsPanel({ value, children, initial, className, variant = 'compact' }: TabsPanelProps) { const ref = useRef(null); const [isActive, setIsActive] = useState(initial); @@ -272,7 +304,10 @@ export function TabsPanel({ value, children, initial, className }: TabsPanelProp role="tabpanel" hidden={!isActive} data-value={value} - className={twMerge(clsx('overflow-scroll p-6 max-h-96 flex-1'), className)} + className={twMerge( + clsx('overflow-scroll p-6 max-h-96 flex-1', variant === 'compact' && 'bg-faded-black dark:bg-soot'), + className + )} > {children}
diff --git a/site/src/components/ThemeInit.astro b/site/src/components/ThemeInit.astro index 4640865d..e750e2ff 100644 --- a/site/src/components/ThemeInit.astro +++ b/site/src/components/ThemeInit.astro @@ -5,29 +5,35 @@ import { THEME_KEY } from '@/consts'; {/* Dark mode initialization script - runs before paint to prevent FOUC */} diff --git a/site/src/components/ThemeToggle.tsx b/site/src/components/ThemeToggle.tsx index 50bbd731..c6a05301 100644 --- a/site/src/components/ThemeToggle.tsx +++ b/site/src/components/ThemeToggle.tsx @@ -1,16 +1,17 @@ -import { Monitor, Moon, Sun } from 'lucide-react'; - import { useEffect, useState } from 'react'; import { THEME_KEY } from '@/consts'; +import Computer from './icons/computer.svg?react'; +import Moon from './icons/moon.svg?react'; +import Sun from './icons/sun.svg?react'; import ToggleGroup from './ToggleGroup'; type Preference = 'system' | 'light' | 'dark'; type Theme = 'light' | 'dark'; const themeOptions = [ - { value: 'system' as const, label: