Skip to main content

Component examples

Existing UI APIs stay available through the compatibility layer. Use the primitives entry point for native Astryx APIs, and site components for page structure.

Design Tokens

Compatibility token names resolved through the shared Newth theme. Prefer semantic Astryx tokens for new site-specific styles.

Core Colors

Background
--color-bg
Background Secondary
--color-bg-secondary
White (foreground)
--color-white
Grey 100
--color-grey-100
Grey 200
--color-grey-200
Grey 300
--color-grey-300
Grey 400
--color-grey-400
Grey 600
--color-grey-600
Grey 800
--color-grey-800

Category Colors

Sage
--color-sage
Coral
--color-coral
Mint
--color-mint
Gold
--color-gold

Legacy surface aliases

Glass Background
--glass-bg
Glass Border
--glass-border
Glass Highlight
--glass-highlight

Compatibility surface

Compatibility border

Typography

Satoshi (Display)

Geist Sans (Body/UI)

Geist Mono (Code)

Usage

/* CSS custom properties */
.my-component {
background: var(--glass-bg);
border: 1px solid var(--glass-border);
color: var(--color-white);
}
/* Tailwind classes via preset */
<div className="bg-glass-bg border-glass-border text-white" />

Controls

Interactive examples of the existing UI compatibility API. Native Astryx props are available through @n3wth/ui/primitives.

Button

Variant:Size:
<Button variant="primary" size="md">
Button
</Button>

Badge

Variant:Size:
DefaultStatusv1.0
<Badge variant="default" size="sm">
Default
</Badge>

Input

Variant:Size:
<Input
variant="default"
inputSize="md"
placeholder="Type something..."
/>

Icon (Iconoir)

Size:Color:
arrow-right
arrow-left
arrow-up
arrow-down
chevron-right
chevron-left
chevron-up
chevron-down
check
x
copy
search
menu
sun
moon
external
github
terminal
code
plus
minus
settings
user
heart
star
mail
calendar
clock
bell
home
folder
file
trash
edit
eye
eye-off
lock
unlock
link
external-link
download
upload
refresh
filter
sort
grid
list
more-horizontal
more-vertical
info
warning
success
error
<Icon name="search" size="md" />
<Icon name="github" size="md" />

CodeBlock

import { Nav, Hero, Button, useTheme } from '@n3wth/ui'
import '@n3wth/ui/styles'
function App() {
const { theme, toggleTheme } = useTheme()
return (
<Nav
logo="myapp"
items={[
{ label: 'Home', href: '/' },
{ label: 'About', href: '/about' },
]}
theme={theme}
onThemeToggle={toggleTheme}
fixed
hideOnScroll
/>
)
}
// Quick start
npm install @n3wth/ui

Compositions

Interactive examples of the existing UI compatibility API. Native Astryx props are available through @n3wth/ui/primitives.

Card

Variant:Padding:

Default Card

Basic border card

Cards contain content and actions about a single subject.

<Card variant="default">
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Description text</CardDescription>
</CardHeader>
<CardContent>Content here</CardContent>
<CardFooter>
<Button size="sm" variant="secondary">Action</Button>
</CardFooter>
</Card>

Tabs

Variant:

Overview content with animated indicator that follows the active tab.

<Tabs value={tab} onChange={setTab} variant="underline">
<TabsList>
<TabsTab value="tab1">Overview</TabsTab>
<TabsTab value="tab2">Features</TabsTab>
</TabsList>
<TabsPanel value="tab1">Overview content</TabsPanel>
<TabsPanel value="tab2">Features content</TabsPanel>
</Tabs>

Modal

Size:
<Modal isOpen={open} onClose={() => setOpen(false)} size="md">
<ModalHeader>
<div>
<ModalTitle>Modal Title</ModalTitle>
<ModalDescription>Description text</ModalDescription>
</div>
<ModalCloseButton onClick={() => setOpen(false)} />
</ModalHeader>
<ModalBody>Content here</ModalBody>
<ModalFooter>
<Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button>
<Button onClick={() => setOpen(false)}>Confirm</Button>
</ModalFooter>
</Modal>

Toast

