Doop
Doop: 오픈소스 멀티플레이어 디자인 캔버스 및 AI 에이전트용 MCP
A design system built to outlive its frameworks: W3C design tokens → CSS → accessible React components.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A design system built to outlive its frameworks. By Pere Pages
(@pearpages). Tokens are the product; CSS and React
components are renderers of them.README 전문 보기 ↗A design system built to outlive its frameworks. By Pere Pages (@pearpages). Tokens are the product; CSS and React components are renderers of them.
pulp,
bitepals), light and dark through light-dark(), three tiers (primitive → semantic → component).data-* attributes.@pearpages/pulp-react/button ships the button.
Half the entries are under 1 kB brotli and the largest (Toast) is 3.1 kB, React Aria and the
modal and heatmap vendors aside; every entry has a budget CI enforces (2.1 kB for a leaf).Docs and live examples: pulp.pearpages.com
Reference consumer: perepages.com takes its colour from
@pearpages/pulp-tokens (semantic names only, both schemes) and its theme toggle from
@pearpages/pulp-react, while keeping its own reset, type scale and print edition.
| Package | |
|---|---|
@pearpages/pulp-tokens | tokens.css, tokens.json |
@pearpages/pulp-css | index.css (layers + tokens + reset + base) |
@pearpages/pulp-react | 50 components, one entry each (below) |
@pearpages/pulp-icons | stroke icons as React components, tree-shakeable |
Heading, TextAccordion, AppShell, Card, Divider, Inline, StackButton, IconButtonCalendar, Checkbox, Chip, Combobox, DatePicker, Field, Listbox, Picker, RadioGroup,
Radio, SegmentedControl, Select, Slider, Switch, TextField, TextareaLink, NavList, Pagination, TabBar, TabsDialogSystem, Dialog, Menu, Popover, Sheet, TooltipAlert, Badge, EmptyState, Progress, Skeleton, Spinner, ToastProviderAvatar, DataGrid, Heatmap, TableIcon, VisuallyHiddennpm install @pearpages/pulp-react @pearpages/pulp-tokens @pearpages/pulp-css
React 19 is a peer dependency. Then, in your stylesheet:
@import "@pearpages/pulp-css";
@import "@pearpages/pulp-react/styles.css";
With pnpm 11, a release less than 24 hours old will not install: minimumReleaseAge defaults to
1440 minutes, as a guard against a hijacked package reaching you at once. To take a release on the day
it ships, exempt the scope in pnpm-workspace.yaml:
minimumReleaseAgeExclude:
- '@pearpages/*'
npm and yarn have no such delay.
Load the brand typefaces yourself (pulp: Archivo, Instrument Sans, Geist Mono; bitepals:
Nunito, Inter; menja: Trochut, Inter), for example from @fontsource-variable/* (Trochut is
static: @fontsource/trochut). The tokens name the families
with system fallbacks but ship no font files. Shipped CSS uses native nesting and
light-dark(), not lowered; the supported browsers are the browserslist in
package.json.
The complex widgets (Combobox, Listbox, Picker, Calendar, DatePicker, Slider, DataGrid) build
on React Aria Components, installed with the package and tree-shaken per entry. Their
props are pulp's; dates cross the API as YYYY-MM-DD strings.
Dialog, DialogSystem and Sheet build on @pearpages/modals
(focus trap, inert page, stacking, Escape and backdrop dismissal), also installed with the
package. pulp themes it by mapping its tokens onto the vendor's --modal-* variables, so dialogs
follow brand and scheme. Heatmap does the same over
@pearpages/heatmap, mapping onto its
--contribution-heatmap-* variables, with the cells on the brand's sequential data scale
(--color-data-sequential-*). These are the two vendors whose stylesheets you import yourself,
into the vendor layer so pulp's styles win:
@import "@pearpages/modals/styles.css" layer(vendor);
@import "@pearpages/heatmap/styles.css" layer(vendor);
Skip the first if you never render a Dialog or Sheet, and the second if you never render a
Heatmap.
Compound components have dotted parts (Menu.Trigger), each also exported flat from the same
entry (MenuTrigger). In a React Server Component use the flat names: a client entry reaches it as
a client reference, which has no static properties.
import { Button } from '@pearpages/pulp-react/button';
<html data-brand="bitepals" data-scheme="dark">
<Button variant="secondary" size="lg">Save</Button>
</html>
pnpm install
pnpm storybook # docs and stories on :6006
pnpm test # unit tests
pnpm test:storybook # stories as browser tests (once: pnpm --filter pulp-docs exec playwright install chromium)
pnpm build && pnpm test:dist && pnpm check:package && pnpm check:size && pnpm check:floor
pnpm verify # everything CI runs, in the same order; run it before pushing to main
See PRINCIPLES.md for why the system is shaped this way, architecture.md for how the pieces
fit together, CONTRIBUTING.md to send a change, docs/decisions/ for the
decisions that applied them (the headless layer, positioning, the vendor dialog), and
CLAUDE.md for the rules CI enforces. What is pending is in tasks.md.
MIT