niuma-ui 1.3.7 → 1.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -56,6 +56,7 @@ var RsTerminal_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
56
56
  type: Boolean,
57
57
  default: false
58
58
  },
59
+ extraContextMenuItems: { default: () => [] },
59
60
  rightClickSelectsWord: {
60
61
  type: Boolean,
61
62
  default: true
@@ -94,7 +95,8 @@ var RsTerminal_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
94
95
  "resize",
95
96
  "action",
96
97
  "askAi",
97
- "selectionChange"
98
+ "selectionChange",
99
+ "extraSelect"
98
100
  ],
99
101
  setup(__props, { expose: __expose, emit: __emit }) {
100
102
  const props = __props;
@@ -177,6 +179,11 @@ var RsTerminal_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
177
179
  icon: "bot",
178
180
  disabled: !hasSelection.value && !menuSelectionSnapshot.value
179
181
  });
182
+ if (props.extraContextMenuItems?.length) items.push({
183
+ key: "sep-extra",
184
+ label: "",
185
+ separator: true
186
+ }, ...props.extraContextMenuItems);
180
187
  items.push({
181
188
  key: "sep-1",
182
189
  label: "",
@@ -438,8 +445,20 @@ var RsTerminal_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
438
445
  emit("action", "askAi");
439
446
  }
440
447
  }
448
+ const BUILTIN_TERMINAL_ACTIONS = /* @__PURE__ */ new Set([
449
+ "copy",
450
+ "paste",
451
+ "selectAll",
452
+ "clear",
453
+ "askAi",
454
+ "search"
455
+ ]);
441
456
  function onContextMenuSelect(key) {
442
- runTerminalAction(key);
457
+ if (BUILTIN_TERMINAL_ACTIONS.has(key)) {
458
+ runTerminalAction(key);
459
+ return;
460
+ }
461
+ emit("extraSelect", key);
443
462
  }
