企业产品设计 · 新资源

Nord 设计系统.

通过房间请求草稿,查看 Nord 的 Therapy 主题令牌和 Web Component 契约:真实的颜色角色、响应式字段尺寸、明确的验证,以及在本地准备的结果。

OpenDesign 指南8 个章节38 条参考条目原始应用指南
01

Nord 设计系统 界面预览

从五种房间容量中选择一项,验证标题,并生成本地请求摘要。

房间申请草稿打开完整示例
对 Nord Therapy 令牌的离线 HTML/CSS 解读;原生 Web Component 集成另行展示。· 实现参考
02

Nord 设计系统 设计参考

Nord 令牌 9.0.4 和当前组件文档。以下数值描述的是默认 Therapy 主题,并非所有 Nordhealth 品牌的主题。公开文档并不授予在 Nordhealth 预期范围之外使用 Nord 的权限。

Therapy 角色值

来源
名称 / 规则值 / 配置用途
--n-color-accent#3559c7 主要操作。
--n-color-text#0c1a3d 主要内容。
--n-color-text-weak#36434a 辅助性文本。
--n-color-background#fafbfb 页面。
--n-color-surface#ffffff 面板。
--n-color-border#d8dee4 分隔线。
--n-color-border-strong#bcc5cc 控件边框。
--n-color-text-error#d24023 错误消息。

间距

来源
名称 / 规则值 / 配置用途
--n-space-xs4px紧密。
--n-space-s8px相关内容。
--n-space-m16px分组。
--n-space-l24px区块。
--n-space-xl36px大号。
--n-space-xxl72px主要。

字体与形状

来源
名称 / 规则值 / 配置用途
--n-font-size-m0.875rem正文。
--n-font-size-l1rem大号文本。
--n-font-size-xl1.25rem区块标题。
--n-font-size-xxl1.5rem标题。
--n-line-height1.5正文缩放系数。
--n-line-height-form20px控件行。
--n-font-weight-heading600标题。
--n-border-radius-s3px控件。
--n-border-radius5px界面表面。

输入控件约定

来源
名称 / 规则值 / 配置用途
label / hint / errorBuilt-in field text独立使用的输入框需自行提供标签。
expandBoolean, default false填满父元素宽度。
sizes / m / l默认中等尺寸。
readonly versus disabledSubmitted versus excluded只读元素仍可获得焦点。
--n-input-inline-size240px默认固定宽度;响应式表单优先使用 expand。

Select 约定

来源
名称 / 规则值 / 配置用途
Default slotNative option elements不要臆造 nord-option。
valueString受控选择。
requiredBoolean使用 novalidate 和应用级错误消息。
changeUser selection event读取 component.value。
focus()Component method等待定义完成后再调用。

按钮约定

来源
名称 / 规则值 / 配置用途
typesubmit by default非提交操作请指定 button。
variantdefault / primary / dashed / plain / danger每个区段只使用一个主按钮。
hrefCreates anchor semantics用于导航。
sizes / m / l默认中等尺寸。
loadingBusy presentation搭配已播报的状态信息使用。
03

Nord 设计系统 完整指南

实用指南,介绍如何为真实界面选择、应用和评审此系统。

DESIGN-nordhealth.md

完整指导、实现起点和源代码链接。

下载指南

Nord 设计系统 Nord 是一套内部产品系统,并提供公开参考资料

明确标示预期用途

Nord 的文档介绍了一套为 Nordhealth 产品体验打造的系统。其可公开查看的组件可作为参考,但本示例并不表示品牌或组件条款允许任意商业复用。此处的房间名称和申请流程均为原创演示数据。

摘自本 OpenDesign 指南

默认令牌表代表 Therapy 主题。兽医或医疗应用应选择其预期使用的主题,而不是假定蓝色强调色适用于 Nordhealth 的所有产品。主题选择应由应用层负责。

阅读配套规范

