无头组件系统 · 新资源

Oruga UI 设计系统.

原生 Oruga 目录编辑器,支持搜索和移除主题标签、强制执行词汇限制、使用可选主题的真实令牌,并通过实时卡片呈现所选标签。

OpenDesign 指南9 个章节25 条参考条目原始应用指南
01

Oruga UI 设计系统界面预览

搜索受控词汇表,最多添加三个主题,移除标签,并保存本地笔记说明。

研究笔记目录打开完整示例
@oruga-ui/oruga-next 0.14.4 搭配 @oruga-ui/theme-oruga 0.10.0 和本地 MDI 图标。· 实现参考
02

Oruga UI 设计系统设计参考

Oruga Vue 3 程序包 0.14.4 搭配 @oruga-ui/theme-oruga 0.10.0。下方的值属于该可选默认主题,并非不可变的无头核心。MDI 7.4.47 图标由本地提供。周边的目录布局和文件夹插画均为原创。

Oruga 可选主题的语义颜色

来源
名称 / 规则值 / 配置用途
--oruga-primary#445e00 选中的标签和主要操作。
--oruga-primary-invert#fff主要标签上的文字。
--oruga-success#006724 成功状态变体。
--oruga-info#005c98 信息状态变体。
--oruga-warning#f4c300 警告状态变体。
--oruga-danger#b60000 字段错误状态变体。
--oruga-control-border-color#dbdbdb 默认字段边界。

可选主题的字体、间距和几何属性

来源
名称 / 规则值 / 配置用途
--oruga-font-size1rem默认文字大小。
--oruga-line-height1.5默认行高比例。
--oruga-border-radius4px标准控件圆角。
--oruga-control-spacer.5em通用控件间距。
--oruga-control-height2.25em控件高度相对于字体的比例。
--oruga-control-padding-verticalcalc(.375em - 1px)计入边框后的垂直内边距。
--oruga-control-padding-horizontalcalc(.8em - 1px)计入边框后的水平内边距。
--oruga-control-disabled-opacity.5禁用状态的视觉样式。
--oruga-animation-speed-fast.15s快速过渡时长。
--oruga-animation-speed.3s标准过渡时长。

明确设定的原创应用比例

来源
名称 / 规则值 / 配置用途
Font stacksystem-ui, sans-serif应用外围文字;可选主题也使用平台字体栈。
Page title34px / 1.15; 29px narrow原始层级。
Catalog card titleGeorgia, serif; 29px / 1.25原创的编辑风格对比度,并非 Oruga 默认值。
Supporting type10 / 11 / 12 / 13 / 14 / 15px明确设定的原创说明文字、定义和文案。
Spacing4 / 5 / 7 / 12 / 13 / 14 / 16 / 20 / 22 / 24 / 28 / 32px实际布局数值;无头库不提供网格比例。
LayoutFlexible editor + 330px catalog card; stack at 760px原始网格。
Topic constraints1–3 unique existing labelsallow-new=false,allow-duplicates=false,maxitems=3。
Title constraint5–80 characters; minimum evaluated after trim应用层验证加原生长度限制。
03

Oruga UI 设计系统完整指南

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

DESIGN-oruga-ui.md

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

下载指南

Oruga UI 设计系统:将 Oruga 组件行为与可选主题分开

将 Oruga 组件行为与可选主题分开

Oruga 提供 Vue 组件,但不要求使用特定的 CSS 框架。此示例将 Vue 3 软件包与独立的 Oruga 默认主题搭配使用。选中的绿色标签和描边输入框来自该主题,而搜索、选择和移除则是组件的原生行为。

摘自本 OpenDesign 指南

评估这个库时,了解这一区分很有帮助。团队可以保留组件 API,并替换类配置,或选择其他受支持的主题。因此,参考表列出主题软件包及其版本,而不是把绿色主色描述成每个 Oruga 应用都必须采用的配色。

阅读配套规范

Oruga UI 设计系统 使用默认主题的实际变量

使用默认主题的实际变量

已安装的可选主题将 --oruga-primary 定义为 #445e00,将 --oruga-primary-invert 定义为白色。危险色为 #b60000,控件边框使用 #dbdbdb。组件的 variant 属性会选择相应的语义色系,无需为每个输入框或标签单独编写 CSS 规则。

同一主题还定义了 4 像素的标准圆角、2.25em 的控件高度,以及减去 1 像素边框的内边距公式。由于这些值相对于控件文字计算,调整字体缩放会影响几何尺寸。主题中的半 em 间距值用于组件之间的关系,并不意味着它提供了完整的页面布局间距比例。

阅读配套规范

