{
"path": "/projects/ui",
"site": "at://did:plc:ofrbh253gwicbkc5nktqepol/site.standard.publication/3mfyq5mpohw25",
"tags": [
"pkgs",
"website"
],
"$type": "site.standard.document",
"title": "@ewanc26/ui",
"description": "Svelte UI component library extracted from ewancroft.uk — pluggable layout, card, SEO, and UI primitive components alongside Svelte stores and a multi-theme config system.",
"publishedAt": "2026-03-06T00:00:00.000Z",
"textContent": "@ewanc26/ui is the Svelte component library extracted from ewancroft.uk. It provides layout components, a rich set of card types, UI primitives, SEO tags, Svelte stores, badge helpers, and a central multi-theme configuration — all built for SvelteKit 2 + Svelte 5 + Tailwind CSS 4.\n\nPart of the @ewanc26/pkgs monorepo.\n\nInstallation\n\nRequires svelte >= 5, @sveltejs/kit >= 2, and tailwindcss >= 4 as peer dependencies. @ewanc26/atproto is an optional peer dependency needed for the AT Protocol card components.\n\nComponents\n\nLayout Toggles\n\nLayout: Main\n\nCards\n\nThe AT Protocol card components accept typed props from @ewanc26/atproto:\n\nFeedCard\n\nFeedCard is a generic, protocol-agnostic feed list card. Pass any array of FeedItem objects and it renders a titled list with avatar/icon slots, optional descriptions, relative timestamps, optional badges, and clickable rows — all using the same hover-state pattern as the rest of the card family.\n\nThe FeedItem interface:\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| id | string | No | Unique key for Svelte's keyed {#each}. Falls back to title + index. |\n| title | string | Yes | Primary row label. |\n| description | string | No | Secondary copy, clamped to two lines. |\n| href | string | No | When present, the row renders as an <a>. |\n| avatarUrl | string | No | Image URL shown in the leading avatar slot. |\n| iconFallback | string | No | Emoji or initials shown when avatarUrl is absent. |\n| timestamp | string | No | ISO-8601 string rendered as a relative time label. |\n| badge | string | No | Short label shown as a trailing badge. |\n\nProps on FeedCard:\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| items | FeedItem[] \\| null | null | null triggers the loading skeleton. |\n| title | string | 'Feed' | Section heading inside the card. |\n| emptyMessage | string | 'Nothing here yet.' | Copy shown when items is an empty array. |\n\nUI Primitives\n\n- Card — base card wrapper\n- InternalCard — card variant for internal links and interactive rows\n- DocumentCard — Standard.site document preview\n- BlogPostCard — blog post listing item with badges\n- Dropdown — accessible dropdown menu\n- Pagination — numbered page navigation\n- SearchBar — text search input\n- Tabs — tab bar with active state\n- PostsGroupedView — posts grouped by year/month with tag filtering\n\nSEO\n\nStores\n\n| Store | Type | Description |\n|-------|------|-------------|\n| wolfMode | Writable<boolean> | Activates wolf mode text transformation |\n| colorTheme | Writable<ColorTheme> | Active colour theme value |\n| colorThemeDropdownOpen | Writable<boolean> | Controls theme picker dropdown visibility |\n| happyMacStore | Writable<boolean> | Happy Mac easter egg state |\n\nTheme Configuration\n\n12 named themes across four categories, using OKLCH colour values:\n\nCategories: neutral (Sage, Monochrome, Slate), warm (Ruby, Coral, Sunset, Amber), cool (Forest, Teal, Ocean), vibrant (Lavender, Rose).\n\nHelpers\n\nPost Badges\n\nPost Utilities\n\nTypes\n\nTech Stack\n\nSvelte 5, SvelteKit 2, Tailwind CSS 4, TypeScript 5.9+, @lucide/svelte. Built with svelte-package.\n\nLicence\n\nAGPL-3.0-only — see the pkgs monorepo.",
"canonicalUrl": "https://docs.ewancroft.uk/projects/ui"
}