Skip to Content
卡片 SDKUI 套件与样式

UI 套件与样式

在自己的方框内,卡片就是一个普通网页:任何框架、任何 CSS、canvas、WebGL、WebAssembly 都行。设计样式有两种方式:

  • 原生外观——可选的 ui.css 套件:一套基于应用实时主题的小型深色按钮、输入框、列表和徽章。用它做出的卡片看起来就像 NeuroSquad 的一部分,并跟随它的主题。
  • 你自己的设计——不用这个套件。主题变量依然存在,想借用某个颜色时随时可用。

UI 套件

<link rel="stylesheet" href="vendor/ui.css" /> <!-- plain template -->
import '@neurosquad/card-sdk/ui.css' // with a bundler (React template)

在 <body> 上加 class="ns-kit" 即可获得基础排版、背景和滚动条,然后使用这些类:

<body class="ns-kit"> <header class="ns-spread"> <h1 class="ns-title ns-truncate">Test radar</h1> <span class="ns-badge ns-badge--danger">3 failed</span> </header> <ul class="ns-list ns-scroll"> <li class="ns-list-item"><span class="ns-dot ns-dot--danger"></span> checkout › pays</li> <li class="ns-list-item"><span class="ns-dot ns-dot--success"></span> auth › logs in</li> </ul> <label class="ns-field"> <span class="ns-label">Filter</span> <input class="ns-input" placeholder="checkout" /> </label> <div class="ns-row"> <button class="ns-btn ns-btn--primary">Run</button> <button class="ns-btn ns-btn--ghost ns-btn--sm">Clear</button> </div> </body>
分组类名
布局ns-kit、ns-stack(纵向)、ns-row(横向)、ns-spread(两端对齐)、ns-grow、ns-scroll、ns-pad、ns-divider
容器ns-surface、ns-surface--inset、ns-callout、ns-callout--success、ns-callout--danger、ns-empty
文本ns-title、ns-subtitle、ns-muted、ns-small、ns-mono、ns-truncate、ns-kbd、ns-help、ns-error
按钮ns-btn + --primary、--secondary、--outline、--ghost、--danger、--sm、--lg、--icon
表单ns-field、ns-label、ns-input、ns-textarea、ns-select、ns-switch
列表ns-list、ns-list-item
状态ns-badge + --accent、--success、--warning、--danger;ns-dot + 同样的修饰;ns-spinner、ns-progress

在应用之外(浏览器预览中),套件会回退到应用的深色主题,所以预览效果也是正确的。

主题变量

connect() 会把应用的实时主题以 --ns-<token> 变量的形式写到 <html> 上——--ns-background、--ns-surface、--ns-foreground、 --ns-muted、--ns-accent、--ns-success、--ns-warning、--ns-danger,以及它们的 -foreground 和 -soft 变体、--ns-border、 --ns-focus、--ns-field-*、--ns-radius、--ns-font-sans、--ns-font-mono 等(完整列表见主题)。 在你自己的 CSS 中使用它们,卡片就会跟随应用:

:root { color-scheme: dark; } body { margin: 0; background: var(--ns-background, #0b0b0f); color: var(--ns-foreground, #fafafa); font: 13px/1.45 var(--ns-font-sans, system-ui, sans-serif); } .chip { border-radius: calc(var(--ns-radius, 0.5rem) * 2); background: var(--ns-accent-soft); color: var(--ns-accent-soft-foreground); }

如果页面也需要在应用之外渲染,请像上面那样给变量设置回退值。想让你自己的颜色不受影响,请使用 connect({ theme: false }) 连接。

页面的沙箱规则

你的页面从它自己的卡片包中提供,并带有严格的内容安全策略(CSP)。实际上意味着:

  • 不能有内联脚本或 onclick="…" 属性——把代码放进 .js 文件。eval 和 new Function 也被禁止(WebAssembly 允许)。
  • 不能引用外部文件。 脚本、样式、字体和图片都必须在卡片包内;<link href="https://fonts…"> 或 <img src="https://…"> 会被拦截。 data: 和 blob: 图片可以用。远程数据请使用 card.net.fetch,再把图片转成 blob: URL。
  • 内联样式没问题(style="…" 和 <style>)。
  • 使用相对 URL。 页面从 nscard://<id>/<path> 提供;构建时请使用相对资源路径(Vite:base: './',React 模板已配置)。
  • 没有 localStorage、Cookie、alert、弹窗、下载、全屏、摄像头或麦克风。 请使用 card.storage、card.ui.confirm、card.openLink。
  • 页面不能写入剪贴板。 copy/cut 处理函数和 document.execCommand('copy') 不起作用(否则任何卡片都能在一次点击时替换剪贴板)。 请使用 card.copyText;用户自己复制选中文本仍然可以。
  • 不能嵌套框架。 iframe、frame、object 和 embed 元素会被移除。
  • 只能用 blob Worker。 new Worker('worker.js') 在卡片的源中会失败;请先获取脚本,把它包装成 Blob, 再用 new Worker(URL.createObjectURL(blob)) 启动。
  • 永远不要信任 message 事件。 其他卡片可以对你的框架调用 postMessage。

npx @neurosquad/card-sdk validate 会对入口页面中的内联脚本、内联事件处理器和外部文件发出警告。

表单永远不会跳转。 <form> 的 submit 事件会触发,你的处理函数也会运行,但应用会取消提交本身, form.submit() 也什么都不做——卡片页面无法向任何地方提交,也无法重新加载。无论如何,请在处理函数中调用 event.preventDefault(),并用 JavaScript 完成工作。

为画布而设计

  • 大小皆宜。 卡片通常是 400×300,有时会展开铺满屏幕。两种状态都要做得完整:用 card.lifecycle.onExpanded 或 useExpanded() 切换布局。
  • 空状态、加载中、出错。 数据到达之前、没有数据时、调用失败时,都要显示合理的内容。
  • 概览图块就是缩小后的你的卡片。 用 setOverview 持续展示最重要的那一条信息。
  • 没人看时保持安静。 usePaused() 为 true 时停止动画——一块画布上可能有五十张卡片。
  • 标题栏属于应用。 不要在正文里重复卡片名称或关闭按钮;标题栏已经有了。

卡片正文里的一切都属于卡片自己,用户也被如此告知。不要模仿 NeuroSquad 的对话框,也不要在卡片里索要密码和密钥—— 请使用 secret 设置,由应用在它自己的表单中询问。