Imports tradein-mvp/frontend (38 components) to a claude.ai/design design-system project. Synth-entry build (Next.js app, no dist): - overrides/source-kit.mjs: process.env shim for browser IIFE - preview-provider.tsx: seeded TanStack Query provider (mirrors the repo's offline ui-preview client) so fetch-coupled + auth-gated cards render - previews/*.tsx: authored preview compositions (real fixture data) - conventions.md: README header for the design agent - config.json + NOTES.md: reproducible re-sync inputs
3.3 KiB
Trade-In UI — how to build with this design system
React components from the GenDesign trade-in product (real-estate trade-in valuation, RU/ЕКБ). Import everything from tradein-mvp-frontend (bound at window.TradeInUI). The cards are domain-specific and prop-driven — you compose them with data, you don't restyle their internals.
Setup & wrapping (required for data components)
Most cards take their data as props and render standalone. But several read app state through TanStack Query hooks (UserMenu, Topbar, RouteGuard → useMe; HouseAnalyticsSection, PlacementHistoryCard, StreetDealsCard → estimate sub-queries). Those MUST be rendered inside a QueryClientProvider (the app ships one as Providers). Without it they throw "No QueryClient set"; with an empty client they render their loading/null state. Prop-only cards (HeroSummary, OfferCard, PriceRangeBar, DealsCard, ListingsCard, charts…) need no provider.
import { Providers, HeroSummary, OfferCard } from "tradein-mvp-frontend";
<Providers>
<main className="page" style={{ display: "flex", flexDirection: "column", gap: 24 }}>
<HeroSummary estimate={estimate} input={input} onResubmit={fn} />
<OfferCard estimate={estimate} brandSlug={null} />
</main>
</Providers>
Load styles.css once at the root — it pulls the component CSS + design tokens.
Styling idiom — global stylesheet + CSS custom properties
This is not Tailwind and not CSS-in-JS. Styling is a global stylesheet of semantic class names plus CSS custom-property design tokens. Two rules:
- The components carry their own classes (
.card,.card-head,.section-kicker,.count-strip,.pricebar,.source-chip,.control,.pill,.mono,.top-nav,.meta-grid…). Don't reach inside them; compose via props. New class names you invent will not exist in the stylesheet. - For your own layout/wrapper glue, use the token vars + inline styles, on the 4/8/12/16/24/32 spacing scale (tabular-nums for numbers). Color/shape tokens, all defined in the shipped CSS:
| Group | Tokens |
|---|---|
| Surface | --bg-app --bg-card --bg-card-alt --bg-headline |
| Text | --fg-primary --fg-secondary --fg-tertiary --fg-on-dark |
| Brand/CTA | --accent --accent-hover --accent-soft --accent-2 |
| Semantic | --success --warn --danger (*-soft variants) |
| Border | --border-soft --border-card --border-strong |
| Shape/type | --radius --radius-sm --radius-lg --shadow-md --font-sans (Manrope) --font-mono --container |
<div style={{ background: "var(--bg-card)", border: "1px solid var(--border-card)",
borderRadius: "var(--radius)", padding: 16, color: "var(--fg-primary)",
fontFamily: "var(--font-sans)" }}>
<b style={{ color: "var(--accent)" }}>9 850 000 ₽</b>
</div>
Where the truth is
- Styles/tokens: read the bound
styles.cssand its@import_ds_bundle.css— the authoritative class + token list. - Per component:
<Name>.d.ts(props) and<Name>.prompt.md(usage). NB: synth-built.d.tsprops are loose ([key: string]: unknown); the.prompt.md+ preview card show real prop shapes and realistic data. - Money/area/dates are RU-formatted (
toLocaleString("ru-RU"),₽,м²). Keep that idiom.