@dasshai/sds
v1.0.8
Published
Dassh Shared Design System — centralized UI components and tokens
Readme
@dasshai/sds
Dassh Shared Design System — centralized UI components, tokens, and themes for all Dassh AI applications.
Built on Mantine v9 and React 19. Ships three sub-packages targeting different products with a unified token layer underneath.
Packages
| Import path | Target app | Components | Approach |
|---|---|---|---|
| @dasshai/sds | Shared / generic | 13 Mantine wrappers | Token-driven Mantine theme |
| @dasshai/sds/dashboard | Dashboard (dashboard-v2) | 13 Mantine wrappers | Intent-based APIs, Onest font |
| @dasshai/sds/assessment | Assessment Portal | 16 standalone components | CSSProperties, no Mantine dep |
| @dasshai/sds/website | Marketing site | BaseButton, SectionHeader | Responsive clamp() typography |
Quick Start
Install
npm install @dasshai/sdsThe package is published to GitHub Packages:
# .npmrc
@dasshai:registry=https://npm.pkg.github.comSetup (Dashboard / Shared)
import { MantineProvider } from '@mantine/core'
import { mantineTheme } from '@dasshai/sds/dashboard'
import '@mantine/core/styles.css'
function App() {
return (
<MantineProvider theme={mantineTheme}>
<YourApp />
</MantineProvider>
)
}Setup (Assessment)
No provider needed — assessment components are standalone:
import { DSButton, DSCard, tokens } from '@dasshai/sds/assessment'
function Page() {
return (
<DSCard variant="elevated">
<DSButton variant="primary" size="md">Start Assessment</DSButton>
</DSCard>
)
}Peer Dependencies
| Package | Required | Notes |
|---|---|---|
| react / react-dom | ≥ 19 | Required |
| @mantine/core | ≥ 9 | Required for dashboard/shared |
| @mantine/dates | ≥ 9 | Optional — only if using DatePickerInput / DateTimePicker |
| @phosphor-icons/react | ≥ 2 | Optional — only if using icon props |
Components
Dashboard / Shared
Intent-based Mantine wrappers with token-driven styling:
- Button —
intentprop maps to color + variant (primary,secondary,danger,danger-outline,ghost,outline) - TextInput / PasswordInput / NumberInput / Textarea — Consistent label + input styling
- Select / MultiSelect / Autocomplete — Dropdown components with unified option styling
- Checkbox — Size-responsive label styling
- DatePickerInput / DateTimePicker — Date components (requires
@mantine/dates) - SegmentedControl — Tab-like segmented selector
- Text — Typography component with size scale (xs–xl)
Assessment
Standalone components with no Mantine dependency:
- DSButton / DSText / DSCard / DSInput — Core primitives
- DSIconBox / DSSpinner / DSBadge / DSAvatar — Display components
- DSProgressRing / DSStepper / DSTabs / DSTimeline — Progress & navigation
- DSEmptyState / DSScheduleModal / DSPagination — Composite components
- DSSidebar — Navigation sidebar
Plus pre-composed style objects (styles.card, styles.buttonPrimary, etc.) and full token exports.
Website
- BaseButton — Marketing CTA button
- SectionHeader — Responsive section headings with clamp() sizing
Design Tokens
All visual decisions flow from a single token file:
import { COLOR, FONT, SIZE } from '@dasshai/sds/dashboard'
COLOR.primary // '#1A1A1A'
COLOR.border // 'var(--border-color)'
COLOR.danger // 'var(--bright-red-500)'
FONT.family // 'Onest'
FONT.size.md // 14
FONT.weight.semibold // 600
SIZE.borderRadius // 8
SIZE.buttonHeight // 45
SIZE.inputBorderRadius // 6Pre-composed style objects are also exported for direct use:
import { INPUT_BASE_STYLES, LABEL_BASE_STYLES, DROPDOWN_BASE_STYLES } from '@dasshai/sds/dashboard'Development
Prerequisites
- Node.js 20+
- npm 10+
Build the library
npm install
npm run build # One-shot build → dist/
npm run dev # Watch mode (rebuilds on save)Output structure:
dist/
├── index.js / index.esm.js / index.d.ts
├── dashboard.js / dashboard.esm.js / dashboard.d.ts
├── assessment.js / assessment.esm.js / assessment.d.ts
└── website.js / website.esm.js / website.d.tsType checking & linting
npm run type-check # tsc --noEmit
npm run lint # eslint src/Documentation Site
A Next.js App Router site that imports directly from source for instant hot-reload.
Run locally
npm run docs:install # First time only
npm run docs # http://localhost:3000Edit any file in src/ — the docs site hot-reloads immediately. No rebuild step.
How it works
The docs app uses a tsconfig path alias (@dasshai/sds → ../src/index.ts) and Turbopack's root option to resolve source files directly. This gives you Storybook-like DX with a deployable documentation site.
Pages
The docs site covers three product contexts:
/dashboard/*— Dashboard component pages (Button, TextInput, Select, etc.)/assessment/*— Assessment component pages (Badge, Card, Stepper, Timeline, etc.)/website/*— Website component pages
Each page includes live previews, code examples, and a props table.
Adding a new component page
- Create the component in
src/ - Export it from the relevant
index.ts(e.g.src/dashboard/index.ts) - Create
docs/app/<context>/<component>/page.tsx:
'use client'
import { MyComponent } from '@dasshai/sds/dashboard'
import { Preview } from '@/components/Preview'
import { PropsTable, type PropDef } from '@/components/PropsTable'
const props: PropDef[] = [
{ name: 'variant', type: "'primary' | 'secondary'", default: "'primary'", description: '...' },
]
export default function MyComponentPage() {
return (
<div>
<h1>MyComponent</h1>
<h2>Basic Usage</h2>
<Preview
code={`<MyComponent variant="primary">Hello</MyComponent>`}
render={() => <MyComponent variant="primary">Hello</MyComponent>}
/>
<h2>Props</h2>
<PropsTable data={props} />
</div>
)
}Deploy
Set root directory to docs/ on Vercel. Every push to main auto-deploys.
Project Structure
├── src/
│ ├── index.ts # Main entry (shared components)
│ ├── dashboard/
│ │ ├── index.ts # Dashboard entry
│ │ ├── components/ # Dashboard-specific wrappers
│ │ ├── tokens/ # Dashboard tokens
│ │ └── theme/ # Dashboard Mantine theme
│ ├── assessment/
│ │ ├── index.ts # Assessment entry
│ │ ├── components/ # Standalone assessment components
│ │ ├── tokens/ # Assessment tokens
│ │ └── styles/ # Pre-composed style objects
│ ├── website/
│ │ ├── index.ts # Website entry
│ │ ├── components/ # Marketing components
│ │ └── theme/ # Website Mantine theme
│ ├── components/ # Shared component source (Button/, TextInput/, etc.)
│ ├── tokens/tokens.ts # Core design tokens
│ ├── theme/mantineTheme.ts # Shared Mantine theme config
│ └── utils/ # Utilities (pxToRem, etc.)
├── docs/ # Next.js documentation site
│ ├── app/ # App Router pages
│ ├── components/ # Doc-specific components (Preview, PropsTable, Sidebar)
│ └── next.config.ts # Turbopack + webpack config
├── dist/ # Built output (CJS + ESM + types)
├── scripts/
│ └── link-docs-deps.mjs # Post-install symlink script
├── .storybook/ # Storybook config (alternative dev tool)
├── rollup.config.mjs # Build configuration
├── tsconfig.json # TypeScript config
└── package.jsonScripts Reference
| Command | Description |
|---|---|
| npm run build | Build all entry points to dist/ |
| npm run dev | Watch mode — rebuild on source changes |
| npm run type-check | Run TypeScript type checking |
| npm run lint | Lint source files |
| npm run clean | Remove dist/ |
| npm run docs | Start docs dev server (http://localhost:3000) |
| npm run docs:build | Production build of docs site |
| npm run docs:install | Install docs dependencies |
Publishing
To npm
# 1. Authenticate (one-time)
npm login --scope=@dasshai
# 2. Bump version
npm version patch # or minor / major
# 3. Build & publish
npm run clean
npm run build
npm publishConsuming projects need this in their .npmrc:
@dasshai:registry=https://registry.npmjs.org/Version bumping
npm version patch # 1.0.0 → 1.0.1 (bug fixes)
npm version minor # 1.0.0 → 1.1.0 (new components, non-breaking)
npm version major # 1.0.0 → 2.0.0 (breaking changes)This creates a git commit + tag automatically. Push both:
git push && git push --tagsUsing in Other Projects
From GitHub Packages (production)
npm install @dasshai/sds@latestLocal development with npm link
# In this repo
npm link
# In your consuming project
npm link @dasshai/sdsNote: with npm link you need to run npm run build after source changes. The docs site doesn't have this limitation since it imports source directly.
Architecture Decisions
- Mantine wrappers, not forks — Dashboard components wrap Mantine with opinionated defaults via
createTheme(). This keeps us on the Mantine upgrade path while enforcing consistency. - Assessment is standalone — The assessment portal has no Mantine dependency. Components use plain React + CSSProperties for maximum portability and bundle size control.
- Token-first — All magic numbers live in
tokens.ts. Components reference tokens, not raw values. - Intent-based Button API — Instead of
color="red" variant="filled", useintent="danger". Semantic naming reduces decision fatigue. - Docs as source of truth — The documentation site imports from source, so it's always accurate. If the docs show it working, it works.
License
UNLICENSED — proprietary to Dassh AI.