Nord 设计系统 Therapy 角色让工作区保持克制

区分文本、边框和界面表面角色

该示例使用主要文本角色呈现请求详情,使用次要文本角色呈现说明。白色面板位于米白色页面背景之上;更醒目的边框用于标识可编辑字段。错误文本显示在无效标题旁,而不是让整个界面泛红。预览中不包含任何临床或患者信息。

阅读配套规范

Nord 设计系统 紧凑文本需要足够的行距

将文档规定的字号与行高搭配使用

该令牌将 0.875rem 的正文字号与 1.5 的正文行高配对使用,而表单文本则采用独立的 20px 行框。这是两套不同的规则:将表单的数值用于长段落会造成不必要的压缩。在线参考使用 Nordhealth Sans 字体系列令牌;此离线演绎稿特意使用可用的系统字体,不会暗示已提供授权字体。

阅读配套规范

Nord 设计系统 在应用网格中扩展控件

组件不会决定页面断点

Input 的初始内联尺寸变量为 240px。文档规定使用 expand 来占据可用的字段列。我们的示例在桌面端将房间列表放在编辑器旁,在移动端则改为纵向排列;断点由应用决定,并非 Nord 令牌的一部分。选中某一行时,房间名称、容量和可用状态标签仍会显示。

离线演绎稿中的房间列表使用原生单选按钮组。单独提供的库示例使用包含五个选项的 Select。两者都用于选择一个房间,但展示的是不同布局,不能视为相同的组件运行时实现。

阅读配套规范

Nord 设计系统 为标签和错误消息各指定一个负责人

此表单使用独立字段就已足够

Input 或 Select 可以自行提供标签、提示和错误信息。使用较新的 Field 组合模式时,这些职责会由 Field 接管,因此同时重复配置两套内容会产生冗余说明。此示例采用独立组件方案,并在去除首尾空格后的标题为空时设置一条简短错误信息。

禁用字段不会随表单提交,而只读字段会保留相关值,以便聚焦和提交。如果房间标识仍需随请求一并提交,就不要仅为禁止编辑而将其禁用。

  • 确保请求标题标签始终可见。
  • 提示信息应说明预期内容,不要用它代替标签。
  • 将验证消息与无效控件关联起来。

阅读配套规范

Nord 设计系统 Select 包含普通的 option 元素

从宿主组件读取值

默认插槽接受原生 option 元素。每个房间都有稳定的值,以及包含其容量的描述性可见标签。change 事件会通知应用根据宿主组件的值重新计算摘要。此组合中没有自定义的 nord-option 标签。

Nord 建议在选项较多时使用 Select;如果直接展示少量选项很有帮助,则建议使用单选按钮。示例提供五个房间;离线单选按钮样式让容量差异一目了然。

阅读配套规范

Nord 设计系统 Button 默认行为会影响表单组合

明确指定操作、链接和加载状态的语义

Nord Button 的默认类型为 type="submit"。因此,如果表单中的次要预览或类似重置的操作不应提交表单,就需要显式指定 type。为组件设置 href 会将其语义改为链接;导航时应使用这种方式,而不是用点击处理程序模拟锚点。

加载状态会让按钮保持可聚焦,同时阻止重复激活。其旋转指示器对辅助技术隐藏,因此应用必须用文字说明进度。不要一概改用 disabled:操作不可用与操作正在执行,对焦点和反馈的需求不同。

房间请求示例会同步计算草稿,因此不需要加载时段。主按钮会验证标题并读取所选房间;修改任一项都会移除过时的草稿句子。上方的字段和 Select 部分说明了由哪些 Nord API 负责这些输入项。

阅读配套规范

Nord 设计系统 调用组件方法前,先加载所需的 CSS

原型加载与生产环境打包有所不同

官方快速入门将组件模块与 CSS 框架搭配使用。后者提供共享令牌和基础样式。对于经过打包的应用,请安装 @nordhealth/css 和 @nordhealth/components,导入一次 CSS,并且只导入实际使用的组件模块。软件包模块会通过副作用注册其自定义元素。

