@scalio-cloud/ui

中文文档
0.29.0发布于 2026/11/02SEE LICENSE IN README.mdCommonJS零依赖

Scalio控制室设计令牌,顺风预设,自托管字体,共享的应用程序标题,登录布局,侧边栏和页面块

中文使用文档
文档目录16 节
  1. 在应用程序中使用它(CRA/craco或Vite)
  2. 应用头(React)
  3. 侧边栏,切换器和页面块(React)
  4. 设置页面(React)
  5. 登录页面和配置文件(React)
  6. 用户管理(React)
  7. Microsoft Entra ( RoleAdmin , RoleSourceSettings )
  8. 设置向导(React)
  9. 双因素卡和许可面板(React)
  10. Gruppe系统:zur<s:1> cksetzen和helpers (React)
  11. Benachrichtigungen: E-Mail-Versand and E-Mail-Vorlagen (Rea…
  12. 协议:动作和工作(React)
  13. 命令面板(React)
  14. 安装
  15. 许可证
  16. 释放

@scalio-cloud / ui

Scalio应用程序(Nexus, Rosetta, Foundry, Citadel, Compass,后来的Pulse)的共享外观和感觉: “控制室”的设计标志,一个顺风预设和字体,从应用程序本身提供。 规范: design/UISPEC.md 在 Scalio-Cloud/scalio-docs (单一副本)。

文件它是什么?
tokens.cssshadcn/ui CSS变量,亮起 :root,暗的 .dark (克莱因蓝 #002FA7,半径4px)
fonts.css@font-face 用于Chivo, IBM Plex Sans, JetBrains Mono (woff2,拉丁语,SIL OFL 1.1)。没有谷歌字体请求
base.css正文/标题/代码字体系列
shell.css应用标题、用户菜单、页面标题和版本(scalio-* 类)
nav.css侧边栏,电话抽屉,切换器,上下文选择,支持抽屉,页面块
index.css所有这些都在一个导入中
react/React的共享应用头(见下文),除了React之外没有依赖项
tailwind-preset.js颜色,字体,半径,手风琴动画, brand 的颜色, h-switcher, h-header, w-sidebar
tokens.js没有CSS的代码的原始值(图表、电子邮件、pdf)

在应用程序中使用它(CRA/craco或Vite)

// tailwind.config.js
module.exports = {
  presets: [require("@scalio-cloud/ui/tailwind-preset")],
  content: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"],
  plugins: [require("tailwindcss-animate")],
};
/* src/index.css, first line */
@import "@scalio-cloud/ui/index.css";
@tailwind base;
@tailwind components;
@tailwind utilities;

然后删除应用程序自己的 :root { --... } / .dark { --... } 块和谷歌字体 @import / <link>. 类等 bg-primary, rounded-sm, font-display 保持工作不变。

应用头(React)

每个应用都在右侧显示相同的标题,总是按照这个顺序:(应用操作),状态,语言,主题, 支持,《阿凡达》。 部件只有在应用程序通过其处理程序时才会出现(Compass没有暗模式,所以没有) onThemeChange)。

import { AppHeader, PageHeader, VersionTag, manualUrl } from "@scalio-cloud/ui/react";

<AppHeader
  brand={{ mark: "N", name: "Scalio Nexus", sub: "Dev" }}  // or your own element
  onMenu={() => setMobileNavOpen(true)}                     // hamburger below 768px
  left={<TenantSelect />}                                   // after the brand
  actions={<LocalePopover />}                               // right side, before the fixed group
  status={<ApiStatus />}                                    // hidden below 768px
  lang={lang} onLangChange={setLang}                        // one click, shows the other language
  theme={theme} themeModes={["light", "dark", "system"]} onThemeChange={setTheme}
  docsUrl={manualUrl("nexus", { stage, lang })}           // book icon, opens the manual in a new tab
  onSupport={() => setSupportOpen(true)}
  user={{ name, email, role }} onLogout={logout}
  menuItems={[{ label: "Profil", icon: User, onSelect: () => nav("/profile"), testId: "profile-link" }]}
  testIds={{ logout: "logout-button" }}                     // keep an app's existing test ids
/>
<PageHeader eyebrow="Verwaltung" title="Benutzer" subtitle="..." actions={<Button>Neu</Button>} />
<VersionTag version="1.2.4" commit="3f2a1bc" />              // bottom of the sidebar

文本是内置的 lang de 和 en 并且可以被覆盖 labels。默认测试id (language-toggle-btn, theme-toggle-btn, support-ticket-trigger, user-avatar-btn, logout-btn)都在 TEST_IDS。组件是普通的CommonJS React.createElement,所以CRA、Vite和Jest不需要额外的配置。 图标是内联的(Lucide, ISC,参见 licenses/)。

侧边栏,切换器和页面块(React)

每个应用程序都有相同的帧(UISPEC“导航”):切换器,标题与上下文选择在左边,然后 侧边栏搜索,最多一个主要操作,“Übersicht”,最多三个部分和“Verwaltung”最后 (Protokoll, Konten und rolen, einstein)配置文件和个人页面只存在于用户菜单中。应用程序 将其导航描述为数据;侧边栏、电话抽屉和(后来的)搜索读取相同的列表。

import { NavLink } from "react-router-dom";
import { AppShell, Sidebar, ProductSwitcher, ContextSelect, SupportDrawer, useScalioApps,
  KpiTile, EmptyState, Loading, Notice, StatusBadge, LABELS } from "@scalio-cloud/ui/react";

const L = LABELS[lang];
const NAV = { sections: [
  { id: "main", items: [{ to: "/", label: L.overview, icon: LayoutGrid, end: true }] },
  { id: "compliance", label: t("Compliance"), items: [
    { to: "/drifts", label: t("Drifts"), icon: GitCompareArrows, badge: open || null, badgeTone: "error" },
  ] },
  { id: "admin", label: L.administration, items: [
    { to: "/audit", label: L.auditLog, icon: ScrollText },
    { to: "/accounts", label: L.accounts, icon: Users, hidden: !isAdmin },   // hidden items and empty sections disappear
    { to: "/settings", label: L.settings, icon: SlidersHorizontal },
  ] },
] };

const apps = useScalioApps(() => api.get("/apps").then((r) => r.data));   // once per page load
<AppShell
  switcher={apps.features.switcher && <ProductSwitcher current="citadel" links={apps.links} stage={apps.stage} sso={sso} lang={lang} />}
  header={<AppHeader ... onMenu={() => setDrawer(true)}
    left={<ContextSelect label={L.tenant} value={tenantId} options={tenants} onChange={select} hint={domain} testId="tenant-switcher" />} />}
  sidebar={<Sidebar nav={NAV} link={NavLink} lang={lang} version={VERSION} commit={COMMIT}
    search={{ onOpen: openPalette, shortcut: "⌘K" }} primaryAction={{ label: t("Scan starten"), icon: Play, onSelect: scan }} />}
  drawerOpen={drawer} onDrawerClose={() => setDrawer(false)}   // phones: same sidebar in a drawer (test ids with "m-")
  drawerTop={<ContextSelect ... testId="m-tenant-switcher" />}  // below 640px the header hides the select, the drawer shows it
>
  <Routes>...</Routes>
</AppShell>
<SupportDrawer open={supportOpen} onClose={...} lang={lang} client={supportApi(api)} page={location.pathname}
  context={[["URL", location.pathname], [L.tenant, current?.name]]} />

与 client 抽屉里有“Neue Anfrage”标签(类别、主题、描述、技术细节)和 “我的票”(列表、回答、回复、评分);机票到Compass (scalio-docs ADR)的中央服务台 0022),后端路由来自scalio-connect scalio_connect.support.web. supportApi(api) 取应用程序的 axios实例。设置卡 <SupportConnection client={supportApi(api)} lang={lang} /> 连接 安装使用一次性代码(admins)。没有 client 抽屉里保存着旧的单张表格 onSubmit. supportApi(api, { ideas: true }) 添加标签“Ideen”(Scalio Ideen, ADR 0050;后端路由器) scalio_connect.support.ideas_web.ideas_router(scalio-connect 0.8.0):应用程序的想法与投票和评论和 “Idee vorschlagen”也有类似的想法;然后是“unsch”类别。

