Skip to content

Pagewright · UI kit

Components

Every building block used across these docs, with its states. All of them read their colors from tokens, so they switch with the theme and stay accessible in both.

Buttons

Five variants in three sizes. Disabled buttons keep their shape at half opacity.

components/ui/button.tsx
Button variants by size
Variantsmmdicondisabled
primary
secondary
outline
ghost
danger

Badges

Short labels for state and metadata. Add a dot when the badge reports a status.

components/ui/badge.tsx

Plain

NeutralBetaStableDeprecatedRemoved

With dot

QueuedRunningSucceededRetryingFailed

Status

A dot with a written label. Pulse marks a live state.

components/ui/misc.tsx
OperationalDegraded performancePartial outageMaintenancePaused

Inputs

Input, Select and Textarea wrapped in Field, which ties the label and hint to the control.

components/ui/field.tsx

Lowercase letters, numbers and dashes.

Set by your plan.

Switch

An on/off control with role switch. Pair it with a visible label.

components/ui/switch.tsx
  • Retry failed jobsOn
  • Pause queueOff

Tabs

Underline tabs with counts and arrow-key navigation.

components/ui/tabs.tsx

Every job in the last 24 hours, newest first.

Kbd

Keyboard keys for shortcuts in prose and menus.

components/ui/misc.tsx
  • Open search⌘K
  • Focus search/
  • Move through results↑↓
  • CloseEsc

Progress

A labelled progress bar. The tone tells how close a limit is; the number says it exactly.

components/ui/misc.tsx
Monthly jobs4,213 of 10,000
Backfill progressComplete
Rate limit used78 of 100 req/s
Log storage9.6 of 10 GB

Avatars

Initials on a tone picked from the name, in three sizes. Decorative: keep the name next to it.

components/ui/avatar.tsx
sm md lg
Mira, Tomasz and 3 others edited this page

Callouts

Four asides. The label is always written, so meaning never relies on color.

components/docs/blocks.tsx

Steps

Numbered, vertical steps for procedures.

components/docs/blocks.tsx
  1. Install the CLI

    Use npm, Homebrew or the install script.

  2. Log in

    Run halyard login and approve the device in your browser.

  3. Start a local worker

    halyard dev runs your handlers against the test environment.

Cards that lead to the next page, in two or three columns.

components/docs/blocks.tsx

Accordion

Native details elements, open and closed.

components/docs/blocks.tsx
Open: What counts as a job?

Each job you create counts once, however many attempts it needs.

Closed: Can I pause a queue?

Yes. Paused queues keep accepting jobs and start them when you resume.

File tree

Project layouts with notes. Mark the file the reader should open.

components/docs/blocks.tsx
acme-api
halyard.config.ts— queues and schedules
workers
emails.ts
billing.ts
package.json
.env.local— HALYARD_KEY

Methods and endpoints

MethodBadge for each HTTP verb, and Endpoint for a method with its path.

components/docs/blocks.tsx
GETPOSTPUTPATCHDELETE
POST/v3/jobs
GET/v3/jobs/{id}
DELETE/v3/queues/{queue_id}/jobs/{id}

Parameters

Request parameters and response fields with type, required flag and default.

components/docs/blocks.tsx

Body parameters

queuestringrequired
The queue to add the job to, for example emails.
taskstringrequired
The task name your worker handles.
max_attemptsintegerdefault: 5
How many times to try before the job moves to dead letters.
run_attimestamp
Delay the job until this time (ISO 8601).

Code

CodeBlock for one snippet, with marked lines and line numbers. CodeGroup for one example in several languages.

components/ui/code.tsx
workers/emails.ts
import { Worker } from "@halyard/node"; const worker = new Worker(process.env.HALYARD_KEY, { queues: ["emails"], concurrency: 10 }); worker.task("send-welcome-email", async (job) => {  const user = await db.users.find(job.payload.user_id);  await mailer.send("welcome", user.email);  return { sent: true, attempt: job.attempt };}); await worker.start();
curl https://api.halyard.example/v3/jobs/job_3Rk9Tq7Xw2 \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d"

Table

Data tables scroll inside their own frame on small screens, so the page never does.

components/ui/table.tsx
JobTaskQueueStatusDuration
job_3Rk9Tq7Xw2send-welcome-emailemailsSucceeded182 ms
job_9Qe1Hs6Zt3sync-crm-contactintegrationsRetrying2.4 s
job_2Wd8Nf5Kb1build-invoice-pdfbillingRunning—
job_6Ty3Gm1Rc5resize-avatarmediaFailed30.0 s

Empty state

What a list shows before there is anything in it, with one clear next step.

components/ui/misc.tsx

No dead letters

Jobs that use every attempt land here. Nothing has failed for good in the last 30 days.

How retries work

Suggested