@dybo-ai/design 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +57 -0
- package/README.md +346 -0
- package/assets/logo-dybo-01-dark.png +0 -0
- package/assets/logo-dybo-01.jpeg +0 -0
- package/assets/logo-dybo-01.png +0 -0
- package/dist/index.cjs +515 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +161 -0
- package/dist/index.d.ts +161 -0
- package/dist/index.js +497 -0
- package/dist/index.js.map +1 -0
- package/package.json +80 -0
- package/theme.css +730 -0
- package/tokens.cjs +31 -0
- package/tokens.json +132 -0
- package/tokens.mjs +40 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What this repo is
|
|
6
|
+
|
|
7
|
+
`@dybo-ai/design` — the DYBO design system packaged as an installable npm module (private, published to GitHub Packages). It ships design tokens, a Tailwind preset, plain CSS + helper classes, and a handful of React components. There is no build step, bundler, test suite, or linter configured — every file in the package is hand-authored and published as-is (see `files` in `package.json`).
|
|
8
|
+
|
|
9
|
+
This `CLAUDE.md` is itself shipped to consumers (it's in `package.json`'s `files` list) and is meant to be copied into a consuming app's own `CLAUDE.md` — see "Design system rules for consuming apps" below. Keep that section self-contained and consumer-facing; put repo-maintenance notes in the sections after it instead of mixing them in.
|
|
10
|
+
|
|
11
|
+
## Architecture: one source of truth, four hand-synced mirrors
|
|
12
|
+
|
|
13
|
+
`tokens.json` is canonical (values + original Figma variable names). Every other token surface is a **manually maintained mirror** of it — there is no code generation:
|
|
14
|
+
|
|
15
|
+
| File | Mirrors tokens.json as... |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `tokens.mjs` | ESM flat exports (`color`, `space`, `radius`, etc.) |
|
|
18
|
+
| `tokens.cjs` | CommonJS mirror of `tokens.mjs` |
|
|
19
|
+
| `theme.css` | CSS custom properties + `.dybo-*` helper classes (`.dybo-glass`, `.dybo-btn`, `.dybo-input`, `.dybo-badge`) |
|
|
20
|
+
| `tailwind-preset.cjs` | Tailwind theme extension (`dybo-*` utilities) |
|
|
21
|
+
| `react/index.jsx` | Thin React wrappers (`Button`, `Card`, `Input`, `Badge`) over the `theme.css` classes — requires the consumer to import `theme.css` separately |
|
|
22
|
+
|
|
23
|
+
**When changing a token value or adding a new one, update all five in the same change.** There's no automated check that catches drift between them (a Style Dictionary generation pipeline is proposed but not implemented — see `docs/SETUP.md` Part E).
|
|
24
|
+
|
|
25
|
+
`assets/` holds static brand image files (currently the logo) — it's shipped via `package.json`'s `files` list and importable as `@dybo-ai/design/assets/<file>`, but it's not part of the token-mirror sync described above.
|
|
26
|
+
|
|
27
|
+
`docs/design-system.md` is the narrative reference extracted from Figma (file `ZHtkvTEeTYlNVbSncLyI1a`) — it's the rationale/source document behind `tokens.json`, including a documented naming quirk (Figma's "Feedback Colors/Error" is actually orange; the real red danger color is `Brand/Danger/700` / `#a21a17`).
|
|
28
|
+
|
|
29
|
+
## Commands
|
|
30
|
+
|
|
31
|
+
There is no build, lint, or test tooling in this repo — don't invent npm scripts that don't exist (`package.json` has no `scripts` field).
|
|
32
|
+
|
|
33
|
+
Publishing (manual, no CI):
|
|
34
|
+
```bash
|
|
35
|
+
npm version patch # or minor / major — see docs/SETUP.md Part D for the semver rule
|
|
36
|
+
npm publish
|
|
37
|
+
git push --follow-tags
|
|
38
|
+
```
|
|
39
|
+
`npm publish --dry-run` is useful to confirm the packed file list matches `package.json`'s `files` array before actually publishing. Publishing requires a `.npmrc` (git-ignored, copy from `.npmrc.example`) with a `GITHUB_TOKEN` that has `write:packages`.
|
|
40
|
+
|
|
41
|
+
## Design system rules for consuming apps
|
|
42
|
+
|
|
43
|
+
When building UI in a DYBO app, use `@dybo-ai/design`. Do not hard-code hex values or ad-hoc spacing — reference tokens.
|
|
44
|
+
|
|
45
|
+
- **Font:** Urbanist (400/500/600/700). Titles use weight 400 with 1px letter-spacing; body uses weight 500.
|
|
46
|
+
- **Style:** glassmorphism — translucent cards `rgba(240,241,244,0.70)`, 1px white stroke, 20px radius, soft blue-gray shadow, 4px backdrop blur, on a `#e6eaf0` page.
|
|
47
|
+
- **Key colors:** primary/ink `#0a1323`, blue accent `#5878a7`, logo navy `#1d335c`. Semantic: success `#20a156`, warning `#f16c24`, danger `#a21a17`.
|
|
48
|
+
- **Spacing:** 4px scale — 4/8/12/16/20/32.
|
|
49
|
+
- **Radius:** 12 (buttons/inputs), 20 (cards), 999 (pills).
|
|
50
|
+
|
|
51
|
+
How to consume (pick per app):
|
|
52
|
+
- Tailwind app → `presets: [require("@dybo-ai/design/tailwind")]`, use `dybo-*` utilities.
|
|
53
|
+
- Non-Tailwind → `import "@dybo-ai/design/theme.css"` and use `.dybo-glass`, `.dybo-btn`, `.dybo-input`, `.dybo-badge`.
|
|
54
|
+
- React → `import { Button, Card, Input, Badge } from "@dybo-ai/design/react"` (also import the CSS).
|
|
55
|
+
- Programmatic values → `import { color, space, radius } from "@dybo-ai/design"`.
|
|
56
|
+
|
|
57
|
+
Reference `tokens.json` for the full token list and `docs/design-system.md` for rationale. Semantic "danger" is red `#a21a17` — ignore Figma's mislabeled orange "Feedback/Error".
|
package/README.md
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# @dybo-ai/design
|
|
2
|
+
|
|
3
|
+
DYBO design system — tokens, CSS theme, Tailwind V4 support, and React components with TypeScript.
|
|
4
|
+
Style: **glassmorphism** · Font: **Urbanist** · Published on [npmjs.com](https://www.npmjs.com).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @dybo-ai/design
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Load the Urbanist font once in your HTML (or via `@fontsource/urbanist`):
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<link
|
|
18
|
+
href="https://fonts.googleapis.com/css2?family=Urbanist:wght@400;500;600;700&display=swap"
|
|
19
|
+
rel="stylesheet"
|
|
20
|
+
/>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Tailwind V4
|
|
26
|
+
|
|
27
|
+
Add one line to your app's main CSS file:
|
|
28
|
+
|
|
29
|
+
```css
|
|
30
|
+
/* app.css */
|
|
31
|
+
@import "tailwindcss";
|
|
32
|
+
@import "@dybo-ai/design/theme.css";
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This automatically registers all DYBO utilities via `@theme`:
|
|
36
|
+
|
|
37
|
+
| Utility | Example |
|
|
38
|
+
| ---------------- | ----------------------------------------------------------------------- |
|
|
39
|
+
| `bg-dybo-*` | `bg-dybo-blue`, `bg-dybo-page`, `bg-dybo-danger` |
|
|
40
|
+
| `text-dybo-*` | `text-dybo-ink`, `text-dybo-muted`, `text-dybo-on-dark` |
|
|
41
|
+
| `border-dybo-*` | `border-dybo-line` |
|
|
42
|
+
| `rounded-dybo-*` | `rounded-dybo-sm` (12px), `rounded-dybo-md` (20px), `rounded-dybo-full` |
|
|
43
|
+
| `shadow-dybo-*` | `shadow-dybo-card`, `shadow-dybo-drop` |
|
|
44
|
+
| `blur-dybo` | 4px backdrop blur |
|
|
45
|
+
|
|
46
|
+
**No Tailwind?** Import only the CSS — all variables and `.dybo-*` classes work in any framework:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
import "@dybo-ai/design/theme.css";
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## React Components
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import "@dybo-ai/design/theme.css";
|
|
58
|
+
import { Button, Card, Input, Badge } from "@dybo-ai/design/react";
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
All components are TypeScript with `I`-prefixed interfaces.
|
|
62
|
+
|
|
63
|
+
### Available components
|
|
64
|
+
|
|
65
|
+
| Category | Components |
|
|
66
|
+
| -------------- | ---------------------------------------------------- |
|
|
67
|
+
| **Base** | `Button`, `Card`, `Input`, `Badge` |
|
|
68
|
+
| **Layout** | `AppShell`, `Sidebar`, `TopBar` |
|
|
69
|
+
| **Navigation** | `NavItem`, `NavSection` |
|
|
70
|
+
| **Data** | `DataTable`, `Tabs`, `OverviewGrid`, `OverviewField` |
|
|
71
|
+
| **Form** | `Select` |
|
|
72
|
+
| **Feedback** | `Alert` |
|
|
73
|
+
| **Overlay** | `Modal` |
|
|
74
|
+
| **Auth** | `LoginCard` |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Examples
|
|
79
|
+
|
|
80
|
+
### Full app shell
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
import "@dybo-ai/design/theme.css";
|
|
84
|
+
import {
|
|
85
|
+
AppShell,
|
|
86
|
+
Sidebar,
|
|
87
|
+
TopBar,
|
|
88
|
+
NavItem,
|
|
89
|
+
NavSection,
|
|
90
|
+
} from "@dybo-ai/design/react";
|
|
91
|
+
|
|
92
|
+
function MyApp() {
|
|
93
|
+
return (
|
|
94
|
+
<AppShell
|
|
95
|
+
sidebar={
|
|
96
|
+
<Sidebar
|
|
97
|
+
brand={<img src="/logo.png" alt="DYBO" height={36} />}
|
|
98
|
+
user={{ name: "Jane Smith", email: "jane@dybo.ai" }}
|
|
99
|
+
onLogout={() => logout()}
|
|
100
|
+
>
|
|
101
|
+
<NavSection label="Dashboard" />
|
|
102
|
+
<NavItem label="Overview" href="/" active />
|
|
103
|
+
<NavItem label="Projects" href="/projects" />
|
|
104
|
+
<NavSection label="Settings" />
|
|
105
|
+
<NavItem label="Parameters" href="/settings" />
|
|
106
|
+
</Sidebar>
|
|
107
|
+
}
|
|
108
|
+
topBar={<TopBar title="Tax Calculator 2026" />}
|
|
109
|
+
>
|
|
110
|
+
{/* page content */}
|
|
111
|
+
</AppShell>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Glassmorphism card
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
import { Card, Button, Input } from "@dybo-ai/design/react";
|
|
120
|
+
|
|
121
|
+
<Card>
|
|
122
|
+
<Input label="Name" placeholder="Enter your name" />
|
|
123
|
+
<Button variant="primary" style={{ marginTop: 16 }}>
|
|
124
|
+
Save
|
|
125
|
+
</Button>
|
|
126
|
+
</Card>;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### DataTable
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import { DataTable } from "@dybo-ai/design/react";
|
|
133
|
+
import type { IColumn } from "@dybo-ai/design/react";
|
|
134
|
+
|
|
135
|
+
interface IUser {
|
|
136
|
+
id: number;
|
|
137
|
+
name: string;
|
|
138
|
+
email: string;
|
|
139
|
+
status: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const columns: IColumn<IUser>[] = [
|
|
143
|
+
{ key: "name", label: "Name", align: "left" },
|
|
144
|
+
{ key: "email", label: "Email", align: "left" },
|
|
145
|
+
{
|
|
146
|
+
key: "status",
|
|
147
|
+
label: "Status",
|
|
148
|
+
format: (v) => <Badge status="success">{String(v)}</Badge>,
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
|
|
152
|
+
<DataTable
|
|
153
|
+
columns={columns}
|
|
154
|
+
rows={users}
|
|
155
|
+
rowKey="id"
|
|
156
|
+
onRowClick={(user) => navigate(`/users/${user.id}`)}
|
|
157
|
+
/>;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Tabs
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { useState } from "react";
|
|
164
|
+
import { Tabs } from "@dybo-ai/design/react";
|
|
165
|
+
|
|
166
|
+
const TABS = [
|
|
167
|
+
{ key: "federal", label: "Federal (IRS)" },
|
|
168
|
+
{ key: "state", label: "State" },
|
|
169
|
+
{ key: "annual", label: "Annual Inputs" },
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
function ProjectDetail() {
|
|
173
|
+
const [tab, setTab] = useState("federal");
|
|
174
|
+
return (
|
|
175
|
+
<>
|
|
176
|
+
<Tabs tabs={TABS} active={tab} onChange={setTab} />
|
|
177
|
+
{tab === "federal" && <FederalView />}
|
|
178
|
+
{tab === "state" && <StateView />}
|
|
179
|
+
{tab === "annual" && <AnnualInputs />}
|
|
180
|
+
</>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Overview grid
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
import { OverviewGrid } from "@dybo-ai/design/react";
|
|
189
|
+
|
|
190
|
+
<OverviewGrid
|
|
191
|
+
fields={[
|
|
192
|
+
{ label: "Entity", value: "Jestor Holdings Inc" },
|
|
193
|
+
{ label: "State", value: "DE" },
|
|
194
|
+
{ label: "Federal Tax", value: "$1,432.00" },
|
|
195
|
+
{ label: "State Tax", value: "$312.00" },
|
|
196
|
+
]}
|
|
197
|
+
/>;
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Alert
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
import { Alert } from "@dybo-ai/design/react";
|
|
204
|
+
|
|
205
|
+
<Alert variant="danger" onClose={() => setError(null)}>
|
|
206
|
+
Failed to save. Please check the data and try again.
|
|
207
|
+
</Alert>;
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Modal
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
import { useState } from "react";
|
|
214
|
+
import { Modal, Button } from "@dybo-ai/design/react";
|
|
215
|
+
|
|
216
|
+
function ConfirmDelete() {
|
|
217
|
+
const [open, setOpen] = useState(false);
|
|
218
|
+
return (
|
|
219
|
+
<>
|
|
220
|
+
<Button variant="danger" onClick={() => setOpen(true)}>
|
|
221
|
+
Delete
|
|
222
|
+
</Button>
|
|
223
|
+
<Modal
|
|
224
|
+
open={open}
|
|
225
|
+
onClose={() => setOpen(false)}
|
|
226
|
+
title="Confirm deletion"
|
|
227
|
+
footer={
|
|
228
|
+
<>
|
|
229
|
+
<Button variant="ghost" onClick={() => setOpen(false)}>
|
|
230
|
+
Cancel
|
|
231
|
+
</Button>
|
|
232
|
+
<Button variant="danger" onClick={handleDelete}>
|
|
233
|
+
Delete
|
|
234
|
+
</Button>
|
|
235
|
+
</>
|
|
236
|
+
}
|
|
237
|
+
>
|
|
238
|
+
<p>This action cannot be undone. Do you want to continue?</p>
|
|
239
|
+
</Modal>
|
|
240
|
+
</>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Login card
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
import { LoginCard, Input, Button } from "@dybo-ai/design/react";
|
|
249
|
+
|
|
250
|
+
<LoginCard
|
|
251
|
+
logo={<img src="/logo.png" alt="DYBO" height={44} />}
|
|
252
|
+
subtitle="Sign in to your account"
|
|
253
|
+
>
|
|
254
|
+
<form onSubmit={handleSubmit}>
|
|
255
|
+
<Input label="Email" type="email" name="email" />
|
|
256
|
+
<Input
|
|
257
|
+
label="Password"
|
|
258
|
+
type="password"
|
|
259
|
+
name="password"
|
|
260
|
+
style={{ marginTop: 14 }}
|
|
261
|
+
/>
|
|
262
|
+
<Button
|
|
263
|
+
variant="primary"
|
|
264
|
+
type="submit"
|
|
265
|
+
style={{ width: "100%", marginTop: 20 }}
|
|
266
|
+
>
|
|
267
|
+
Sign in
|
|
268
|
+
</Button>
|
|
269
|
+
</form>
|
|
270
|
+
</LoginCard>;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Select
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
import { Select } from "@dybo-ai/design/react";
|
|
277
|
+
|
|
278
|
+
<Select
|
|
279
|
+
label="State"
|
|
280
|
+
placeholder="Select…"
|
|
281
|
+
options={[
|
|
282
|
+
{ value: "CA", label: "California" },
|
|
283
|
+
{ value: "DE", label: "Delaware" },
|
|
284
|
+
{ value: "NY", label: "New York" },
|
|
285
|
+
]}
|
|
286
|
+
onChange={(e) => setState(e.target.value)}
|
|
287
|
+
/>;
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Tokens in JS/TS
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
import { color, space, radius } from "@dybo-ai/design";
|
|
296
|
+
|
|
297
|
+
color.brand.blue; // "#5878a7"
|
|
298
|
+
color.semantic.danger.solid; // "#a21a17"
|
|
299
|
+
space["200"].value; // 16
|
|
300
|
+
radius.medium.value; // 20
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Assets
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
import logo from "@dybo-ai/design/assets/logo-dybo-01.jpeg"; // opaque JPEG
|
|
309
|
+
import logoLight from "@dybo-ai/design/assets/logo-dybo-01.png"; // PNG transparent background, navy ink (light surfaces)
|
|
310
|
+
import logoDark from "@dybo-ai/design/assets/logo-dybo-01-dark.png"; // PNG transparent background, light ink (dark surfaces)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Customization via CSS variables
|
|
316
|
+
|
|
317
|
+
All tokens are CSS custom properties. To override selectively:
|
|
318
|
+
|
|
319
|
+
```css
|
|
320
|
+
/* Override in a specific component */
|
|
321
|
+
.my-sidebar {
|
|
322
|
+
--dybo-sidebar-bg: #0a1323;
|
|
323
|
+
--dybo-sidebar-width: 260px;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/* Global override */
|
|
327
|
+
:root {
|
|
328
|
+
--dybo-color-brand-blue-yonder: #4a6fa0; /* your blue shade */
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Publishing guide
|
|
335
|
+
|
|
336
|
+
For maintainers (how to publish a new version): see [`docs/PUBLISHING.md`](./docs/PUBLISHING.md).
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Token reference
|
|
341
|
+
|
|
342
|
+
`tokens.json` contains all values with the original Figma names.
|
|
343
|
+
`docs/design-system.md` contains the design rationale extracted from Figma.
|
|
344
|
+
|
|
345
|
+
> **Semantic note**: The system's "danger" is red `#a21a17` (`Brand/Danger/700`).
|
|
346
|
+
> Figma has a color called "Feedback Colors/Error" that is orange — that's `warning`, not `danger`.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|