OSS-first docs
These docs teach the open system first: contracts, generated surfaces, runtimes, governance, and incremental adoption. Studio shows up as the operating layer on top, not as the source of truth.
@lssm-tech/lib.design-system
High-level design system components, patterns, and layouts for LSSM applications. Built on top of @lssm-tech/lib.ui-kit.
Installation
bun add @lssm-tech/lib.design-systemWhat It Provides
- Composite Components: Molecules and Organisms that solve common UI problems
- Layouts: Ready-to-use page structures for dashboards, marketing sites, and lists
- Data Views: Standardized renderers for lists, tables, and detail views
- Forms: Zod-integrated form layouts and components
- Code Display: Syntax-highlighted code blocks with package manager tabs
- Platform Utilities: Hooks for responsive and adaptive design
- Object References: Clickable references for addresses, phone numbers, users, customers, files, URLs, and custom objects
- Adaptive Panels: One panel API that resolves to a desktop sheet or mobile drawer
- Theme Bridge: ThemeSpec to Tailwind variables, presets, CSS text, and runtime light/dark mode
- Legal Templates: Compliant templates for Terms, Privacy, and GDPR
ThemeSpec to Tailwind
The theme bridge keeps ThemeSpec as the source of truth and exposes no-generation Tailwind helpers, optional CSS text serialization, runtime CSS variables, light/dark modes, and OKLCH color pass-through.
import {
DesignSystemThemeProvider,
resolveThemeModeTokens,
themeSpecToCssVariables,
themeSpecToTailwindCss,
themeSpecToTailwindPreset,
} from '@lssm-tech/lib.design-system';
const tokens = resolveThemeModeTokens(themeSpec, 'light', {
targets: ['tenant:acme'],
});
export default themeSpecToTailwindPreset(tokens);
const css = themeSpecToTailwindCss(
themeSpecToCssVariables(themeSpec, { targets: ['tenant:acme'] }),
{ includeCustomVariant: true }
);
export function TenantSurface({ children }: { children: React.ReactNode }) {
return (
<DesignSystemThemeProvider
theme={themeSpec}
targets={['tenant:acme']}
mode="dark"
applyCssVariables
>
{children}
</DesignSystemThemeProvider>
);
}Focused import surfaces
New code can use focused subpaths for theme, controls, forms, and layout while existing root imports remain compatible.
import { themeSpecToTailwindPreset } from '@lssm-tech/lib.design-system/theme';
import { Select } from '@lssm-tech/lib.design-system/controls';
import { FormDialog } from '@lssm-tech/lib.design-system/forms';
import { HStack } from '@lssm-tech/lib.design-system/layout';
import { AdaptivePanel } from '@lssm-tech/lib.design-system/components/overlays';
import { RichRef } from '@lssm-tech/lib.ui-kit-web/rich-ref';
import { ObjectPreview, ObjectPanel } from '@lssm-tech/lib.design-system/rich-reference/layouts/object';
// Root imports remain supported:
import { Button, DataTable } from '@lssm-tech/lib.design-system';Actionable object references
Use RichRef whenever a product surface renders an object that may need quick interaction: addresses, phone numbers, emails, users, customers, files, URLs, code symbols, and tenant-specific objects. The shared ReferenceDispatcher resolves payloads through the four governance ports (subject, preferences, kind-policy, audit), enforces post-handler redaction, and routes to the matching per-kind layout.
Descriptor model
- References use data-only descriptors:
id,kind,label,value,href,openTarget,metadata,iconKey, andariaLabel. - Rich references use nested
propertiesandsections, so one user or customer can expose email, phone, address, files, and links inside the same panel. - Reference kinds are
address,email,phone,user,customer,file,url, andcustom.
Runtime behavior
- Choose visibility with
interactivityVisibility:none,underline, oricon. - Detail navigation defaults to
same-page; setopenTarget="new-page"on the handler, reference, or action when a new page is required. - Host apps provide behavior through
copyHandler,openHref,actionHandlers,onAction, andonActionError.
Default actions
createDefaultObjectReferenceActionsadds copy, open, email, phone, and map actions when the descriptor supports them.createMapsReferenceActionscreates Google Maps, Apple Maps, Waze, or geo actions for address references.Safe href handling allows expected app, web, email, phone, and map URLs while rejecting unsafe schemes.
Extension points
- Use
renderTrigger,renderDetail,renderAction,renderProperty,renderSection, andiconRendererto wrap or overload presentation. Keep tenant-specific permissions, analytics, and integration side effects at the host boundary through runtime handlers.
import { RichRef } from '@lssm-tech/lib.ui-kit-web/rich-ref';
// References resolve through the shared ReferenceDispatcher wired in
// @lssm-tech/integration.runtime/rich-reference. The runtime enforces
// post-handler redaction and applies coarse + fine personalization.
<RichRef
kindId="object"
refId="user.amina"
variant="inline"
panelMode="popover"
/>;
// Custom per-kind layouts are registered at app boot:
import { registerRichReferenceLayouts } from '@lssm-tech/lib.design-system';
import { CustomerPreview, CustomerPanel } from '@/app/customers/rich-ref-layout';
registerRichReferenceLayouts('customer', {
Preview: CustomerPreview,
Panel: CustomerPanel,
});Adaptive panels
AdaptivePanel is the shared overlay decision for surfaces that should feel native on both desktop and small screens. Its default responsive mode renders a sheet at the configured desktop breakpoint and a drawer below it. RichRef uses the same interaction decision through its panelMode prop while host-owned detail and edit panels can call AdaptivePanel directly.
import { AdaptivePanel } from '@lssm-tech/lib.design-system/components/overlays';
<AdaptivePanel
open={open}
onOpenChange={setOpen}
trigger={<button type="button">Edit</button>}
title="Edit customer"
description="Update contact and site details."
mode="responsive"
mobileMode="drawer"
desktopMode="sheet"
breakpoint="md"
sheetSide="right"
drawerDirection="bottom"
>
{content}
</AdaptivePanel>;Prompt for adoption work
Use this prompt when asking an agent or downstream OSS consumer to replace inert references across an application.
Find every user-facing address, phone number, email, user, customer, file, URL, and tenant-specific reference currently rendered as inert text.
Replace each one with <RichRef> from @lssm-tech/lib.ui-kit-web/rich-ref. Pass stable kindId and refId props; the shared ReferenceDispatcher (wired in @lssm-tech/integration.runtime/rich-reference) resolves payloads, enforces post-handler redaction, and applies coarse + fine personalization.
Use one of the six built-in kinds when applicable: database-record, object, link, file, media, code-symbol. For domain-specific kinds (e.g. customer), define a per-kind layout (Preview + Panel) and register it via registerRichReferenceLayouts(kindId, { Preview, Panel }).
Use panelMode="popover" for compact previews, "drawer" for mobile-first detail, "modal" for blocking review, "route" for navigable detail, or "inline-expand" for in-place expansion. Do not call low-level overlay primitives directly for this interaction unless a lower-level primitive is being implemented.
Use panelMode="popover" for compact previews, "drawer" for mobile-first detail, "modal" for blocking review, "route" for navigable detail, or "inline-expand" for in-place expansion. Tenant-specific permissions and per-instance authz belong in the KindPolicyProvider implementation (typically @lssm-tech/lib.surface-runtime/rich-reference/rolemorph), not in the renderer.
After replacing references, verify keyboard access, visible affordance choice (none, underline, or icon), safe href behavior, mobile drawer layout, and desktop sheet layout. Verify denied references render as redaction placeholders with HMAC-signed DenialToken wire forms.Entity surfaces
The current OSS path for entity listing, detail, and editing is contract-driven composition: DataViewRenderer for collections, AdaptivePanel for responsive detail/edit panels, RichRef for reference fields, and host-owned RoleMorph/personalization adapters. Follow the entity surfaces guide before migrating bespoke panels.
Data table example
This is the composed lane from the canonical Data Grid Showcase. The design-system wrapper owns title, description, header actions, and the opinionated card shell on top of the raw web primitive.
import { Button, DataTable } from '@lssm-tech/lib.design-system';
import { useContractTable } from '@lssm-tech/lib.presentation-runtime-react';
import { SHOWCASE_ROWS } from '@lssm-tech/example.data-grid-showcase/ui/data-grid-showcase.data';
import { useShowcaseColumns } from '@lssm-tech/example.data-grid-showcase/ui/data-grid-showcase.columns';
import {
ExpandedRowContent,
ShowcaseToolbar,
} from '@lssm-tech/example.data-grid-showcase/ui/data-grid-showcase.parts';
export function AccountHealthTable() {
const columns = useShowcaseColumns();
const controller = useContractTable({
data: SHOWCASE_ROWS,
columns,
selectionMode: 'multiple',
initialState: {
sorting: [{ id: 'arr', desc: true }],
pagination: { pageIndex: 0, pageSize: 4 },
columnVisibility: { notes: false },
columnPinning: { left: ['account'], right: [] },
},
renderExpandedContent: (row) => <ExpandedRowContent row={row} />,
getCanExpand: () => true,
});
return (
<DataTable
controller={controller}
title="Account health"
description="Composed table surface for the canonical account grid."
headerActions={<Button variant="outline">Reset</Button>}
toolbar={
<ShowcaseToolbar
controller={controller}
label="Client mode"
primaryColumnId="account"
toggleColumnId="notes"
pinColumnId="owner"
sortColumnIds={['arr', 'renewalDate']}
/>
}
loading={false}
emptyState={<div>No rows available.</div>}
footer={`Page ${controller.pageIndex + 1} of ${controller.pageCount}`}
/>
);
}Key Exports
Organisms
AppShell, PageOutline
AppLayout, AppHeader, AppSidebar
MarketingLayout, HeroSection
ListCardPage, ListTablePage
Data & Forms
DataTable
DataViewTable
DataViewRenderer
ZodForm
FormLayout, FormDialog
Code Display
RichRef (kindId="code-symbol", with variant="inline" or "card")
CommandTabs (package manager tabs)
InstallCommand (convenience wrapper)
CopyButton
Providers
PackageManagerProvider
References & Overlays
RichRef (canonical reference orchestrator)
registerRichReferenceLayouts (custom per-kind layouts)
rich-reference/layouts/{kind} (Preview, Panel)
AdaptivePanel
Where this layer fits
Read Application shell for the shared sidebar, topbar, command search, mobile navigation, and PageOutline pattern. Read Cross-platform UI for the package split between shared runtime controllers, leaf platform primitives, and this composed design-system layer.
Translation runtime
Use ContractSpec TranslationSpec catalogs as the canonical i18n layer, then resolve, format, snapshot, and optionally project messages to i18next.
Architecture
See how the spec layer, runtimes, integrations, and multi-surface outputs fit together.
Why ContractSpec
Keep educational and comparison content reachable without letting it define the primary OSS learning path.