@ambasada/ui

中文文档
0.8.19发布于 2026/11/06MITTypeScriptES Module零依赖近 30 天下载 4461

The Ambasada look for mini apps: design tokens (colours, Inter + JetBrains Mono, radii, spacing, safe areas) and a small component set in plain CSS, with optional React wrappers. One stylesheet to .

原始使用文档
文档目录4 节
  1. Install
  2. Tokens
  3. Components
  4. React

@ambasada/ui

The Ambasada look for mini apps: design tokens (the Ambasada colours, Inter + JetBrains Mono, radii, spacing, the mono label, the shell's safe areas and host bar) and a small component set in plain CSS, with optional React wrappers. Light only, no framework, no runtime: one stylesheet a plain HTML page can <link>.

Install

npm install @ambasada/ui
import "@ambasada/ui"; // fonts + tokens + components, once at the root of the app

Or the parts: @ambasada/ui/tokens.css, @ambasada/ui/components.css, @ambasada/ui/fonts.css (skip fonts.css if you serve Inter and JetBrains Mono yourself).

With no build step, the same three in one file from any npm CDN (the fonts load from next to it):

<link rel="stylesheet" href="https://unpkg.com/@ambasada/[email protected]/dist/ambasada-ui.css" />

Optional: the ambasada init templates start unstyled, and only the mini app's in-app page (ambasada miniapp enable) loads it. Use it on your own pages if you want the Ambasada app's look.

Tokens

All on :root, from the Ambasada hub (each has a source comment in tokens.css): --color-accent (the logo red), --color-accent-text (red for small text), --color-bg, --color-surface, --color-surface-2, --color-ink / -2 / -3, --color-line, --color-success / warn / danger / info and their -soft tints, --card-* (the member card palettes), --font-sans, --font-mono, --text-*, --weight-*, --tracking-label, --radius-*, --shadow-*, --space-1 to --space-10, --page-max, --tap, --ease, --duration.

The shell's insets, for anything you position yourself:

VariableDefaultInside the Ambasada app
--ambasada-safe-area-top / bottom / left / rightenv(safe-area-inset-*, 0px)set on <html> by @ambasada/miniapp's ready()
--ambasada-host-bar0pxthe height of the shell's top bar
--ambasada-inset-top / bottom / left / rightmax(--ambasada-safe-area-*, env(safe-area-inset-*))what to keep clear: use these

Use the --ambasada-inset-* tokens for anything you place yourself. They take the larger of the shell's report and the browser's own inset, so the inset is right inside the app and on the open web and is never counted twice. Keep the margin on top of it small (8 px): an empty band above the home indicator is a bug.

.my-bar { position: fixed; bottom: 0; padding-bottom: calc(8px + var(--ambasada-inset-bottom)); }

Components

ClassWhat
ui-pageThe 480 px column, padded clear of the host bar and every safe area.
ui-card, ui-card-titleWhite card, hairline border, 16 px radius.
ui-button, ui-button secondary, blockPrimary (brand red: one per screen) and secondary buttons, ≥ 44 px. On <button> or <a>.
ui-labelThe mono label: 11 px, uppercase, 0.1em. Captions, never sentences.
ui-group (ui-group-head, ui-group-body)A list: rows in one bordered block, with a title.
ui-row (row-icon, row-text, row-title, row-sub, row-right, row-chev)List row; tappable, danger, muted; row-icon accent / good / bad.
ui-pillStatus pill with a dot: good, bad, warn, accent, pulse.
ui-sheet-backdrop > ui-sheet (ui-sheet-handle > ui-sheet-grip + ui-sheet-head, -body, -foot), ui-icon-btnBottom sheet at every width (no centred dialogs): grip, rounded top, dimmed page, a body that scrolls, the one primary action in the foot. Add ui-sheet-open to <body> while open. The React Sheet also portals to <body>, closes on a drag down, and keeps the foot above the keyboard.
ui-field (ui-field-label, ui-field-hint, .bad/.good), ui-inputA form field: label, control, one line of hint or error under it, 8 px apart; compact inside ui-shell with a mouse. ui-input on <input>, <textarea>, <select> (mono, code).
ui-stepper-wrap > ui-stepper (ui-stepper-value), ui-presets− value + for amounts, with preset chips (on).
ui-empty (ui-empty-icon)Empty state: icon, <strong> title, hint, action.
ui-skeletonGrey bars (<span>s) while loading: skeletons, not spinners.

For tools built for the laptop that still open in the Ambasada app (the Developer app):

ClassWhat
ui-shell > ui-shell-side, ui-shell-scrim, ui-shell-main > ui-shell-top (ui-shell-menu), ui-shell-content240 px sidebar, sticky top bar, content up to 1088 px. Under 900 px the sidebar is a drawer (ui-shell open). Clears the host bar and safe areas once.
ui-nav (ui-nav-title), ui-nav-item (ui-nav-label, ui-nav-right, on)Sidebar navigation; the current item gets a red marker.
ui-tabsTabs as links under a title (a.on); scrolls sideways when narrow.
ui-field, ui-inputThe same field as above, compact here with a mouse (40 px, 14 px text). <Field label value onChange /> renders the input itself.
ui-table (.num, tr.tappable)Data table: hairline rows, tabular figures.
<main class="ui-page">
  <p class="ui-label">// My Company</p>
  <section class="ui-card">
    <h2 class="ui-card-title">Your name as a folk poem</h2>
    <button class="ui-button block">Pay 2 TON</button>
  </section>
  <section class="ui-group">
    <div class="ui-group-head"><h2>Orders</h2></div>
    <div class="ui-group-body">
      <a class="ui-row tappable" href="/orders/1">
        <span class="row-text"><span class="row-title">Poem for Ana</span><span class="row-sub">2 min ago</span></span>
        <span class="row-right"><span class="ui-pill good"><i></i>Ready</span></span>
      </a>
    </div>
  </section>
</main>

React

import { Button, Card, Empty, Field, Group, Nav, NavItem, Page, Pill, Row, Shell, Sheet, Skeleton, Stepper, Tabs } from "@ambasada/ui/react";

<Page>
  <Card title="Your name as a folk poem">
    <Button block onClick={() => setOpen(true)}>Pay 2 TON</Button>
  </Card>
  <Group title="Orders">
    <Row title="Poem for Ana" sub="2 min ago" right={<Pill tone="good">Ready</Pill>} href="/orders/1" />
  </Group>
  <Sheet open={open} onClose={() => setOpen(false)} title="Pay" footer={<Button>Pay 2 TON</Button>}>
    <Stepper value={amount} onChange={setAmount} min={1} unit="TON" presets={[1, 2, 5]} />
  </Sheet>
</Page>

<Shell sidebar={<Nav title="Apps"><NavItem label="Acme" href="/p/acme" current /></Nav>} top="Acme" open={menu} onMenu={setMenu}>
  <Tabs tabs={[{ id: "overview", label: "Overview", href: "/p/acme" }]} current="overview" />
  <Field label="Slug" value={slug} onChange={(e) => setSlug(e.target.value)} hint="acme.ambasada.dev" />
</Shell>

The wrappers render markup only and import no CSS (load the stylesheet yourself). The module is marked "use client" (Sheet uses effects), so Next.js server components can render them too; they server-render with react-dom/server. React ≥ 18 is an optional peer dependency.

Rules for the look (one red thing per screen, light only, sheets for forms): docs/DESIGN-SYSTEM.md and docs/MINI-APPS.md §9 in the Ambasada repo.

MIT, © CENTYSO. Inter and JetBrains Mono: SIL Open Font License 1.1 (fonts/OFL-*.txt).

版本与发布记录

@ambasada/ui 共发布 27 个版本,首次发布于 2026/11/02;过去 12 个月发布了 27 个版本。

版本发布日期距今
0.8.19latest2026/11/061 天前
0.8.182026/11/062 天前
0.8.172026/11/052 天前
0.8.162026/11/052 天前
0.8.152026/11/052 天前
0.8.142026/11/052 天前

关于 @ambasada/ui 的常见问题

@ambasada/ui 是什么?

The Ambasada look for mini apps: design tokens (colours, Inter + JetBrains Mono, radii, spacing, safe areas) and a small component set in plain CSS, with optional React wrappers. One stylesheet to .

如何安装 @ambasada/ui?

在项目目录运行 npm install @ambasada/ui,或使用 pnpm add / yarn add / bun add。

@ambasada/ui 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@ambasada/ui 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@ambasada/ui 可以商用吗?

@ambasada/ui 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@ambasada/ui 的下载量有多少?

根据 npm 官方下载统计,@ambasada/ui 在 2026/10/07 – 2026/11/05 这 30 天内被下载 4,461 次,日均约 149 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@ambasada/ui 还在维护吗?

最新版本 0.8.19 发布于 2026/11/06(1 天前);至今共发布 27 个版本,其中过去 12 个月发布了 27 个;首次发布于 2026/11/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。