设置卡 <BeaconConnection client={peersApi(api)} lang={lang} /> 将应用程序与Scalio Beacon配对 (地址和一次性代码来自Beacon, Einstellungen -> Verbundene Apps);然后将调查结果交给Beacon公司。后端: scalio-connect 0.8.0 peers.web.admin_router.

link 是路由器的 NavLink (就 to, end,一个 className 功能和 onClick); 没有它 工具条显示普通链接并将项目标记为 activePath。项目test id默认为 nav-<path> (nav-overview 用于 /),或设置 testId。页面: KpiTile (语气 error =红色数字), EmptyState (孩子=下一步), Loading, Notice (error 红色=费勒; warn/important 橙色= wichtig, ok/success 绿色=融化; info/action 蓝色=行动; banner =全宽), StatusBadge (音调 neutral, running, ok, warn, error), PageHeader 与 back 查看详细页面。

属于一个菜单项的页面保留自己的地址:该菜单项将它们列在其中 match ({ to: "/groups", label: "Gruppen", match: ["/teams", "/distribution-lists"] },通过 activePath 与 link),每页显示 <SubNav items={[{ to: "/groups", label: "Sicherheit", end: true }, ...]} link={NavLink} /> 在上面。一个有两个工作区域(Nexus Identity和HR)的应用程序 <WorkspaceSwitcher options value onSelect /> 进入侧边栏 top.