Oruga UI 设计系统 补充 Oruga 有意不规定的布局

自行提供 Oruga 有意不设定的布局

目录采用灵活的编辑器列和 330px 的卡片列,并在视口宽度低于 760px 时改为堆叠布局。页面标题使用系统无衬线字体,卡片标题则使用 Georgia,营造编辑记录的风格。这两种选择均为自定义,无需外部字体文件。

Oruga 不规定网格或工具类框架。因此,完整的样式表会明确展示面板内边距、小屏幕内缩值和换行规则。标签计数器会让分子和分母保持在一起;卡片标题也允许较长的笔记名称换行,避免内嵌页面被横向挤开。

阅读配套规范

Oruga UI 设计系统 将已选值与搜索查询分开

将选中值与搜索查询分开保存

OTaginput 通过 v-model 绑定已选主题数组。其内部自动补全文本用于筛选候选标签,不会替换该数组。词汇表包含六个自定义主题及其具体定义,实时卡片则只会重复显示已选主题的定义。

默认搜索比较不区分大小写。本地测试输入 Color 后,会等待筛选完成,再选择匹配的选项。如果在输入防抖期间立即断言,就会误以为筛选失败。选择后,查询会清空,同时保留此前选中的标签。

  1. 搜索 Color,并选择匹配的选项。
  2. 添加 Forms,使主题数达到三个(包括 Navigation)。
  3. 移除一个标签,确认卡片随之更新,然后选择替代标签再保存。

阅读配套规范

Oruga UI 设计系统 分别控制词汇表、重复项和计数

分别控制词汇表、重复项和数量

allow-new=false 可防止任意输入的短语成为标签。allow-duplicates=false 可防止同一个现有标签被重复添加。maxitems=3 会限制已选项总数,并显示计数器。每项设置保护的内容各不相同,共同确保词汇表受到控制。

应用仍会在尝试保存时检查是否至少选择了一个主题。设置最大选择数量并不意味着存在最低要求。此外,应用会检查去除首尾空格后的标题是否包含五个有意义的字符,而原生输入框的 maxlength 则将上限限制为 80 个字符。

阅读配套规范

Oruga UI 设计系统 使用 OField 显示标签和具体的验证消息

使用 OField 显示标签和具体的验证消息

OField 用于显示“笔记标题”和“主题”标签及其提示信息。尝试保存无效内容后,相应字段会采用危险样式,并显示具体的修正提示。主题说明会在发生错误前,解释可选范围和词汇表限制。

原生标签输入框的下拉菜单遵循 combobox/listbox 模式。在此版本中,combobox 角色属于一个包装元素,可编辑的文本框则嵌套在其中。因此,QA 会直接填写名为“搜索主题”的实际输入框,而不会假定带有 combobox 角色的元素本身就是输入框。

阅读配套规范

Oruga UI 设计系统 默认图标包仍需加载字体资源

即使使用默认图标包,也仍需提供字体资源

标签的移除控件使用 Oruga 默认的 MDI 图标包。加载组件主题并不会自动加载该字体,因此完整配置还包括 @mdi/font。独立预览使用本地 WOFF2 资源和必需的图标规则,避免依赖远程字体。

移除控件仍是真正的按钮,并带有可供辅助技术识别的“移除主题”标签。装饰性的文件夹插画与这些控件图标无关,因此会对辅助技术隐藏。这样可以避免装饰图案被误认为可操作控件。

阅读配套规范

Oruga UI 设计系统 输入发生变化时,使已保存的快照失效

输入项发生变化时,使已保存的快照失效

保存操作会记录一条句子,其中包含经过修剪的标题和已选主题数量。一个 watcher 会深度监听标题和主题数组;因此,即使只是移除数组中的一项,也会像修改标题一样清除保存确认状态。只有当前快照仍处于已保存状态时,保存按钮才会禁用。

“清除笔记”会重置标题、所有已选主题、已尝试验证的状态以及保存状态。此时卡片会显示“未命名研究笔记”和“未选择主题”。用户无需依赖后端,也不会在按钮背后触发上传或发布操作,就能体验从清空、编辑到保存的完整流程。

  • 查询变化时,保留已选数组模型。
  • 嵌套数组发生变化时,清除保存反馈。
  • 将结果描述为本地状态,而非发布。

阅读配套规范

Oruga UI 设计系统 按照当前 Oruga 注册方式显式导入组件

按照当前 Oruga 注册方式显式导入组件

经验证的 0.14.4 配置会创建 Oruga 实例,并将其安装到 Vue 应用中。App.vue 会显式导入 OField、OInput、OTaginput、OTag 和 OButton。这符合当前的注册方式;如果依赖假定所有组件都已全局注册的旧示例,应用可能会缺少组件。

