Sangria DS

States

Every combination, not every variant

A variant list shows what a component can look like. A matrix shows what it actually reaches. Button, Badge, Input, NativeSelect and the accent helpers are the app's own files; the rows around them are replicas built from the app's class strings. Toggle dark in the header to check both grounds.

Button

ui/button.tsx

Hover applies each variant's own hover classes; focus is its focus-visible ring (ring-2 ring-ring ring-offset-2).

rest
hover
focus
disabled
default
destructive
outline
secondary
ghost
link
transparent

Sidebar item

Rows built from the app's SIDEBAR_ROW_CLASS and sidebarItemClass on each theme's list colour. Read rows dim to brightness .85, the floor that keeps 4.5:1 against the lightest stop of most rails, and lift to full on hover, where some themes also brighten the text. Unread is white at 900 and stays white on hover; active is the theme's own sidebarItem.active at 700. Channels mark unread by weight alone; DM rows add SIDEBAR_COUNT_PILL_CLASS.

use-sidebar-item-styles.ts
rest
hover
active
unread
unread dm
theme=classic
#design
#design
#design
#design
@priya3
theme=onyx
#design
#design
#design
#design
@priya3
theme=aurora
#design
#design
#design
#design
@priya3

Reaction

Own reactions fill with withAlpha(accent, 0.12), 12% in both modes, under a 1px inset accent ring, and only the count takes the accent, at 900. They have no hover style. Others are muted with a hairline ring that darkens on hover. 24px pills, 32px under md.

components/reactions.tsx
other
other 路 hover
own
own 路 hover
add
add 路 hover
theme=classic
馃憖2
馃憖2
馃憖2
馃憖2
theme=onyx
馃憖2
馃憖2
馃憖2
馃憖2
< md 路 classic
馃憖2
馃憖2
馃憖2
馃憖2

Badges and count pills

Badge is the primitive. Count pills are not: they read --theme-badge, which the shell sets to the theme's pastel accent.dark in both modes, with #16090e text. The rail badge is the same fill at 16px, falling back to #ECB22E outside a workspace; a nav row's count (Drafts & sent) is neutral white/20.

ui/badge.tsx
default
secondary
destructive
outline
rest
Admin
Guest
Removed
Bot
SIDEBAR_COUNT_PILL_CLASS 路 sidebar-button.tsx 路 sidebar-item.tsx
dm unread
rail badge
nav count
theme=classic
12
2
4
theme=onyx
12
2
4
theme=aurora
12
2
4

Selected

The shared selection style is accentSelected from lib/accent.ts: an accent tint (8% light, 15% dark) that persists under the pointer, plus accent text. Not every consumer takes all of it, and each keeps its own hover: classes, so every row is composed the way its file composes it. Only the status picker keeps tint and accent text on hover; the preferences tabs, the settings sidebar and the mode picker keep the tint but hover their text to foreground. Theme cards and the huddle invite list take the bare tint, so in light they drop to the grey hover; in dark the tint's dark: rule is emitted after hover:bg-accent and holds. Tabs use an accent underline instead of a tint. Shown in Classic.

Page mode

Follows the header toggle.

rest
hover
selected
selected + hover
Preferences tab
preferences-modal.tsx
Notifications
Notifications
Notifications
Notifications
Settings sidebar
customize-workspace/sidebar.tsx
Mode picker
appearance-settings.tsx
Status picker
status-modal.tsx
馃尨On holiday
馃尨On holiday
馃尨On holiday
馃尨On holiday
Theme card
appearance-settings.tsx
Classic
Classic
Classic
Classic
Huddle invite
new-huddle-modal.tsx
MCMaya Chen
MCMaya Chen
MCMaya Chen
MCMaya Chen
Settings tabs
account 路 channels pages
Profile
Profile
Profile
Profile
Message tabs
message-tabs.tsx
Files
Files
Files
Files

Forced dark

Wrapped in its own .dark, so it reads dark whatever the header toggle says.

rest
hover
selected
selected + hover
Preferences tab
preferences-modal.tsx
Notifications
Notifications
Notifications
Notifications
Settings sidebar
customize-workspace/sidebar.tsx
Mode picker
appearance-settings.tsx
Status picker
status-modal.tsx
馃尨On holiday
馃尨On holiday
馃尨On holiday
馃尨On holiday
Theme card
appearance-settings.tsx
Classic
Classic
Classic
Classic
Huddle invite
new-huddle-modal.tsx
MCMaya Chen
MCMaya Chen
MCMaya Chen
MCMaya Chen
Settings tabs
account 路 channels pages
Profile
Profile
Profile
Profile
Message tabs
message-tabs.tsx
Files
Files
Files
Files

Focus

Buttons, inputs, switches and tabs take the focus ring. Native selects don't: browsers treat a mouse click on a <select> as keyboard focus, so a ring would flash on every click, and a border shift is the cue instead. The composer uses a border shift too (focus-within). Composer toolbar buttons get a 2px inset outline, and huddle invite rows only fill.

rest
focus
Button
Input
NativeSelect
Composer
Message #design
Message #design
Toolbar button
B
B
Huddle invite
Maya Chen
Maya Chen