侧边栏中的页面操作 (从0.18.0开始,ispec第2节): <Sidebar pageActions ... /> 保持Übersicht ( 第一部分的第一项(没有标题),并在它的正下方添加一个插槽。页面将其操作封装在 <PageActions>;从768px他们移动到槽,在手机上,他们留在页眉。槽位不接受 没有动作的页面空间;通过操作,它将菜单向下推。

<PageHeader title="Kontakte" actions={<PageActions><Button onClick={add}><Plus /> Kontakt</Button></PageActions>} />
<PageHeader title={doc.number} actions={<PageActions><Button variant="outline" asChild><Link to="/invoices"><ArrowLeft /> Zurück</Link></Button></PageActions>} />

只有开始或引导的操作才会出现在那里(新建,导入,扫描,扫描<e:1>),每页最多两个。 没有“新”/“新”的标签:+图标表示它(“+ Kontakt”,而不是“+ Neuer Kontakt”)。 过滤器,搜索,标签和specichern留在页面上。有自己侧边栏位置的应用程序 <ActionSlot /> 他们自己。

设置页面(React)

设置的每个区域都有自己的地址(/settings/<area>); 应用程序的路由器会选择该区域 布局绘制子导航,面包屑(“Einstellungen›Verbindungen”)和标题。组 general, connections, notifications, security 和 system 得到他们的名字 LABELS 一直坐在这里 订单,应用程序自己的组(与 label)跟在“Allgemein”后面。隐藏区域和空组消失在下面 三个领域(minItems),没有子导航。搜索将查看标签、提示、组和 keywords; search={false} 忽略它, search={<OwnSearch />} 将应用程序自己的搜索放在那里。

import { SettingsLayout, SettingsSection } from "@scalio-cloud/ui/react";

const GROUPS = [
  { id: "general", items: [{ id: "general", to: "/settings/general", label: "Instanz", hint: "Name, Sprache, Zeitzone" }] },
  { id: "flows", label: "Abläufe", items: [{ id: "onboarding", to: "/settings/onboarding", label: "Onboarding" }] },
  { id: "connections", items: [{ id: "sync", to: "/settings/sync", label: "Synchronisierung", keywords: ["Intervall"] }] },
  { id: "system", items: [{ id: "updates", to: "/settings/updates", label: "Updates", hidden: saas }] },
];

<SettingsLayout groups={GROUPS} active={area} link={NavLink} onSelect={(i) => navigate(i.to)} lang={lang}>
  <SettingsSection id="cloud-sync" title="Cloud-Synchronisierung" description="Intervall und Umfang."
    footer={<Button onClick={save}>Speichern</Button>}>
    ...form fields (shadcn)...
  </SettingsSection>
</SettingsLayout>

登录页面和配置文件(React)

所有登录页面都使用相同的框架和顺序:Microsoft先,然后是“order mit E-Mail”,密码字段为 在它下面,是提交按钮。忘记密码,重置,验证电子邮件和两个步骤是 他们自己的页面在同一个框架里。只显示应用程序可以做什么(仅在Compass中注册,演示帐户仅限) 在演示模式下)。