主题 README 说明,此默认主题使用 Oruga 现有的类名,并且需要其样式表,无需额外的主题配置对象。入口文件依次导入该样式表、MDI 资源和原始布局。上方的完整源码示例和下方的 Vite 根目录包含所有必需内容。

阅读配套规范

Oruga UI 设计系统组件示例

完整的主题目录 SFC

OTaginput、OField、OInput、OTag 和 OButton 将受限词汇表与实时目录卡片连接起来。

vue
<script setup>
import {ref,computed,watch} from 'vue';
import {OField,OInput,OTaginput,OButton,OTag} from '@oruga-ui/oruga-next';
const title=ref('Finding a calmer navigation'),topics=ref(['Navigation']),attempted=ref(false),saved=ref('');
const definitions={'Navigation':'Menus, wayfinding and the path through a product.','Typography':'Type hierarchy, reading rhythm and legibility.','Color':'Semantic roles, contrast and theme behavior.','Forms':'Input labels, validation and correction.','Motion':'Transitions, reduced motion and continuity.','Accessibility':'Keyboard flow, semantics and assistive technology.'};
const options=Object.keys(definitions),valid=computed(()=>title.value.trim().length>=5&&topics.value.length>=1&&topics.value.length<=3);
watch([title,topics],()=>saved.value='',{deep:true});
function save(){attempted.value=true;if(valid.value)saved.value=`Saved locally: “${title.value.trim()}” with ${topics.value.length} ${topics.value.length===1?'topic':'topics'}.`}
function reset(){title.value='';topics.value=[];attempted.value=false;saved.value=''}
</script>
<template><main class="catalog-shell"><header><p class="eyebrow">RESEARCH CATALOG · LABEL A NOTE</p><h1>Give the next reader a useful starting point.</h1><p>Name a research note and choose up to three topics from a controlled vocabulary.</p></header><div class="catalog-layout"><section class="editor"><h2>Note details</h2><OField label="Note title" :variant="attempted&&title.trim().length<5?'danger':undefined" :message="attempted&&title.trim().length<5?'Use at least five meaningful characters.':undefined"><OInput v-model="title" maxlength="80" expanded placeholder="What did you learn?"/></OField><OField label="Topics" :variant="attempted&&!topics.length?'danger':undefined" :message="attempted&&!topics.length?'Choose at least one topic.':'Choose 1–3 existing topics; duplicate and new labels are not added.'"><OTaginput v-model="topics" :options="options" :allow-new="false" :allow-duplicates="false" :maxitems="3" open-on-focus :keep-open="false" expanded variant="primary" placeholder="Search topics" aria-close-label="Remove topic"><template #empty>No matching topic. Try Color, Forms or Motion.</template></OTaginput></OField><div class="actions"><OButton variant="primary" @click="save" :disabled="!!saved">Save local note</OButton><OButton @click="reset">Clear note</OButton></div><p role="status" class="result">{{saved||'The preview keeps only local page state.'}}</p><h3>Vocabulary guide</h3><dl class="vocabulary"><div v-for="(meaning,name) in definitions" :key="name"><dt>{{name}}</dt><dd>{{meaning}}</dd></div></dl></section><aside class="note-card"><div class="folder-art" aria-hidden="true"><i></i><b></b><span></span></div><p class="eyebrow">CATALOG CARD PREVIEW</p><h2>{{title.trim()||'Untitled research note'}}</h2><div class="topic-tags"><OTag v-for="topic in topics" :key="topic" variant="primary">{{topic}}</OTag><span v-if="!topics.length" class="empty-topics">No topics selected</span></div><p class="card-label">This note will appear under</p><ul><li v-for="topic in topics" :key="topic"><strong>{{topic}}</strong><span>{{definitions[topic]}}</span></li></ul><p class="card-foot">Original sample note · no upload or publishing</p></aside></div></main></template>

代码参考

  • 选中项数组模型与内部搜索文本不同。
  • 只能选择现有标签,且不能重复。
  • 深度侦听器会在移除主题后清除已保存的确认状态。

完整的原始目录布局

响应式编辑器/卡片网格、受控换行和原创的 CSS 文件夹插图。

