ApiKeys
List, create and revoke API keys. A new key is shown once.
SourcePackage @weft-js/warp
Preview
tsx
import { state } from '@weft-js/core'import { ApiKeys, Toaster } from '@weft-js/warp'import type { ApiKey } from '@weft-js/warp'export function Test() { const keys = state<readonly ApiKey[]>(API_KEYS) const create = async (draft: { name: string; scopes: string[] }) => { await wait(600) keys.value = [{ id: draft.name, name: draft.name, prefix: 'tsl_test_77aa', scopes: draft.scopes, created: 'Today' }, ...keys.value] return 'tsl_test_77aa_sample_not_a_real_key' } return ( <> <ApiKeys keys={keys} now={NOW} onCreate={create} onRevoke={key => { keys.value = keys.value.filter(k => k !== key) }} /> <Toaster /> </> )}const NOW = '2026-10-31T17:00:00Z'const API_KEYS: ApiKey[] = [ { id: 'k1', name: 'CI deploys', prefix: 'tsl_test_8c2f', scopes: ['deploy'], created: 'Sep 30', lastUsed: '2026-10-31T16:42:00Z' }, { id: 'k2', name: 'Metrics export', prefix: 'tsl_test_41ab', scopes: ['read'], created: 'Aug 2', lastUsed: '2026-10-12T10:00:00Z' }, { id: 'k3', name: 'Staging smoke tests', prefix: 'tsl_test_e07d', scopes: ['read', 'deploy'], created: 'Jul 19', lastUsed: '2026-10-30T04:10:00Z' }, { id: 'k4', name: 'Old Jenkins box', prefix: 'tsl_test_19c4', scopes: ['deploy'], created: 'Mar 3' },]const wait = (ms: number) => new Promise<void>(done => { setTimeout(done, ms) })Installation
npm install @weft-js/warpUsage
tsx
import { ApiKeys } from '@weft-js/warp'Accessibility
- This has no shortcuts of its own: controls inside it use Tab, Enter and Space as usual, and warp's parts keep their roles and labels.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
keys | readonly ApiKey[] | State<readonly ApiKey[]> | — | The keys: only ever a prefix, never the secret. |
kind | "live" | "test" | 'test' | test or live, for the words on the page. |
now | string | — | The current time, for "last used" and the one-day revoke rule. |
scopes | { value: string; label: string; }[] | SCOPES | The scopes to offer. |
expiries | { value: string; label: string; }[] | EXPIRIES | The expiry choices. |
| Event | Type | Default | Description |
|---|---|---|---|
onReauth | ((reason: string) => Promise<boolean>) | — | Ask for a fresh sign-in first. Resolve false to stop. |
onCreate | (draft: KeyDraft) => Promise<string> | — | Creates the key and returns its full secret. |
onRevoke | (key: ApiKey) => void | Promise<void> | — | Revokes it. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="row"] [data-part="prefix"]
prefix