React 19 可以直接使用这些自定义元素。根据当前指南,较旧的 @nordhealth/react 封装已弃用。服务器端渲染不包含组件的 Shadow DOM;在 Next.js 中导入时需要设置客户端边界。请将这些集成限制与离线 HTML 预览区分开来,后者无需该库即可运行交互。

  1. 先加载框架 CSS,再加载组件模块。
  2. 初始化时调用 focus 前,先等待 customElements.whenDefined。
  3. 添加验证和本地状态处理程序。
  4. 在生产环境中打包依赖,不要依赖大量 CDN 模块请求。

阅读配套规范

Nord 设计系统组件示例

完整的独立交互示例

将完整文档保存为 index.html 并在浏览器中打开。这是对 Nord Therapy 设计令牌的离线 HTML/CSS 演绎;原生 Web Component 集成将在另一处展示。

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Nord room request interpretation</title><style>*{box-sizing:border-box}body{margin:0;background:#fafbfb;color:#0c1a3d;font:14px/1.5 system-ui,sans-serif}button,input{font:inherit}header{height:52px;background:white;border-bottom:1px solid #d8dee4;padding:0 24px;display:flex;align-items:center;justify-content:space-between}header small{color:#36434a}main{max-width:960px;margin:36px auto;padding:0 24px}h1{font-size:24px;line-height:1.2;margin:0 0 8px}h2{font-size:20px;line-height:1.2;margin:0 0 16px}p{margin:0 0 24px}.muted{color:#36434a}.layout{display:grid;grid-template-columns:310px 1fr;gap:24px}.panel{background:white;border:1px solid #d8dee4;border-radius:5px;padding:24px}fieldset{margin:0;padding:0;border:0;min-width:0}legend{font-weight:600;margin-bottom:16px}.room{display:flex;gap:12px;padding:12px;border:1px solid #d8dee4;border-radius:3px;margin-bottom:8px;cursor:pointer;align-items:center}.room:has(:checked){border-color:#3559c7;background:#f0f4ff}.room input{accent-color:#3559c7}.room span{flex:1}.room small{display:block;color:#36434a}.room b{font-size:12px;font-weight:500}.diagram{height:120px;background:#f6f8f8;display:grid;place-items:center;margin:-24px -24px 24px;border-radius:5px 5px 0 0;border-bottom:1px solid #d8dee4}.table{height:50px;border:2px solid #bcc5cc;border-radius:5px;background:#fff;position:relative;transition:width .2s ease}.chair{position:absolute;width:12px;height:10px;border:1px solid #bcc5cc;background:white;border-radius:3px;top:-16px}.chair.bottom{top:auto;bottom:-16px}label.field{display:block;font-weight:600;margin:16px 0 8px}#title{width:100%;border:1px solid #bcc5cc;border-radius:3px;height:36px;padding:7px 12px;color:inherit;background:white}#title[aria-invalid=true]{border-color:#d24023}.error{color:#d24023;min-height:20px;font-size:12px;margin:4px 0 12px}button{background:#3559c7;color:white;border:1px solid transparent;box-shadow:0 1px 3px #0c0c0c17;border-radius:3px;padding:7px 16px;cursor:pointer}button:focus-visible,input:focus-visible{outline:2px solid #3559c7;outline-offset:3px}.summary{margin-top:24px;background:#f0f4ff;border:1px solid #c6d4f9;padding:16px;border-radius:5px;overflow-wrap:anywhere}.summary:empty{display:none}.boundary{font-size:12px;color:#36434a;margin-top:24px}#selected{font-weight:600}.facts{display:flex;gap:24px;margin-bottom:24px}.facts strong{font-size:20px;display:block}.facts span{font-size:12px;color:#36434a}@media(max-width:650px){main{margin:24px auto;padding:0 16px}.layout{grid-template-columns:1fr;gap:16px}.panel{padding:16px}.diagram{margin:-16px -16px 16px}.room{padding:8px 12px}header{padding:0 16px}header small{display:none}}</style><header><strong>◈ Workplace</strong><small>Room request workspace</small></header><main><h1>A room for your next conversation</h1><p class="muted">Choose a room and prepare a request draft.</p><div class="layout"><section class="panel"><fieldset><legend>Choose a room</legend><div id="rooms"></div></fieldset></section><section class="panel"><div class="diagram" aria-hidden="true"><div class="table" id="table"></div></div><h2 id="selected">Birch</h2><div class="facts"><div><strong id="capacity">4</strong><span>Seats</span></div><div><strong>Draft</strong><span>Request status</span></div></div><form novalidate><label class="field" for="title">Request title</label><input id="title" type="text" aria-describedby="hint error" placeholder="e.g. Design review"><div id="error" class="error" role="alert"></div><p id="hint" class="muted">Use a non-sensitive meeting title. Availability is not checked in this example.</p><button type="submit">Prepare request</button></form><div class="summary" id="result" role="status"></div></section></div><p class="boundary">Independent HTML interpretation of Nord Therapy tokens. Nord is intended for Nordhealth products. This example creates a local draft only; it does not reserve a room.</p></main><script>const rooms=[['Birch',4],['Cedar',6],['Elm',8],['Maple',10],['Pine',12]],field=document.querySelector('#title'),result=document.querySelector('#result');let selected=0;document.querySelector('#rooms').innerHTML=rooms.map(([name,n],i)=>`<label class="room"><input type="radio" name="room" value="${i}" ${i===0?'checked':''}><span>${name}<small>Meeting room</small></span><b>${n} seats</b></label>`).join('');function update(){let [name,n]=rooms[selected];document.querySelector('#selected').textContent=name;document.querySelector('#capacity').textContent=n;let table=document.querySelector('#table');table.style.width=(n*12+44)+'px';table.innerHTML=Array.from({length:n},(_,i)=>`<i class="chair ${i>=n/2?'bottom':''}" style="left:${12+(i%(n/2))*24}px"></i>`).join('');result.textContent=''}document.querySelectorAll('[name=room]').forEach(input=>input.onchange=()=>{selected=Number(input.value);update()});document.querySelector('form').onsubmit=e=>{e.preventDefault();if(!field.value.trim()){document.querySelector('#error').textContent='Enter a request title.';field.setAttribute('aria-invalid','true');field.focus();return}result.textContent='Draft prepared: '+field.value.trim()+' · '+rooms[selected][0]+' · '+rooms[selected][1]+' seats. No room is reserved.'};field.oninput=()=>{field.removeAttribute('aria-invalid');document.querySelector('#error').textContent='';result.textContent=''};update();</script></html>

代码参考

  • 此示例将房间选项呈现为单选按钮;原生 Nord 示例使用带有普通 option 元素的 Select。两者都不会预留真实房间。

带明确验证的房间申请表

独立的 nord-input 和 nord-select 无需可选的 Field 系列组件即可提供标签。提交时会读取组件值,并设置 Input 的 error 属性。

html
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Room request draft</title>
<link rel="stylesheet" href="https://nordcdn.net/ds/css/5.2.4/nord.min.css">
<script type="module" src="https://nordcdn.net/ds/components/5.3.0/index.js"></script>
<style>main{max-width:560px;margin:auto;padding:var(--n-space-l)}form{display:grid;gap:var(--n-space-l)}</style>
<main><h1>Prepare a room request</h1><p>For an authorized Nordhealth product. Local demonstration only.</p>
<form novalidate>
<nord-input id="request" name="request" label="Request title" hint="Use a non-sensitive meeting title." required expand></nord-input>
<nord-select id="room" name="room" label="Room" value="Birch" expand>
<option value="Birch">Birch · 4 seats</option><option value="Cedar">Cedar · 6 seats</option>
<option value="Elm">Elm · 8 seats</option><option value="Maple">Maple · 10 seats</option><option value="Pine">Pine · 12 seats</option>
</nord-select>
<nord-button type="submit" variant="primary">Prepare request</nord-button>
</form><p id="result" role="status"></p></main>
<script type="module">
await Promise.all(['nord-input','nord-select','nord-button'].map(name=>customElements.whenDefined(name)));
const form=document.querySelector('form'), title=document.querySelector('#request'),room=document.querySelector('#room'),result=document.querySelector('#result');
form.addEventListener('submit',event=>{
 event.preventDefault();title.error=title.value.trim()?'':'Enter a request title.';
 if(title.error){title.focus();return;}
 result.textContent=`Draft: ${title.value.trim()} in ${room.value}. No room is reserved.`;
});
form.addEventListener('input',()=>{result.textContent='';title.error='';});
form.addEventListener('change',()=>{result.textContent='';});
</script></html>

代码参考

  • 五个房间选项让 Select 成为紧凑实用的选择方式。
  • Button 的默认类型为 submit;此示例显式指定了该类型。
  • 使用方法前会先等待自定义元素就绪。不会调用任何预订服务。
04

Nord 设计系统 Agent 设置

实现起点

供获授权的 Nordhealth 用途使用的完整公共 CDN 原型。文档目前指定使用 CSS 5.2.4 和组件 5.3.0。生产环境应打包 npm packages;以下离线视觉演示不会加载这些远程包。

html
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Room request draft</title>
<link rel="stylesheet" href="https://nordcdn.net/ds/css/5.2.4/nord.min.css">
<script type="module" src="https://nordcdn.net/ds/components/5.3.0/index.js"></script>
<style>main{max-width:560px;margin:auto;padding:var(--n-space-l)}form{display:grid;gap:var(--n-space-l)}</style>
<main><h1>Prepare a room request</h1><p>For an authorized Nordhealth product. Local demonstration only.</p>
<form novalidate>
<nord-input id="request" name="request" label="Request title" hint="Use a non-sensitive meeting title." required expand></nord-input>
<nord-select id="room" name="room" label="Room" value="Birch" expand>
<option value="Birch">Birch · 4 seats</option><option value="Cedar">Cedar · 6 seats</option>
<option value="Elm">Elm · 8 seats</option><option value="Maple">Maple · 10 seats</option><option value="Pine">Pine · 12 seats</option>
</nord-select>
<nord-button type="submit" variant="primary">Prepare request</nord-button>
</form><p id="result" role="status"></p></main>
<script type="module">
await Promise.all(['nord-input','nord-select','nord-button'].map(name=>customElements.whenDefined(name)));
const form=document.querySelector('form'), title=document.querySelector('#request'),room=document.querySelector('#room'),result=document.querySelector('#result');
form.addEventListener('submit',event=>{
 event.preventDefault();title.error=title.value.trim()?'':'Enter a request title.';
 if(title.error){title.focus();return;}
 result.textContent=`Draft: ${title.value.trim()} in ${room.value}. No room is reserved.`;
});
form.addEventListener('input',()=>{result.textContent='';title.error='';});
form.addEventListener('change',()=>{result.textContent='';});
</script></html>

适用于你项目的提示词

Agent 提示词
使用 Nord Therapy 语义角色和带标签的控件。在响应式应用布局中展开字段。验证去除首尾空格后的请求标题,保留单个选定房间,并且仅显示本地草稿结果。实际实现 Nordhealth 产品时,请遵循文档所述的软件包和主题使用权限。
05

Nord 设计系统 来源与范围

独立的 OpenDesign 参考。Nord 表示其预期用途是 Nordhealth 产品。本原创的 HTML 演绎既不会预订房间,也不授予品牌或组件的使用权。