Choosing a level
Youj is a ladder: components and blocks (cards, sections and screens), each with its own place to browse. Create assembles an app frame from copy-in parts and fills it with screens; the copy-in levels are single pieces to add to an app you have.
Everything Youj ships sits on one ladder, from a single control to a whole screen: Components, Blocks. Components come in two sizes, simple and composite, and blocks in three: cards, sections and screens. Each rung is built from the rungs below it, never above, and each has its own place, so you can browse one level at a time: the Components and Blocks pages of these docs. Next to the ladder, Create assembles an app frame from copy-in parts (frame-shell, a sidebar, a top bar, an account menu and search), with the screens you add from the Screens catalog inside it, themed and exported as code. To wire a frame by hand from the components instead, follow Build an app frame.
| Level | What it is | You get it by | Browse |
|---|---|---|---|
| Component, simple | One control, surface, mark or effect with plain props: a button, a dialog, a sparkline. | Importing from @youj/react or @youj/motion | Components |
| Component, composite | Several parts, or a model of rows, series or steps, with generic props: a data table, a chart, a date range picker. | Importing from @youj/react | Components |
| Card | A self-contained card or panel with content of its own, in a product domain: a deploy pipeline, a recipe. | npx @youj/cli add <name> | Cards |
| Section | A full-width band of a website: a hero, pricing, a footer. | npx @youj/cli add <name> | Sections |
| Screen | A full screen: sign-in, settings, a dashboard. | npx @youj/cli add <name> | Screens |
An item is built from items on its own level or below, never above: a screen uses cards, a card uses composite components, and a date range picker is built on the date picker. Cards, sections and screens are together the blocks: their registry type is registry:block and add writes them under blocks/.
Components
Components are the basics: code you depend on and update with the package. Each component's docs page shows it live, with its install command (npx @youj/cli add <name>), its import and its props, variants and states. Find one by what it does, then compose it.
import { Button } from '@youj/react'Blocks
The copy-in levels are bigger: whole cards, bands and screens built from those components, which you copy into your app as source with the CLI and then own. Each block's docs page shows it live, with its code and the install command.
When to use which
- A new app, or an app with no shell yet: Create. It composes the frame (sidebar, top bar, account, search) with the screens you add, each a page in its nav, and exports one install command.
- A control or a building block to compose yourself: a component for one control, surface or mark, or for parts that work together (a table, a chart, a picker). Import it from the package.
- A piece for an app that has its own frame: a card for a card or panel, a section for a band of a website, or a screen for a whole screen.
- A frame with no screens: Create with none added. You get the shell and its nav, ready for pages of your own.
Browse a level, smallest first. The rest of this page is about adding the copy-in ones.
Blocks
A block is one card, section or screen, ready to use as it is. Add it by its registry name, which its page shows:
npx @youj/cli add app-analytics-overviewIn an app on the packages, add writes the block's own files under your @/ alias, blocks/app/analytics-overview.tsx and its parts in blocks/app/analytics-overview/, and copies no component: the block imports those from @youj/react, @youj/core, @youj/motion and @youj/icons. It installs whatever the block needs that the app doesn't have yet, here recharts for its charts and date-fns and react-day-picker for its date range picker. Then render it:
import { AnalyticsOverview } from '@/blocks/app/analytics-overview'
export default function AnalyticsPage() {
return <AnalyticsOverview />
}Every block takes the same kinds of props, so you don't edit its source to use it:
- Data: named for what it holds, such as
kpis,membersorplans. The defaults are the demo's data. A few blocks are demo-only and take no data orcopyprops: AI workspace, Dispatch board, Fleet overview, Money overview and Theme playground, and Exploded view takescopy,partsandspecsbut draws a fixed device. Their pages say so; copy the source to build on them. - Text:
copyrewrites any string, labels and announcements included. - Actions:
on…callbacks, such asonRangeChangeoronSave. When one returns a promise, the block shows it pending, then its error if it rejects. A callback you haven't passed plays the demo's behavior, and in development the console says so once, for exampleLogin: onSignIn isn't wired; showing demo behaviour, so a forgotten handler can't pass for a working one. Production builds drop the warning. - State you own: a
value,defaultValueandonValueChangetrio, or a named one such asrange,defaultRangeandonRangeChange. - Loading:
loading,errorwithonRetry, andempty. - Theme and locale: a block wears your app's theme, the one set on
YoujProvideror aThemeScopearound it, and formats numbers and dates in the provider'slocale. Itsthemeprop forces another theme and itslocaleprop another locale; their lists show some blocks in another preset by passingthemefrom their stories. A preset you force brings its type, so load that preset's fonts (see the Type column of Presets), or the block falls back to the system face. - Demo data: a block that shows live operational data, such as rate limits, a job queue or a deploy pipeline, runs a simulation only while you pass none of its data, and marks that with a small dashed Demo data badge. Pass your data and the simulation stops: re-render the block with fresh data to keep it live.
demoMarker={false}hides the badge in a demo of your own. - Where it goes: a block is a card (a card or panel inside a screen), a section of a website or a screen; its registry item says which as
meta.level(and an overlay card says what it opens in asmeta.opens), and its page shows it that way. A card renders as the card itself, at its natural width, for your screen to place;filltakes the width you give it, andembedded={false}draws a screen of its own around it.
Each block's page lists its props and shows it fed with other data. A block takes its density from the app, so it's compact in an app set up with density="compact" (see Density and scaling).
Related
youj add does, and its options.