import { define } from '../../src' import { theme } from '../ssr/themes' import { ButtonExamplesContent } from '../button' import { ProfileExamplesContent } from '../profile' import { NavigationExamplesContent } from '../navigation' import { FormExamplesContent } from '../form' // ThemePicker component const ThemePicker = define('SpaThemePicker', { marginLeft: 'auto', parts: { Select: { base: 'select', padding: `${theme('spacing-xs')} ${theme('spacing-md')}`, background: theme('colors-bgElevated'), border: `1px solid ${theme('colors-border')}`, borderRadius: theme('radius-sm'), color: theme('colors-fg'), fontSize: 14, cursor: 'pointer', transition: 'all 0.2s ease', states: { ':hover': { borderColor: theme('colors-borderActive'), }, ':focus': { outline: 'none', borderColor: theme('colors-borderActive'), } } } }, render({ parts: { Root, Select } }) { return ( ) } }) function themeChanged(e: Event) { const target = e.target as HTMLSelectElement const themeName = target.value document.body.setAttribute('data-theme', themeName) localStorage.setItem('theme', themeName) } export const Main = define('SpaMain', { base: 'div', minHeight: '100%', height: '100%', padding: theme('spacing-xl'), fontFamily: theme('fonts-mono'), background: theme('colors-bg'), color: theme('colors-fg'), boxSizing: 'border-box', }) export const Container = define('SpaContainer', { base: 'div', maxWidth: 1200, margin: '0 auto' }) // Simple client-side router const Link = define('Link', { base: 'a', color: theme('colors-fgMuted'), textDecoration: 'none', fontSize: 14, states: { hover: { color: theme('colors-fg'), } }, selectors: { '&[aria-current]': { color: theme('colors-fg'), textDecoration: 'underline', } }, render({ props, parts: { Root } }) { const handleClick = (e: Event) => { e.preventDefault() window.history.pushState({}, '', props.href) window.dispatchEvent(new Event('routechange')) } return ( {props.children} ) } }) const Nav = define('Nav', { base: 'nav', display: 'flex', gap: theme('spacing-lg'), marginBottom: theme('spacing-xl'), padding: theme('spacing-lg'), background: theme('colors-bgElevated'), border: `1px solid ${theme('colors-border')}`, borderRadius: theme('radius-sm'), }) const P = define('P', { color: theme('colors-fgMuted'), fontSize: 16, marginBottom: theme('spacing-xxl'), }) const ExamplesGrid = define('ExamplesGrid', { display: 'grid', gap: theme('spacing-lg'), gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))' }) const ExampleCard = define('ExampleCard', { base: 'a', background: theme('colors-bgElevated'), padding: theme('spacing-lg'), border: `1px solid ${theme('colors-border')}`, borderRadius: theme('radius-sm'), textDecoration: 'none', display: 'block', states: { hover: { borderColor: theme('colors-borderActive'), } }, parts: { H2: { color: theme('colors-fg'), margin: `0 0 ${theme('spacing-sm')} 0`, fontSize: 18, fontWeight: 400, }, P: { color: theme('colors-fgMuted'), margin: 0, fontSize: 14, } }, render({ props: { title, desc, ...props }, parts: { Root, H2, P } }) { const handleClick = (e: Event) => { e.preventDefault() window.history.pushState({}, '', props.href) window.dispatchEvent(new Event('routechange')) } return (

{title}

{desc}

) } }) const HomePage = () => ( <>

Client-side rendered examples. Click around, check the source.

) const ProfilePage = () => const ButtonsPage = () => const NavigationPage = () => const FormPage = () => export function route(path: string) { switch (path) { case '/spa': case '/spa/': return case '/spa/profile': return case '/spa/buttons': return case '/spa/navigation': return case '/spa/form': return default: return

404 Not Found

} } const HomeLink = define('HomeLink', { base: 'a', color: theme('colors-fgMuted'), textDecoration: 'none', fontSize: 14, states: { hover: { color: theme('colors-fg'), } } }) export function App() { const path = window.location.pathname return (
{route(path)}
) }