import { AuthLayout, AuthHeader, MicrosoftButton, AuthDivider, AuthMessage, ProfileSection } from "@scalio-cloud/ui/react";

<AuthLayout
  brand={{ mark: "N", name: "Scalio Nexus", claim: "Alle Konten aus einer Konsole verwalten.",
           features: ["Onboarding", "Ändern", "Offboarding"] }}
  lang={lang} onLangChange={setLang}                 // top right
  theme={theme} onThemeChange={setTheme}             // optional
  footer={<VersionTag version={v} />}                // optional
>
  <AuthHeader eyebrow="Zugang" title="Anmelden" subtitle="..." />
  <MicrosoftButton href="/api/auth/sso/login" lang={lang} disabled={!ssoReady} hint="..." />
  <AuthDivider lang={lang} />
  <form>...</form>
  <AuthMessage kind="error">{error}</AuthMessage>
</AuthLayout>

// Profile page: the same sections in every app, leave out what an app does not need.
<ProfileSection id="account" lang={lang}>...</ProfileSection>      // Konto
<ProfileSection id="appearance" lang={lang}>...</ProfileSection>   // Darstellung
<ProfileSection id="language" lang={lang}>...</ProfileSection>     // Sprache und Region
<ProfileSection id="security" lang={lang}>...</ProfileSection>     // Sicherheit
<ProfileSection id="connections" lang={lang}>...</ProfileSection>  // Verknüpfungen

章节内容(每个应用都一样,参考Nexus): ProfileIdentity 在Konto, ThemeChoice 在 Darstellung, LanguageChoice + TimezoneChoice 在Sprache und Region, PasswordChange + SecurityFactors 在 Sicherheit。应用程序存储时区(POST /auth/preferences {timezone}),电话 setUserTimezone() 与 的值 /auth/me 并将日期格式化为 timeZone: currentTz(). applyTheme(mode) 设置dark类 适用于光、暗、系统。

其他表单字段和按钮(例如name字段)保持应用程序自己的(shadcn),因此它们与应用程序的其余部分匹配。

用户管理(React)

Konten und rolen→Benutzer,每个应用程序都一样(ADR 0059)。后端遵循scala -docs interfaces/app-users.md; usersApi(api, {base: "/admins"}) 连结。

import { UserAdmin, usersApi, MicrosoftConnection } from "@scalio-cloud/ui/react";

const users = usersApi(api);   // once, outside the component
<UserAdmin client={users} me={user.id} lang={lang} roles={[{ value: "admin", label: t("Administrator") }, ...]}
  defaultRole="operator" signInModes={["microsoft", "password"]} microsoftEnabled={ssoOn} canLock
  accessColumn={{ label: t("Customers"), render: (u) => ... }} accessField={(value, onChange, role, u) => ...}
  notify={(text, tone) => toast[tone](text)} confirm={confirm} formatError={fmt} />

// Profile -> Verknüpfungen
<MicrosoftConnection linked={user.microsoft} canUnlink={user.has_password} onLink={...} onUnlink={...} lang={lang} />

Microsoft Entra (RoleAdmin, RoleSourceSettings)

import { RoleAdmin, rolesApi, RoleSourceSettings } from "@scalio-cloud/ui/react";
const roles = rolesApi(api);                               // Nexus: rolesApi(api, { permissions: "/permissions" })
<RoleAdmin client={roles} lang={lang} notify={toast} confirm={confirm} onChange={reloadUsers} />
<RoleSourceSettings value={source} tenants onSave={({ source, tenants }) => api.put("/users/role-source", { source, tenant_ids: tenants })} lang={lang} />