Variant:
// Standalone
<Toast
variant="success"
title="Toast Title"
description="Toast description"
duration={5000}
onDismiss={() => setShow(false)}
/>
// With useToast hook + Provider
const { toast } = useToast()
toast.success({ title: 'Done!', description: 'Action completed' })

NavLink

Variant:
<NavLink href="/about" variant="underline" isActive>
About
</NavLink>

CommandBox

npm install @n3wth/ui
<CommandBox command="npm install @n3wth/ui" />

ThemeToggle

Current: dark
const { theme, toggleTheme } = useTheme()
<ThemeToggle theme={theme} onToggle={toggleTheme} size="md" />

Site patterns

Page structure belongs to the shared UI layer. The live shell uses these components.

Navigation and footer

import { SiteNavigation, SiteFooter } from '@n3wth/ui/site'
<SiteNavigation brand={<a href="/">My site</a>}
links={<a href="/work">Work</a>} />
<SiteFooter sourceHref="https://github.com/n3wth/n3wth" />

Hero and sections

import { PageHeader, SiteSection, SiteHeading, SiteText } from '@n3wth/ui/site'
<PageHeader title="Work" description="Selected projects."
actions={<a href="/resume.pdf">Resume (PDF)</a>} />
<SiteSection>
<SiteHeading>Projects</SiteHeading>
<SiteText>What each project helps people do.</SiteText>
</SiteSection>

Decorative visual bands

import { AssembleField, VisualBand } from '@n3wth/ui/visuals'
import '@n3wth/ui/site.css'
<VisualBand height="clamp(190px, 34svh, 340px)">
<AssembleField clusters={[[530, 132], [645, 284], [762, 158]]}
width={900} height={400} />
</VisualBand>

Hooks

React hooks for theme, media queries, accessibility, and animations.

useTheme

Current theme:dark
import { useTheme } from '@n3wth/ui'
function ThemeSwitch() {
const { theme, setTheme, toggleTheme } = useTheme()
return (
<button onClick={toggleTheme}>
{theme === 'dark' ? 'Switch to Light' : 'Switch to Dark'}
</button>
)
}

useMediaQuery / useIsMobile / useBreakpoint

Mobile: YesTablet: NoDesktop: No

Current breakpoint: xs

import { useIsMobile, useBreakpoint, useMediaQuery } from '@n3wth/ui'
function ResponsiveLayout() {
const isMobile = useIsMobile() // < 768px
const isTablet = useIsTablet() // 768-1023px
const isDesktop = useIsDesktop() // >= 1024px
const breakpoint = useBreakpoint() // 'sm' | 'md' | 'lg' | 'xl' | '2xl'
const isWide = useMediaQuery('(min-width: 1440px)')
return (
<div className={isMobile ? 'stack' : 'grid-cols-3'}>
{isWide && <Sidebar />}
<Main />
</div>
)
}

useReducedMotion

prefers-reduced-motion:Reduced
import { useReducedMotion } from '@n3wth/ui'
function AnimatedCard() {
const prefersReducedMotion = useReducedMotion()
return (
<div
className={prefersReducedMotion ? 'opacity-100' : 'animate-fade-in'}
style={{ transition: prefersReducedMotion ? 'none' : 'all 0.3s ease' }}
>
Accessible animation
</div>
)
}

useCountUp

0
import { useCountUp } from '@n3wth/ui'
function StatsCounter() {
const { value, ref } = useCountUp({
end: 1000,
duration: 2,
startOnView: true,
})
return <span ref={ref}>{value}</span>
}

useKeyboardShortcuts

Register keyboard shortcuts with modifier keys. Handles platform differences (Cmd vs Ctrl) automatically.

import { useKeyboardShortcuts, getModifierKey } from '@n3wth/ui'
function SearchDialog() {
const [open, setOpen] = useState(false)
const modKey = getModifierKey() // 'Cmd' | 'Ctrl'
useKeyboardShortcuts([
{
key: 'k',
modifiers: ['meta'],
handler: () => setOpen(true),
description: 'Open search',
},
])
return <span>Press {modKey}+K to search</span>
}

Motion policy

Keep route content visible immediately. Existing animation hooks are compatibility tools for deliberate demonstrations and functional feedback, not a default page treatment.