css
html,body,#app{height:auto;min-height:0;margin:0}*{box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#f4f4ed;color:#34392b}.catalog-shell{max-width:1100px;margin:auto;padding:32px}.eyebrow{font-size:10px;letter-spacing:.14em;font-weight:700;color:#6e775f}h1{font-size:34px;line-height:1.15;max-width:700px;margin:12px 0}header>p:last-child{font-size:15px;line-height:1.6;color:#727965;max-width:630px}.catalog-layout{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:24px;margin-top:28px}.editor,.note-card{background:white;border:1px solid #dfe3d4;border-radius:14px;padding:24px;min-width:0}.editor>h2{font-size:20px;margin:0 0 24px}.editor .o-field{margin-bottom:22px}.editor .o-field__message{font-size:12px;line-height:1.6}.actions{display:flex;gap:12px;flex-wrap:wrap}.result{font-size:12px;line-height:1.6;color:#596d2e;margin:16px 0 28px}.editor h3{font-size:14px}.vocabulary{margin:0}.vocabulary>div{padding:12px 0;border-bottom:1px solid #eaede3}.vocabulary dt{font-size:13px;font-weight:650}.vocabulary dd{font-size:12px;line-height:1.6;margin:4px 0 0;color:#707763}.note-card{align-self:start;background:#fcfcf5}.note-card h2{font-family:Georgia,serif;font-size:29px;line-height:1.25;font-weight:400;overflow-wrap:anywhere}.folder-art{height:145px;background:#e3e8cf;border-radius:8px;position:relative;overflow:hidden;margin-bottom:24px}.folder-art i{position:absolute;left:15%;top:40px;width:70%;height:100px;border-radius:7px;background:#7e8e52;transform:rotate(-8deg)}.folder-art b{position:absolute;left:21%;top:24px;width:60%;height:115px;background:#fffef5;transform:rotate(5deg);border-radius:4px}.folder-art span{position:absolute;left:16%;top:71px;width:70%;height:80px;background:#a6b57a;border-radius:7px}.topic-tags{display:flex;gap:7px;flex-wrap:wrap}.card-label{font-size:11px;color:#737b65;margin-top:24px}.note-card ul{list-style:none;padding:0}.note-card li{border-top:1px solid #e0e4d6;padding:13px 0}.note-card li strong{font-size:13px;display:block}.note-card li span{font-size:12px;color:#6c765b;line-height:1.6;display:block;margin-top:5px}.card-foot{font-size:10px;line-height:1.6;color:#7c846e;margin-top:20px}.empty-topics{font-size:12px;color:#7c846e}.o-taginput{max-width:100%}.o-taginput__container{min-width:0}.o-taginput .o-input{min-width:0}@media(max-width:760px){.catalog-layout{grid-template-columns:minmax(0,1fr)}.catalog-shell{padding:20px}h1{font-size:29px}}@media(max-width:360px){.catalog-shell{padding:14px}.editor,.note-card{padding:16px}.actions>*{width:100%}}
.o-taginput__counter{white-space:nowrap;flex-shrink:0}

代码参考

  • Oruga 不提供必需的网格系统;此布局由应用程序 CSS 明确实现。
  • 窄屏下计数文本保持单行显示。
04

Oruga UI 设计系统 Agent 设置

实现起点

已验证 Oruga 0.14.4、可选的默认主题 0.10.0 和 MDI 7.4.47。组件均显式导入;默认主题无需额外的 JavaScript 主题配置。

javascript
// npm create vite@latest oruga-catalog -- --template vue
// cd oruga-catalog && npm install
// npm install @oruga-ui/[email protected] @oruga-ui/[email protected] @mdi/[email protected]
// Save the complete examples as src/App.vue and src/style.css.
// src/main.js:
import {createApp} from 'vue';
import {createOruga} from '@oruga-ui/oruga-next';
import '@oruga-ui/theme-oruga/style.css';
import '@mdi/font/css/materialdesignicons.css';
import './style.css';
import App from './App.vue';
createApp(App).use(createOruga()).mount('#app');
// index.html: <div id="app"></div><script type="module" src="/src/main.js"></script>
// npm run dev

适用于你项目的提示词

Agent 提示词
从 Oruga 0.14.4 研究笔记目录及其 0.10.0 主题开始。保留 OTaginput 对六个主题词汇的受控选择、大小写不敏感的搜索、禁用新标签和重复标签,以及最多三个标签的限制。将实时主题定义和标题验证与已保存的快照关联起来,并在内容更改后清除已保存的反馈。包含 createOruga、主题 CSS 和本地 MDI 资源设置。重置为空白草稿;不要虚构产品对比数据或远程目录更新。
05

Oruga UI 设计系统来源与范围

Oruga 0.14.4,搭配可选的默认主题 0.10.0。原创词汇表和目录插图。保存更改仅影响本地页面状态,不会上传、发布,也不会在重新加载后保留。