后端是规模平台 roles_router (0.3.0)。内置角色是只读的;自己的角色永远得不到 应用程序为管理员保留的权限。

设置向导(React)

第一次登录后,在每个应用程序中都一样(ADR 0060, uspec第3节)。应用程序写道 只有它的脚步;后端遵循scala -docs interfaces/setup-wizard.md (GET/PUT /api/setup/wizard)。

import { SetupWizard, SetupWizardButton, useSetupWizard, setupWizardApi } from "@scalio-cloud/ui/react";

const wizardClient = setupWizardApi(api);   // once, outside the component ({ base: "/wizard" } for another route)

function AppWizard() {
  const w = useSetupWizard({ client: wizardClient, enabled: isAdmin });   // opens by itself while needed
  const steps = [
    { id: "tenant", label: t("Tenant"), title: t("Connect Microsoft"), description: "...", content: <TenantsSection />,
      canNext: connected, onNext: async () => { /* save; a rejected promise keeps the step open */ } },
    { id: "mail", label: t("Email"), title: t("Email (SMTP)"), content: <SmtpForm />, optional: true },
  ];
  return <SetupWizard {...w.props} lang={lang} title={t("Set up Foundry")} subtitle={t("...")} steps={steps}
    success={{ title: t("Setup complete"), text: t("...") }} />;
}

// Einstellungen: open it again (admins only)
<SetupWizardButton lang={lang} />

测试id: setup-wizard, wizard-stepper(-item), wizard-step-{id}, wizard-next, wizard-back, wizard-skip, wizard-close, wizard-error, wizard-success, wizard-done, settings-open-wizard.

双因素卡和许可面板(React)

每个应用程序中都有相同的后端路由,因此应用程序只传递它们的axios实例和一些helper。

import { SecurityFactors, securityApi, LicensePanel, licenseApi } from "@scalio-cloud/ui/react";
import { QRCodeSVG } from "qrcode.react";
import { startRegistration, browserSupportsWebAuthn } from "@simplewebauthn/browser";

const security = securityApi(api, { startRegistration, browserSupportsWebAuthn });   // once, outside the component
const license = licenseApi(api);

// Profile -> Sicherheit: authenticator app, backup codes, passkeys. Hidden for accounts without a password.
<SecurityFactors client={security} lang={lang} product="Scalio Citadel" email={user.email}
  qr={(uri) => <QRCodeSVG value={uri} size={160} />} notify={(text, tone) => toast[tone](text)}
  confirm={confirm} onMfaChange={(on) => setUser({ ...user, mfa_enabled: on })} />

// Einstellungen -> System -> Lizenz (scalio-license backend: /license, /license/addons)
<LicensePanel client={license} lang={lang} product="Citadel" kindLabel={licenseKindLabel}
  featureLabel={licenseFeatureLabel} noFeatures={t("Drift detection only")} notify={...} confirm={confirm} />
// noFeatures only when the app has a better text than «Nur die Grundfunktionen»

securityApi 读取snake_case和camelCase的答案。 notify(text, tone) 得到 "success" 或者 "error";没有它 这些块本身显示信息。 confirm 应用程序的对话框({title, action, danger} - >承诺), window.confirm 否则。 formatError(err) 让应用程序短语API错误(例如许可证限制代码)。有其他路由的license后端传递自己的路由 client 和一个 map(license, {L}) 中描述的视图模型 react/license.js. Nexus做到了这一点:它 map 添加试用徽章,座位提示,无效 附加组件和只读注释(演示模式),并将其试用通知传递为 statusExtra 提醒设置为 children.

从0.27.0 (ADR 0069)开始,面板在设置表单中显示三个区域(左边是标题和提示,右边是卡片) Nutzung»,«Add-ons»,«lizenzschlssel»。 children 与 extraTitle (和 extraHint)成为第四个领域。面板通过其 lang 每一个 client 调用; licenseApi 将其发送为 ?lang=因此,scalio-license 0.4.0以页面语言呈现警告和错误。

Gruppe系统:zur<s:1> cksetzen和helpers (React)