444
463
  function attachShortcuts() {
445
464
  if (!terminal) return;
@@ -3,6 +3,6 @@ import _plugin_vue_export_helper_default from "../_virtual/_plugin-vue_export-he
3
3
  import RsTerminal_vue_vue_type_script_setup_true_lang_default from "./RsTerminal.impl.js";
4
4
 
5
5
  //#region src/components/RsTerminal.vue
6
- var RsTerminal_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsTerminal_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-db06bdc1"]]);
6
+ var RsTerminal_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsTerminal_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-27605f60"]]);
7
7
  //#endregion
8
8
  export { RsTerminal_default as default };
@@ -0,0 +1,26 @@
1
+ export interface RsAnchorItem {
2
+ href: string;
3
+ title: string;
4
+ children?: RsAnchorItem[];
5
+ }
6
+ export interface RsAnchorFlatItem {
7
+ href: string;
8
+ title: string;
9
+ depth: number;
10
+ }
11
+ /** `#overview` / `path#overview` → `overview` */
12
+ export declare function hrefToAnchorId(href: string): string;
13
+ export declare function flattenAnchorItems(items: RsAnchorItem[], depth?: number): RsAnchorFlatItem[];
14
+ /**
15
+ * 滚动监听:取最后一个 top <= offset 的标题。
16
+ * entries 须按文档顺序(与 DOM 一致),top 为相对滚动容器顶部的距离。
17
+ */
18
+ export declare function pickActiveAnchorHref(entries: ReadonlyArray<{
19
+ href: string;
20
+ top: number;
21
+ }>, offset: number): string;
22
+ export declare function resolveAnchorContainer(getContainer?: () => HTMLElement | Window | null | undefined): HTMLElement | Window;
23
+ export declare function readContainerScrollTop(container: HTMLElement | Window): number;
24
+ export declare function targetTopInContainer(target: HTMLElement, container: HTMLElement | Window): number;
25
+ export declare function scrollContainerTo(container: HTMLElement | Window, top: number): void;
26
+ export declare function computeScrollTopForTarget(target: HTMLElement, container: HTMLElement | Window, targetOffset: number): number;
@@ -0,0 +1,63 @@
1
+ //#region src/components/anchor-utils.ts
2
+ /** `#overview` / `path#overview` → `overview` */
3
+ function hrefToAnchorId(href) {
4
+ const raw = href.trim();
5
+ return (raw.includes("#") ? raw.slice(raw.indexOf("#") + 1) : raw).replace(/^#/, "");
6
+ }
7
+ function flattenAnchorItems(items, depth = 0) {
8
+ const out = [];
9
+ for (const item of items) {
10
+ out.push({
11
+ href: item.href,
12
+ title: item.title,
13
+ depth
14
+ });
15
+ if (item.children?.length) out.push(...flattenAnchorItems(item.children, depth + 1));
16
+ }
17
+ return out;
18
+ }
19
+ /**
20
+ * 滚动监听:取最后一个 top <= offset 的标题。
21
+ * entries 须按文档顺序(与 DOM 一致),top 为相对滚动容器顶部的距离。
22
+ */
23
+ function pickActiveAnchorHref(entries, offset) {
24
+ if (entries.length === 0) return "";
25
+ let active = entries[0]?.href ?? "";
26
+ for (const entry of entries) if (entry.top <= offset) active = entry.href;
27
+ return active;
28
+ }
29
+ function resolveAnchorContainer(getContainer) {
30
+ const resolved = getContainer?.();
31
+ if (resolved) return resolved;
32
+ if (typeof window !== "undefined") return window;
33
+ throw new Error("RsAnchor: no scroll container");
34
+ }
35
+ function readContainerScrollTop(container) {
36
+ if (container instanceof Window) return container.scrollY;
37
+ return container.scrollTop;
38
+ }
39
+ function targetTopInContainer(target, container) {
40
+ const targetRect = target.getBoundingClientRect();
41
+ if (container instanceof Window) return targetRect.top;
42
+ return targetRect.top - container.getBoundingClientRect().top;
43
+ }
44
+ function scrollContainerTo(container, top) {
45
+ if (container instanceof Window) {
46
+ container.scrollTo({
47
+ top,
48
+ behavior: "smooth"
49
+ });
50
+ return;
51
+ }
52
+ container.scrollTo({
53
+ top,
54
+ behavior: "smooth"
55
+ });
56
+ }
57
+ function computeScrollTopForTarget(target, container, targetOffset) {
58
+ const current = readContainerScrollTop(container);
59
+ const relativeTop = targetTopInContainer(target, container);
60
+ return Math.max(0, current + relativeTop - targetOffset);
61
+ }
62
+ //#endregion
63
+ export { computeScrollTopForTarget, flattenAnchorItems, hrefToAnchorId, pickActiveAnchorHref, readContainerScrollTop, resolveAnchorContainer, scrollContainerTo, targetTopInContainer };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,9 @@ export { default as RsConfigProvider } from './components/RsConfigProvider.js';
2
2
  export { default as RsBadge } from './components/RsBadge.js';
3
3
  export { default as RsContainer } from './components/RsContainer.js';
4
4
  export { default as RsBreadcrumb } from './components/RsBreadcrumb.js';
5
+ export { default as RsAnchor } from './components/RsAnchor.js';
6
+ export type { RsAnchorFlatItem, RsAnchorItem } from './components/anchor-utils';
7
+ export { flattenAnchorItems, hrefToAnchorId, pickActiveAnchorHref, } from './components/anchor-utils';
5
8
  export { default as RsToolbar } from './components/RsToolbar.js';
6
9
  export { default as RsButton } from './components/RsButton.js';
7
10
  export type { RsButtonTone, RsButtonVariant } from './components/button-utils';
package/dist/index.js CHANGED
@@ -49,6 +49,7 @@ export { RS_TIME_SECONDS_FORMAT } from './lib/rs-dayjs.js'
49
49
  export { RS_TOAST_DEFAULT_GAP } from './components/overlay-utils.js'
50
50
  export { RS_TOAST_DEFAULT_POSITION } from './components/overlay-utils.js'
51
51
  export { default as RsAlert } from './components/RsAlert.js'
52
+ export { default as RsAnchor } from './components/RsAnchor.js'
52
53
  export { default as RsAutoComplete } from './components/RsAutoComplete.js'
53
54
  export { default as RsAvatar } from './components/RsAvatar.js'
54
55
  export { default as RsBadge } from './components/RsBadge.js'
@@ -191,6 +192,7 @@ export { filterTableRows } from './components/table-utils.js'
191
192
  export { filterTableTreeRows } from './components/table-utils.js'
192
193
  export { filterTreeNodes } from './components/tree-utils.js'
193
194
  export { fixedCellStyle } from './components/table-utils.js'
195
+ export { flattenAnchorItems } from './components/anchor-utils.js'
194
196
  export { flattenTreeNodeIds } from './components/tree-utils.js'
195
197
  export { flattenVisibleCountRough } from './composables/useRsTableVirtual.js'
196
198
  export { flattenVisibleTableTreeEntries } from './components/table-utils.js'
@@ -235,6 +237,7 @@ export { hasStableTableTreeRowKey } from './components/table-utils.js'
235
237
  export { hasTableSummaryConfig } from './components/table/table-summary-utils.js'
236
238
  export { hasTableTreeChildren } from './components/table-utils.js'
237
239
  export { hasTreeChildren } from './components/tree-utils.js'
240
+ export { hrefToAnchorId } from './components/anchor-utils.js'
238
241
  export { inferLogLevel } from './components/log-utils.js'
239
242
  export { injectExpandRows } from './components/table-utils.js'
240
243
  export { inputRuleMessageKeys } from './components/input-rules.js'
@@ -300,6 +303,7 @@ export { parseLocalDateTimeToUtcIso } from './lib/iso-local-datetime.js'
300
303
  export { parseNumberInput } from './components/input-number-utils.js'
301
304
  export { parseRsLogLevel } from './components/log-utils.js'
302
305
  export { parseTimeValue } from './components/time-picker-utils.js'
306
+ export { pickActiveAnchorHref } from './components/anchor-utils.js'
303
307
  export { placeAnchoredPopup } from './components/overlay-utils.js'
304
308
  export { prefetchClipboardText } from './utils/rs-clipboard.js'
305
309
  export { prewarmCodeMirrorEditor } from './components/code-mirror-lang.js'
@@ -12,6 +12,7 @@ var zhCN = {
12
12
  "autocomplete.suggestions": "自动完成建议",
13
13
  "dropdown.placeholder": "请选择",
14
14
  "breadcrumb.label": "面包屑",
15
+ "anchor.label": "本页目录",
15
16
  "breadcrumb.separator": "分隔符",
16
17
  "menu.label": "导航菜单",
17
18
  "menu.expandSubmenu": "展开子菜单",
@@ -178,10 +179,11 @@ var zhCN = {
178
179
  "log.level.fatal": "致命",
179
180
  "log.level.plain": "输出",
180
181
  "playground.brand": "Niuma UI",
181
- "playground.subtitle": "Vue 3 组件演示",
182
- "playground.nav.label": "组件导航",
183
- "playground.nav.start": "开始",
184
- "playground.nav.overview": "首页",
182
+ "playground.subtitle": "内部测试,不是文档站",
183
+ "playground.docs": "文档站",
184
+ "playground.nav.label": "测试页导航",
185
+ "playground.nav.start": "索引",
186
+ "playground.nav.overview": "测试索引",
185
187
  "playground.nav.components": "组件",
186
188
  "playground.nav.basic": "基础",
187
189
  "playground.nav.form": "表单",
@@ -189,7 +191,7 @@ var zhCN = {
189
191
  "playground.nav.feedback": "浮层与反馈",
190
192
  "playground.nav.data": "数据展示",
191
193
  "playground.nav.editor": "编辑器",
192
- "playground.nav.lab": "实验室",
194
+ "playground.nav.lab": "像素回归",
193
195
  "playground.nav.search": "搜索组件…",
194
196
  "playground.nav.empty": "没有匹配的组件",
195
197
  "playground.nav.toggle": "打开导航",
@@ -205,22 +207,21 @@ var zhCN = {
205
207
  "playground.demo.api.type": "类型",
206
208
  "playground.demo.api.default": "默认值",
207
209
  "playground.demo.api.desc": "说明",
208
- "playground.index.title": "为运维台与桌面工具打造的 Vue 3 设计系统",
209
- "playground.index.intro": "一致的 Rs* 组件、--rs-* 设计 token,以及面向控制台场景的表格、树与编辑器能力。",
210
- "playground.index.cta.install": "安装",
211
- "playground.index.cta.browse": "浏览组件",
212
- "playground.index.install": "安装",
213
- "playground.index.installHint": "通过包管理器安装后,引入样式并包裹 RsConfigProvider。",
214
- "playground.index.quickStart": "快速开始",
215
- "playground.index.quickStartHint": "业务侧只从 niuma-ui 导入,不要直接依赖 reka-ui。",
216
- "playground.index.featured": "精选组件",
217
- "playground.index.featuredHint": "从高频能力开始体验交互与主题。",
218
- "playground.index.dev": "开发者索引",
219
- "playground.index.devHint": "演示页与单元测试对照,便于贡献与回归。",
210
+ "playground.demo.apiHint": "下表仅供回归对照。对外用法与 API 以文档站为准。",
211
+ "playground.index.title": "内部组件测试台",
212
+ "playground.index.intro": "playground 只做冒烟与像素回归。安装、何时使用、API 只认 site/ 文档站。",
213
+ "playground.index.cta.site": "打开文档站",
214
+ "playground.index.cta.browse": "打开测试页",
215
+ "playground.index.docs": "官方用法",
216
+ "playground.index.docsHint": "组件文档:https://blair-shang.github.io/niuma-ui/ 。本页不维护对外 API。",
217
+ "playground.index.featured": "常用测试页",
218
+ "playground.index.featuredHint": "高频控件的交互冒烟入口。",
219
+ "playground.index.dev": "测试对照表",
220
+ "playground.index.devHint": "测试页与单元测试文件对照。",
220
221
  "playground.index.column.component": "组件",
221
- "playground.index.column.demo": "演示页",
222
+ "playground.index.column.demo": "测试页",
222
223
  "playground.index.column.test": "单元测试",
223
- "playground.index.hint": "本地启动",
224
+ "playground.index.hint": "启动内部测试台",
224
225
  "codeBlock.copy": "复制",
225
226
  "codeBlock.copied": "已复制",
226
227
  "codeBlock.download": "下载",
@@ -244,6 +245,7 @@ var enUS = {
244
245
  "autocomplete.suggestions": "Autocomplete suggestions",
245
246
  "dropdown.placeholder": "Select",
246
247
  "breadcrumb.label": "Breadcrumb",
248
+ "anchor.label": "On this page",
247
249
  "breadcrumb.separator": "Separator",
248
250
  "menu.label": "Navigation menu",
249
251
  "menu.expandSubmenu": "Expand submenu",
@@ -410,10 +412,11 @@ var enUS = {
410
412
  "log.level.fatal": "Fatal",
411
413
  "log.level.plain": "Output",
412
414
  "playground.brand": "Niuma UI",
413
- "playground.subtitle": "Vue 3 component demos",
414
- "playground.nav.label": "Component navigation",
415
- "playground.nav.start": "Start",
416
- "playground.nav.overview": "Home",
415
+ "playground.subtitle": "Internal test — not the docs site",
416
+ "playground.docs": "Docs site",
417
+ "playground.nav.label": "Test page navigation",
418
+ "playground.nav.start": "Index",
419
+ "playground.nav.overview": "Test index",
417
420
  "playground.nav.components": "Components",
418
421
  "playground.nav.basic": "Basic",
419
422
  "playground.nav.form": "Form",
@@ -421,7 +424,7 @@ var enUS = {
421
424
  "playground.nav.feedback": "Overlay & feedback",
422
425
  "playground.nav.data": "Data display",
423
426
  "playground.nav.editor": "Editors",
424
- "playground.nav.lab": "Lab",
427
+ "playground.nav.lab": "Visual regression",
425
428
  "playground.nav.search": "Search components…",
426
429
  "playground.nav.empty": "No matching components",
427
430
  "playground.nav.toggle": "Open navigation",
@@ -437,22 +440,21 @@ var enUS = {
437
440
  "playground.demo.api.type": "Type",
438
441
  "playground.demo.api.default": "Default",
439
442
  "playground.demo.api.desc": "Description",
440
- "playground.index.title": "A Vue 3 design system for ops consoles and desktop tools",
441
- "playground.index.intro": "Consistent Rs* components, --rs-* tokens, plus table, tree, and editor capabilities for console UIs.",
442
- "playground.index.cta.install": "Install",
443
- "playground.index.cta.browse": "Browse components",
444
- "playground.index.install": "Install",
445
- "playground.index.installHint": "Install the package, import styles, and wrap your app with RsConfigProvider.",
446
- "playground.index.quickStart": "Quick start",
447
- "playground.index.quickStartHint": "Import only from niuma-ui — do not depend on reka-ui directly.",
448
- "playground.index.featured": "Featured",
449
- "playground.index.featuredHint": "Start with high-traffic components to explore interaction and theming.",
450
- "playground.index.dev": "Developer index",
451
- "playground.index.devHint": "Demo pages mapped to unit tests for contribution and regression.",
443
+ "playground.demo.apiHint": "This table is for regression only. Public usage and API live on the docs site.",
444
+ "playground.index.title": "Internal component test bench",
445
+ "playground.index.intro": "playground is smoke and visual regression only. Install, when-to-use, and API live on the site/ docs.",
446
+ "playground.index.cta.site": "Open docs site",
447
+ "playground.index.cta.browse": "Open a test page",
448
+ "playground.index.docs": "Official usage",
449
+ "playground.index.docsHint": "Component docs: https://blair-shang.github.io/niuma-ui/ . This page does not maintain the public API.",
450
+ "playground.index.featured": "Frequent test pages",
451
+ "playground.index.featuredHint": "Smoke entries for high-traffic controls.",
452
+ "playground.index.dev": "Test map",
453
+ "playground.index.devHint": "Test pages mapped to unit-test files.",
452
454
  "playground.index.column.component": "Component",
453
- "playground.index.column.demo": "Demo",
455
+ "playground.index.column.demo": "Test page",
454
456
  "playground.index.column.test": "Unit test",
455
- "playground.index.hint": "Local start",
457
+ "playground.index.hint": "Start the internal test bench",
456
458
  "codeBlock.copy": "Copy",
457
459
  "codeBlock.copied": "Copied!",
458
460
  "codeBlock.download": "Download",
package/dist/styles.css CHANGED
@@ -1697,6 +1697,64 @@ code {
1697
1697
  cursor: not-allowed;
1698
1698
  }
1699
1699
 
1700
+ /* 面板 Portal 在 body,尺寸只能跟 content 档位,不能跟 .rs-select--sm */
1701
+ .rs-select__content--sm .rs-select__item,
1702
+ .rs-select__content--ssm .rs-select__item {
1703
+ gap: var(--rs-space-xs);
1704
+ font-size: var(--rs-font-size-xs);
1705
+ line-height: var(--rs-line-height-tight);
1706
+ }
1707
+
1708
+ .rs-select__content--sm .rs-select__item {
1709
+ min-height: var(--rs-control-height-sm);
1710
+ padding: 0.25rem 0.5rem;
1711
+ }
1712
+
1713
+ .rs-select__content--ssm .rs-select__item {
1714
+ min-height: var(--rs-control-height-ssm);
1715
+ padding: 0.125rem 0.375rem;
1716
+ }
1717
+
1718
+ .rs-select__content--lg .rs-select__item {
1719
+ min-height: var(--rs-control-height-lg);
1720
+ padding: var(--rs-space-sm) var(--rs-space-lg);
1721
+ font-size: var(--rs-font-size-base);
1722
+ }
1723
+
1724
+ .rs-select__content--sm .rs-select__item-check,
1725
+ .rs-select__content--ssm .rs-select__item-check {
1726
+ width: 0.75rem;
1727
+ }
1728
+
1729
+ .rs-select__content--sm .rs-select__search,
1730
+ .rs-select__content--ssm .rs-select__search {
1731
+ font-size: var(--rs-font-size-xs);
1732
+ }
1733
+
1734
+ .rs-select__content--ssm .rs-select__search-wrap {
1735
+ min-height: var(--rs-control-height-ssm);
1736
+ }
1737
+
1738
+ .rs-select__content--sm .rs-select__empty,
1739
+ .rs-select__content--ssm .rs-select__empty,
1740
+ .rs-select__content--sm .rs-select__status,
1741
+ .rs-select__content--ssm .rs-select__status {
1742
+ padding: var(--rs-space-sm);
1743
+ font-size: var(--rs-font-size-xs);
1744
+ }
1745
+
1746
+ .rs-select__content--sm .rs-select__viewport,
1747
+ .rs-select__content--ssm .rs-select__viewport {
1748
+ padding-left: 0.25rem;
1749
+ padding-right: 0.25rem;
1750
+ padding-bottom: 0.25rem;
1751
+ }
1752
+
1753
+ .rs-select__content--sm:not(:has(.rs-select__search-bar)) .rs-select__viewport,
1754
+ .rs-select__content--ssm:not(:has(.rs-select__search-bar)) .rs-select__viewport {
1755
+ padding-top: 0.25rem;
1756
+ }
1757
+
1700
1758
  .rs-auto-complete {
1701
1759
  position: relative;
1702
1760
  display: inline-flex;
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "niuma-ui",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
- "description": "Vue 3 工作台设计系统(Rs* 组件、--rs-* token;含可选编辑器 / 终端)",
6
+ "description": "Vue 3 workbench design system — Rs* components, --rs-* tokens, optional Monaco / CodeMirror / xterm",
7
7
  "keywords": [
8
8
  "vue",
9
9
  "vue3",
10
10
  "ui",
11
11
  "components",
12
12
  "design-system",
13
+ "workbench",
13
14
  "reka-ui",
14
15
  "niuma"
15
16
  ],
@@ -18,7 +19,7 @@
18
19
  "type": "git",
19
20
  "url": "git+https://github.com/Blair-Shang/niuma-ui.git"
20
21
  },
21
- "homepage": "https://github.com/Blair-Shang/niuma-ui#readme",
22
+ "homepage": "https://blair-shang.github.io/niuma-ui/",
22
23
  "bugs": {
23
24
  "url": "https://github.com/Blair-Shang/niuma-ui/issues"
24
25
  },
@@ -140,9 +141,12 @@
140
141
  },
141
142
  "scripts": {
142
143
  "dev": "vite --config playground/vite.config.ts",
144
+ "dev:site": "vite --config site/vite.config.ts",
143
145
  "build": "node scripts/build-lib.mjs",
144
146
  "build:playground": "vite build --config playground/vite.config.ts",
145
147
  "preview:playground": "vite preview --config playground/vite.config.ts",
148
+ "build:site": "vite build --config site/vite.config.ts",
149
+ "preview:site": "vite preview --config site/vite.config.ts",
146
150
  "test": "vitest run",
147
151
  "test:watch": "vitest",
148
152
  "test:perf": "vitest run src/__tests__/RsTable.perf.spec.ts src/__tests__/useRsTableCore.perf.spec.ts",