@fohte/ui
Shared design tokens and React components for fohte applications.
Installation
pnpm add @fohte/ui
Usage
@import 'tailwindcss';
@import '@fohte/ui/tokens.css';
The package provides light tokens at :root and dark tokens under .dark, plus font stacks, radius values, and a 2xs text size. Colors are available as Tailwind utilities such as bg-background and text-foreground.
The package does not follow prefers-color-scheme; the consuming application controls when .dark is applied. Tailwind CSS v4 is required to process the @theme directives. The font stacks reference JetBrains Mono Variable and IBM Plex Mono, which this package does not bundle; load the font files in your application if needed.
React components
Import components from their subpaths:
import { BottomNavigation } from '@fohte/ui/bottom-navigation'
import { Button } from '@fohte/ui/button'
import { ButtonGroup } from '@fohte/ui/button-group'
import { Checkbox } from '@fohte/ui/checkbox'
import { Chip } from '@fohte/ui/chip'
import { CommandPalette } from '@fohte/ui/command-palette'
import { Dialog, DialogContent, DialogTitle } from '@fohte/ui/dialog'
import { FieldTrigger } from '@fohte/ui/field-trigger'
import { Input } from '@fohte/ui/input'
import { Kbd } from '@fohte/ui/kbd'
import { List, ListItem } from '@fohte/ui/list'
import { Panel } from '@fohte/ui/panel'
import { Popover, PopoverContent, PopoverTrigger } from '@fohte/ui/popover'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@fohte/ui/select'
import { SegmentedControl } from '@fohte/ui/segmented-control'
import { Tabs, TabsList, TabsPanel, TabsTab } from '@fohte/ui/tabs'
import { Textarea } from '@fohte/ui/textarea'
import { Tooltip, TooltipContent, TooltipTrigger } from '@fohte/ui/tooltip'
BottomNavigation accepts links and action buttons in one horizontal row. Each item has an id and visible label, and can also include an icon, selected state, and className. Link items use renderLink to wrap the content with the consuming application's router component. The render slot receives the link content, styling class, and current-page state. Replace openComposer in the example with the application's action handler.
import {
BottomNavigation,
type BottomNavigationItem,
} from '@fohte/ui/bottom-navigation'
const items = [
{
id: 'overview',
type: 'link' as const,
label: 'Overview',
selected: true,
renderLink: ({ children, ...props }) => (
<a href="/overview" {...props}>
{children}
</a>
),
},
{
id: 'compose',
type: 'button' as const,
label: 'Compose',
onClick: openComposer,
},
] satisfies ReadonlyArray<BottomNavigationItem>
<BottomNavigation aria-label="Primary navigation" items={items} />
The component provides semantic token colors, single-line labels, and horizontal scrolling when the items do not fit. Pass className to style or position the navigation for the application layout, and set an item's className to customize its appearance. fixed or sticky placement and space for the bar remain the consuming application's responsibility.
React, React DOM, @base-ui/react, and lucide-react are peer dependencies. Make sure they are available in the consuming application. Their supported version ranges are declared in package.json.
The component subpaths publish TSX source, so the consuming bundler must transform TSX from dependencies.
The components also require Tailwind CSS v4, tw-animate-css, and shadcn in the consuming application. Install them as development dependencies if they are not already present:
pnpm add -D tailwindcss@^4 tw-animate-css@^1 shadcn@^4
For example, a select can be composed from its trigger, value, content, and items:
<Select defaultValue="first">
<SelectTrigger aria-label="Choose an option">
<SelectValue placeholder="Choose an option" />
</SelectTrigger>
<SelectContent>
<SelectItem value="first">First option</SelectItem>
<SelectItem value="second">Second option</SelectItem>
</SelectContent>
</Select>
The consuming application's CSS must load Tailwind CSS v4, tw-animate-css, shadcn/tailwind.css, and this package's tokens. Tailwind v4 ignores dependency files by default, so explicitly register the package source using @source. Adjust the path relative to the stylesheet:
@import 'tailwindcss';
@import 'tw-animate-css';
@import 'shadcn/tailwind.css';
@import '@fohte/ui/tokens.css';
@source '../node_modules/@fohte/ui/src';
License
MIT © Hayato Kawai