每个应用程序都以相同的顺序显示Einstellungen→System: Lizenz, Updates, Sicherung, zur<s:1> cksetzen ()settingsGroups 对组进行排序 system 这种方式)。重置块与scalio-platform对话 factory_reset (GET/POST /api/admin/factory-reset):

import { FactoryReset, factoryResetApi, SettingsField, SettingsRow } from "@scalio-cloud/ui/react";

const reset = factoryResetApi(api);   // once, outside the component
<FactoryReset client={reset} lang={lang} tokenKey="citadel_token" backupTo="/settings/backup" link={Link} />

SettingsField (标签,字段,帮助)和 SettingsRow (左边是标题和帮助,右边是开关或按钮; tone="danger") 将字段保持在 SettingsSection 每个应用程序都是一样的。

Benachrichtigungen: E-Mail-Versand and E-Mail-Vorlagen (React)

自0.29.0 (ADR 0069 W5)以来,每个应用程序都以相同的方式发送邮件。服务器端是scalio-platform 0.8.0 mail (Mailer.router,安装于 /api/mail). 两个块都进入设置组«Benachrichtigungen»。

import { MailTransport, MailTemplates, mailApi } from "@scalio-cloud/ui/react";
import { RichTextEditor } from "@/components/RichTextEditor";   // optional, the app's own editor (Compass: react-quill-new)

const mail = mailApi(api);   // once, outside the component; mailApi(api, "/admin/mail") for another prefix
<MailTransport client={mail} lang={lang} notify={toast} graphHint={t("...Mail.Send and Mail.ReadWrite...")}>
  <InboxSettings />           {/* optional blocks after «Testmail» */}
</MailTransport>
<MailTemplates client={mail} lang={lang} editor={RichTextEditor} />

MailTransport 显示三个块:«E-Mail-Versand»(关闭,SMTP或Microsoft 365,发件人,语言;秘密回来 作为掩码,掩码原封不动地发送回来),«Testmail»(空收件人:to me)和«Letzte Mails»(outbox={false} 隐藏)。在测试实例中,后端响应 test_mailbox: true 服务器字段被锁定。 MailTemplates 选择邮件和语言,提供占位符作为按钮,显示真实呈现的预览 在沙盒框架中,并保存,测试(«Test an mich»)或重置为内置文本。一个可切换的邮件得到 复选框“已发送的邮件”。这个 editor 得到 {value, onChange, testId};如果没有它,则使用文本字段,因此 包不保留任何依赖项。使用编辑器,普通内置文本作为段落(textToHtml)。

协议:动作和工作(React)

一个菜单项«协议»有两个标签,如Nexus (scalio-docs ADR 0070)。服务器端是规模平台 audit_router 和 jobs_router (0.7.0)。

import { AuditNav, AuditLog, JobsPanel, auditApi, jobsApi } from "@scalio-cloud/ui/react";

const audit = auditApi(api);   // GET /audit, /audit/export.csv
const jobs = jobsApi(api);     // GET /jobs, /jobs/runs, /jobs/queue, POST /jobs/{key}/run, queue actions

<PageHeader title={L.auditLog} nav={<AuditNav link={NavLink} lang={lang} />} />
<AuditLog client={audit} lang={lang} notify={toast} actionLabel={(a, lang) => ACTIONS[lang][a]} tenantLabel="Kunde" />
<JobsPanel client={jobs} lang={lang} notify={toast} canRun={can("jobs.run")} link={Link} confirm={confirm} />
  • AuditLog:注意«unveränderlich»,芯片计数(从服务器的类别),搜索,过滤器的行动, 状态、租户和时间范围、可排序列、列选择器(人员、租户、IP)、具有相同过滤器的CSV、 “Ältere laden”(光标),用“alt→new”查看,手机上的卡片。配件: toolbar, rowActions(entry), renderDetail(entry) (Nexus KI, Citadel PDF, Nexus步骤)。
  • JobsPanel:选项卡Warteschlange(仅当应用程序有一个),Läufe(按作业和状态过滤)和Hintergrundjobs (时间表,最后一次运行,最后的结果,«Jetzt ausf<s:1> hren»与 canRun); 每15秒重新装填一次(pollMs). 配件: queueActions(item, reload), renderQueueDetail(item, reload).
  • AuditNav:标签 /audit 和 /jobs (base 对于另一个前缀, jobs={false} 隐藏工作)。

