Repository navigation
Releases: httpassoca/dssoca
Release list
v0.19.0 — TierList, docs IA & mobile key caps
Added
TierListcomponent (DS-0159,DS-0160) — labelled tier rows (S / A / B / C / D by
default, or any{ id, label, color? }list) plus an unranked tray, holding one tile per
item. Tiles move by pointer drag between and within rows (Pointer Events, so touch works;
live reorder with a ghost under the pointer, commit on release) and by keyboard (Space
picks up, arrows move — left/right within the row, up/down across rows, Home/End — Space
drops, Escape cancels) with every step read out by a polite live region, so ranking never
depends on dragging (WCAG 2.2 SC 2.5.7). Presentational: what a tile shows is yourtile
snippet; the result comes back asplacements(tier id → ordered item ids) through
bind:placements/onchange;onselectactivates a tile (Enter / click);readonlyshows
someone else's ranking. Row accents are palette slots (accent, cyan, yellow, muted, red, …)
as Badge-style washes — no colour literals; sizes read the new--ss-tier-*tokens
(src/styles/components/_tierlist.scss). No runtime dependency: the pure model, move maths
and wording live intierlist-core.ts, shared with the plain-HTML behaviour
(dssoca/vanilla.jsnow drives the rendered markup: same drag + keyboard paths, emits
ss:changewith{ placements },data-ss-readonlymakes it inert). Ported from the
passoca roulette tierlist minus its app logic (posters, autosave, publish, export).- Inspirations gallery inside the docs (
DS-0158)./inspirationson the docs site lists
every example website — same cards, blurbs, component chips and thumbnails as the GitHub Pages
gallery — inside the docs layout and axes; each card opens its site on the Pages host in a new
tab. The nav entry is internal now (Explore group) and search routes to it. One source of
truth:inspirations/manifest.jsonfeeds both galleries (the Pages gallery's cards are rendered
intoindex.htmlat build time from it — adding a site is a folder + a manifest entry),
drift-guarded by the root and docs test suites. Thumbnails are hot-linked from the Pages host
with the striped placeholder as fallback. Cardexternalprop (DS-0158) — withhref, the overlay link opens in a new tab
(target="_blank",rel="noopener noreferrer") and announces "(opens in a new tab)", matching
Sidebar'sexternal.Iconsearchglyph (DS-0157) — a magnifier, used by Topbar's command button on touch
devices (below) and available to consumers like every other built-in.
Changed
- Inspirations gallery cards: head laid out as two rows (
DS-0158) — title with the ↗ at its
end, then the kind on its own line — on both the Pages gallery and the docs gallery. Kbdhides itself on keyboard-less devices —hideOnMobileprop, defaulttrue
(DS-0157; behaviour change). Key-cap chips are noise where the only input is a finger, so
on@media (hover: none) and (pointer: coarse)viewports (phones, tablets) the chip is now
display: none— a capability query, not a width, so a narrow desktop window keeps its hints.
PasshideOnMobile={false}where the chip is the content rather than a hint; it then renders
data-hide-on-mobile="false"on the root, which is also the plain-HTML opt-out (bare
<kbd class="ss-kbd">markup gets the new default with no changes).ShortcutsHelpopts its
rows out;Topbar's command button swaps the hidden ⌘K chip for a decorativesearchglyph on
those devices so the tap target never renders empty. Audit your own "Enter to send"-style
sentences: the chip hides, the words around it are yours to hide. The Inspirations sites do
exactly that.- Docs sidebar — grouped guide pages (
DS-0156). The flat run of nine links above the
component list is now three labelled groups: Getting started (Introduction, Installation,
Plain HTML & CSS), Configuration (Theming & config, Tokens, Theme Builder, Keyboard) and
Explore (Inspirations, Color theory, All components). No page moved URL;NAVgroups
carry a stablesectionkey plus a renderedlabel, and the search palette hints each
page with its group. Membership is pinned by the docs tests.
Fixed
- Inspirations thumbnails on GitHub Pages (hotfix after 0.18.0) — the screenshot script
ran the Playwright CLI synchronously from the same process that serves the built site, so
the browser's first request was never answered and the Pages run hung; the capture is
asynchronous now, with a hard timeout, and the suite pins it.
Full changelog: v0.18.0...v0.19.0
v0.17.0 — plain HTML & CSS consumption
Added
dssoca/vanilla.css— every component's styles for plain-HTML pages (DS-0148). A new
stylesheet generated inprepack(scripts/build-vanilla.mjs) from the components' own
compiled<style>blocks — never hand-written, so it cannot drift from the Svelte components.
Each component is wrapped in a donut@scope (.ss-root) to (<every other root>)block so the
unprefixed internal class names stay isolated in a global sheet (root-led selectors get a
zero-specificity:where(:scope)prefix so they still match the root);@keyframesare hoisted; the
four:global()rules are emitted root-anchored. The markup contract is the exact DOM the Svelte
components render. Load it aftertheme.css/tokens.css. Requires CSS@scope
(Chrome/Edge 118+, Safari 17.4+, Firefox 2026+) — no fallback.dssoca/vanilla.js— small, dependency-free behaviours for that markup (DS-0148). An ES
module (relative imports only, loads straight from jsDelivr) that wires, via document-level
event delegation: Modal (data-ss-modal="#id"openers,data-ss-dismiss, backdrop click,
data-ss-static/data-ss-no-esc), Accordion (data-ss-multiple), Menu, Tooltip (basic
placement, no collision engine), Switch, SegmentedControl (data-value), Input clear,
NumberField steppers and Textarea autosize fallback; bubblingss:change/ss:selectevents;
a framework-freetoast/toastsAPI with the same names and defaults as the Svelte one
(renders the Toaster DOM; swipe-to-dismiss not ported);iconSvg/hydrateIconsfor
<span data-ss-icon="name">placeholders;mount(root); and re-exports of
applyDesignConfig& friends.- CSS-only Spinner in
vanilla.css:steps()keyframes generated fromSPINNER_VARIANTS
drive.frame:empty::before; pick the glyph set withdata-varianton the root. src/lib/icons.tsandsrc/lib/spinner-frames.tsnow holdBUILTIN_PATHS/registerIcon
andSPINNER_VARIANTS;Icon.svelte/Spinner.sveltere-export them, andtoast-core.ts
holds the toast types + timer shared by both stores. Public API unchanged.
Changed
- The three unprefixed component
@keyframes(pulse,skeleton-pulse,sk-shimmer) are now
ss-logs-pulse,ss-metric-skeleton-pulse,ss-svc-shimmerso they are safe in a global
sheet (Svelte hash-scoped them before; no visual change).
Deprecated
- The global
.ss-tablelayout class intheme.css(DS-0148) — it predates theTable
component, whose root shares the name. Unchanged in 0.17.0, removed in 0.18.0 (DS-0149).
Use<Table>or its markup +vanilla.css(loaded aftertheme.css).
Docs
- New guide: Plain HTML & CSS (
/vanilla) — install (npm + CDN), load order, the@scope
browser floor, thedata-ss-*contract, thetoastAPI, icons, the CSS-only list, caveats. - Every component page gains an HTML section whose markup is produced at docs build time by
server-rendering the real component (+page.server.ts+svelte/server), with the scoping
hashes stripped and the vanilla hooks added — so snippets can never drift. Each component doc
declares anhtmlExample(props + snippets +behaviour: 'js' | 'css'), enforced by
pnpm docs:test. README,DESIGN.mdandCLAUDE.mdreplace the 0.3.0 "hand-rolling
.ss-btnno longer works" policy with the vanilla policy. A live HTML playground is a planned
follow-up.
v0.16.0 — collision-aware tooltips, keyboard-friendly docs
Added
Tooltipavoids viewport collisions (DS-0146) —placementis now the preferred side: the tip flips (opposite → roomier perpendicular → roomiest) and shifts along the cross axis to stay inside the viewport and anyoverflow-clipping ancestor; re-measures on scroll/resize while open. Resolved side exposed asdata-placement;avoidCollisions={false}pins it. Zero dependencies.
Docs
- Keyboard-friendly, searchable docs site (DS-0147) — dogfoods
Topbar(⌘K),SearchPalette(pages, components with searchable props, actions) and editableShortcutsHelpwith persisted overrides. Bindings:mod+k·/·?, mod+/·shift+dtheme ·shift+ssize.
Full notes: CHANGELOG.md
v0.15.0 — richer tooltips, fullscreen modals
Added
-
Tooltipaccepts a rendered template (DS-0144) —textwidens fromstringtostring | Snippet, so a tip can hold a small template (a<code>path, aKbdchip, an emphasised label) instead of one flat string. A snippet renders inside the same tip element, so thearia-describedbycontract is unchanged: the accessible description stays whatever the tip contains. Existingtext="…"call sites are unaffected.Markup only, not interaction — the tip keeps
pointer-events: noneand stayshiddenwhile closed, per the WAI-ARIA tooltip pattern, so snippets must be non-interactive phrasing content (code,strong,kbd,br,Icon); interactive hints belong in a click-triggered toggletip/popover..tipnow usesdisplay: blockso wrapped/multi-line content lays out correctly. -
Modalfullscreen variant (DS-0145) — newfullscreenprop (defaultfalse) fills the viewport instead of rendering a centred, capped panel: header and footer stay pinned, the body owns the scroll, and100dvh/100dvw(with avh/vwfallback) keeps mobile browser chrome from overshooting. A boolean rather than asize="full"value, sincesm|md|lgis a design axis and "full" is a layout mode — in this mode the size variants go inert. Responsiveness stays with the caller (fullscreen={width < 640}). A full-bleed panel leaves no backdrop area to hit, socloseOnBackdropis unreachable there — the close button and Esc are the exits.
Changed
- Releases publish via npm Trusted Publishing (
DS-0143) — creating a GitHub release now triggersrelease.yml, which OIDC-authenticates to npm (no token, no OTP) and runspnpm publish --access public --provenance. A guard step asserts the tag matchespackage.json.
Full changelog: https://github.com/httpassoca/dssoca/blob/v0.15.0/CHANGELOG.md
v0.14.0 — preset terminal themes
Added
-
Preset terminal palettes (
DS-0142) — six ready-made 19-slot palettes asPRESET_THEMES+presetPalette(): Dracula (light = the official Alucard Classic), Tokyo Night (Night + Day), Gruvbox (dark + light), Nord (dark-only), Solarized (dark + light), and Coffee (light-only). Faithful upstream hues; neutrals role-mapped to the dssoca slot conventions; WCAG 2.2 AA-failing text slots nudged along OKLCH lightness only (each commented with the upstream value and pinned by tests). Single-mode presets mirror into both themes.import { applyDesignConfig, presetPalette } from 'dssoca' applyDesignConfig({ palette: presetPalette('dracula') })
-
Theme Builder preset examples — the docs Theme Builder offers every preset as an example button: picking one loads the full palette as editable slot overrides.
Fixed
- Theme Builder preset buttons — gap between the color swatch dot and the label.
Full details in CHANGELOG.md.
v0.13.0 — keyboard shortcuts + SearchPalette
Added
- SearchPalette (DS-0133) — Cmd/Ctrl+K search & command palette: native
<dialog>modal combobox (APG pattern), grouped generic items, router-nativehrefnavigation, snippets for row/empty/footer. - Keyboard shortcuts (DS-0135 epic):
shortcutsregistry singleton +{@attach shortcut(...)}— tinykeys-style grammar (mod+k, comma alternatives), guarded single window listener, focus-scope conflict tiers, SSR-safe.- WCAG 2.1.4 built in:
setEnabled/remap, globalenabled/characterKeysswitches, serializable overrides. Kbd— display-only key-cap chip (glyph/label,platformprop).ShortcutsHelp— the "?" overlay rendering live registry state;editablemode ships a complete remap/disable settings UI./keyboarddocs guide: "Making your site keyboard-friendly with dssoca".
Switch labelHiddenprop.
Changed (pre-1.0 minor)
- Peer dependency:
svelte@^5.29.0(was^5.0.0) — attachments. - Topbar & SearchPalette register
mod+kthrough the registry and it now fires on the platform modifier only (Ctrl+K no longer triggers on macOS). Restore the old reach:shortcuts.remap('ss:topbar-command', 'mod+k, ctrl+k').
Full details in CHANGELOG.md.
v0.12.0 — monochromatic terminal color rework + DS-0107 component polish
The color system is rebuilt as a monochromatic 16-slot terminal palette, and the DS-0107 component polish round ships alongside it. Full details: CHANGELOG.md → 0.12.0.
Highlights
- Two-layer color architecture — a generated OKLCH root layer (16 ANSI slots +
bg/fg/--ss-accent, seeded from the brand green#66ef73; the dark background follows the complement rule; every text slot AA-solved on both surfaces, asserted in tests) and a semantic layer derived entirely viavar()/color-mix(). Regenerate withpnpm gen:palette. - Custom palettes —
applyDesignConfig({ palette })(runtime) andpaletteToCss()(zero-JS/SSR), plus an interactive Theme Builder and a Color theory guide in the docs. CHART_PALETTEexported; chart family + Avatar share one slot-based categorical palette.- DS-0107: Icon fixed size scale + chevron, configurable default Spinner variant, Button Spinner-variant loading, Badge six semantic tones, coordinated inner sizes,
--ss-gap-xs.
Breaking (pre-1.0 minor)
- Status hues carry new values;
--ss-purple→--ss-magenta,--ss-lime→--ss-green(deprecated aliases shipped for one minor). --ss-primary-rgb/--ss-red-rgbremoved — migrate tocolor-mix(in srgb, var(--ss-accent|--ss-danger) N%, transparent).- Badge tone rename (six semantic tones) and
Buttonloading: boolean | SpinnerVariant(DS-0107).
v0.10.0 — geossoca component gaps
Eleven new components (DS-0090 epic): Chart (D3-backed), Table, Select, Modal, DateField, FileDrop, NumberField, Tooltip, Avatar, Pagination, Switch.
Introduces the design system's first runtime dependencies (d3-scale, d3-shape, d3-array) — used only by Chart; every other component stays dependency-free.
See CHANGELOG.md for the full list.
v0.9.0 — adoption gaps & tooling hardening
Everything the passoca migration revealed as missing (DS-0079 epic), plus the quality-scan
tooling pass (DS-0066 epic).
Added
- New components (
DS-0083–DS-0086):Heading(display recipe via tokens),Container
(page-width wrapper),Textarea(Input's multiline twin with autosize), andSpinner—
10 squared cli-spinners (MIT) text-frame variants, cycling via$effect, static under
reduced motion. Topbar(DS-0080–DS-0082): link tabs ({id,label,href}→ real<a>with
aria-current;string[]still works), optional chrome (services/clockprops, ⌘K chip
only withonCommand), and a responsive scrolling tab strip.Icon(DS-0087): 7 new built-in glyphs —home,briefcase,folder,github,
linkedin,language,color-swatch.Menu(DS-0088): per-item leading visuals — snippet / swatch / emoji with documented
precedence.dssoca/tokens.css(DS-0089): tokens-only stylesheet entry;theme.cssoutput stays
byte-identical.- API additions (
DS-0078):disabledonLinkand component-wide onSegmentedControl
and per-item onBottomNav;ariaLabelonTopbarandEmptyState. Naming + disabled-state
conventions written intoDESIGN.md. - Tests (
DS-0070/DS-0071): +127 tests — parameterized sm/md/lg coverage for every
component, a size-cascade integration suite, theme-application tests, per-component axe
coverage, keyboard interaction tests; v8 coverage configured with thresholds
(lines 89 / statements 88 / functions 90 / branches 76). - Tooling — lint (
DS-0075): ESLint (flat config:eslint-plugin-svelte+
typescript-eslint+eslint-config-prettier) and Prettier (prettier-plugin-svelte) with
lint/format/format:checkscripts; rule severities tuned to the current tree as an
adoptable baseline. - Tooling — CI (
DS-0075): CI now also runs lint,format:check, svelte-check (blocking —
pnpm checkis clean), the docs suite (pnpm docs:test), a Storybook build, and collects v8
test coverage (uploaded as an artifact). - Tooling — release (
DS-0077):scripts/release.mjs(pnpm release) validates the
version bump against the last tag, checks the git-flowrelease/<x.y.z>branch, drafts a
changelog stub from conventional commits, and prints the tag/publish/back-merge steps —
publishing now documents--provenance.
Fixed
- SSR safety (
DS-0067):window/documentlisteners inTopbar/Menuare
environment-guarded;Menu's outside-click handler null-checks its elements;Accordion
ids derive from$props.id()(SSR-stable) instead ofMath.random(). - Image lightbox (
DS-0078): the focus trap now excludes disabled focusables and
tabindex="-1"elements (the backdrop no longer participates). - BottomNav badge: hardcoded
#001b04text →var(--ss-fg-on-primary)(DS-0069). - Repo-wide Prettier formatting applied; whole-tree
pnpm checkis clean (0 errors).
Changed
- Tokenized chrome (
DS-0068): BottomNav badge metrics (--ss-bottom-nav-badge-*) and
LogStream viewport/column metrics (--ss-log-min-h/max-h/t-w/lvl-w) are size-aware tokens
(md = the former px, visually unchanged); ServiceCard/Sidebar/Topbar gaps read spacing
tokens; Toaster's fly duration reads--ss-dur-fast; Sparkline's height fallback reads
--ss-icon. - Theming (
DS-0069): light--ss-primarydarkened#157f3b→#147c3afor WCAG 2.2 AA
(4.46:1 → 4.64:1); new per-theme--ss-code-overlay; explicit light selection overrides;
color-schemeset per theme (ships intokens.csstoo). - Storybook (
DS-0074): every component prop exercisable via controls across 18 stories,
intro/overview MDX page, story-level a11y error params on interactive components. - Docs (
DS-0072/DS-0073): full--ss-*token inventory documented (176 tokens),
.hs-*typography classes marked deprecated, README lists all 23 components + full type
surface, toast API got a canonical reference, dead docs links fixed. - Packaging (
DS-0077): the root export gained a"default": "./dist/index.js"condition
(aftersvelte), so non-Svelte-aware bundlers/tools can resolvedssoca;publintstays
clean.engines.node >= 24declared. - svelte-check (
DS-0076):pnpm checkis trustworthy again — the roottsconfig.json
no longer overridesmodule/moduleResolutiontoNodeNext(inheritsbundlerfrom the
generated SvelteKit config), fixing the false$libalias errors, andtest/types.d.ts
augments vitest'sAssertionwith thevitest-axematcher types (~55 false errors gone).
v0.8.2 — components overview & landing field polish
Published library: a single BottomNav default-data fix; everything else is docs-site only.
Fixed
BottomNav(DS-0065): the defaultservicesitem referenced an invalid icon name —'flex'→'database'— a type error in the shipped default items (lib + story + test).
Changed (docs site — not published)
- Components overview (
/components): equal-width cards viaminmax(0, 1fr)tracks; theTopbarpreview is pinned to the top at its real shell height (no more column blow-out / vertical stretch); a single full-width, left-aligned container (matches the Tokens page); a real photographicImagepreview capped to its 16∶9 frame. - Landing field (
DS-0064,DS-0065): independent per-tile cycling, value crossfade, staggered fade+scale entrance, full-screen radial scrim,imagedropped from the field, fully typed sample data.
Full changelog: https://github.com/httpassoca/dssoca/blob/main/CHANGELOG.md