命令面板(React)

读取与侧边栏相同的导航数据。将其放入布局中;侧边栏搜索按钮打开它。

import { CommandPalette, openCommandPalette, paletteShortcut } from "@scalio-cloud/ui/react";

<Sidebar nav={nav} search={{ onOpen: openCommandPalette, shortcut: paletteShortcut(lang) }} ... />
<CommandPalette nav={nav} activePath={location.pathname} onNavigate={navigate} lang={lang}
  pages={[{ to: "/profile", label: "Profil" }]}
  groups={(query) => [{ id: "ai", label: "KI", order: 10, items: [{ id: "ask", label: `Fragen: ${query}`, onSelect: ask, hidden: !query }] }]} />

页面:每个可见的侧边栏项目加上 pages (每条路径一次),按标签搜索, keywords、截面和路径。 分组排序 order (默认60);最近的页面(50)只在查询为空时显示,页面排在最后(100)。 一个项目有 label, icon, to 或者 onSelect,可选 keywords, hint, tone (primary, danger), testId 和 alwaysShow. 没有 open 面板处理⌘K / Ctrl+K和 openCommandPalette() 本身; 通过 open + onOpenChange 来控制它。 recentKey 设置localStorage键(false:最近没有)。

安装

在npmjs.com上公开,不需要令牌: yarn add @scalio-cloud/ui (固定准确的版本)。 包中只包含SIL OFL下的设计值和字体,没有任何机密。

许可证

设计令牌和预设:(c) Scalio Cloud LLC,可在Scalio应用程序中免费使用。字体:SIL开放字体许可证1.1, 看到 fonts/licenses/. 图标在 react/icons.jsLucide, ISC许可,参见 licenses/lucide-LICENSE.txt.

释放

  1. 更改文件和bump version 在 package.json 无标签;无标签 v)。
  2. 合并 main,然后发布它:在Scalio Dev驾驶舱(在Scalio UI中,“Freigeben”与版本一起)或 在GitHub中(Actions -> publish ->在main上运行工作流,或者自己创建标签/发布)。这个 publish Workflow测试并通过可信发布(无令牌;NPM org)将该版本发布到npmjs.com scalio-cloud,可信发布者Scalio-Cloud / scalio-ui / publish。Yml)和,当由手或从 使用CHANGELOG行创建标签和GitHub发布。变更日志位于scalio-docs中 changelog/scalio-ui/ (ADR 0066):每次更改都会添加一个文件 changelog.d/<name>.md 在那里,在释放a之前 文档公关运行 python3 tools/changelog.py --repo scalio-ui release <version>.
  3. 应用程序更新 yarn upgrade @scalio-cloud/ui@<version> 在他们自己的公关中。

npm test 检查:亮/暗变量匹配,预设只使用定义的变量,所有字体文件存在, 没有从网络中加载任何内容。

版本与发布记录

@scalio-cloud/ui 共发布 40 个版本,首次发布于 2026/10/25;过去 12 个月发布了 40 个版本。

版本发布日期距今
0.29.0latest2026/11/021 天前
0.28.02026/11/021 天前
0.27.12026/11/021 天前
0.27.02026/11/021 天前
0.26.02026/11/021 天前
0.25.12026/11/011 天前

关于 @scalio-cloud/ui 的常见问题

@scalio-cloud/ui 是什么?

Scalio控制室设计令牌,顺风预设,自托管字体,共享的应用程序标题,登录布局,侧边栏和页面块

如何安装 @scalio-cloud/ui?

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

@scalio-cloud/ui 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/scalio-cloud__ui 是否存在。

@scalio-cloud/ui 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@scalio-cloud/ui 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@scalio-cloud/ui 可以商用吗?

@scalio-cloud/ui 使用 SEE LICENSE IN README.md 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@scalio-cloud/ui 还在维护吗?

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