niuma-ui 2.1.0 → 2.1.3

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/components/auto-complete/src/RsAutoComplete.d.ts +2 -2
  3. package/dist/components/code-block/src/RsCodeBlock.css +26 -26
  4. package/dist/components/code-block/src/RsCodeBlock.impl.js +2 -2
  5. package/dist/components/code-block/src/RsCodeBlock.js +1 -1
  6. package/dist/components/code-block/src/code-block-utils.js +2 -1
  7. package/dist/components/code-editor/src/code-editor-utils.js +2 -1
  8. package/dist/components/context-menu/src/RsContextMenu.css +19 -19
  9. package/dist/components/date-picker/src/RsDatePicker.d.ts +2 -2
  10. package/dist/components/date-picker/src/RsDateTimePicker.d.ts +2 -2
  11. package/dist/components/dialog/src/RsConfirmDialog.css +25 -25
  12. package/dist/components/dialog/src/RsConfirmDialog.impl.js +4 -4
  13. package/dist/components/dialog/src/RsConfirmDialog.js +1 -1
  14. package/dist/components/dialog/src/RsDialog.css +63 -63
  15. package/dist/components/dialog/src/RsDialog.impl.js +56 -11
  16. package/dist/components/dialog/src/RsDialog.js +1 -1
  17. package/dist/components/dialog/src/dialog-window.d.ts +1 -0
  18. package/dist/components/dialog/src/dialog-window.js +1 -0
  19. package/dist/components/dynamic-tags/src/RsDynamicTags.d.ts +2 -2
  20. package/dist/components/icon/src/RsIcon.css +5 -5
  21. package/dist/components/icon/src/RsIcon.d.ts +1 -1
  22. package/dist/components/icon/src/RsIcon.impl.js +1 -1
  23. package/dist/components/icon/src/RsIcon.js +1 -1
  24. package/dist/components/input/src/RsInput.d.ts +2 -2
  25. package/dist/components/mentions/src/RsMentions.d.ts +2 -2
  26. package/dist/components/monaco-editor/src/monaco-editor-utils.js +2 -1
  27. package/dist/components/select/src/RsSelect.d.ts +2 -2
  28. package/dist/components/tabs/src/RsTabs.d.ts +3 -3
  29. package/dist/components/tabs/src/RsTabs.impl.js +1 -1
  30. package/dist/components/terminal/src/terminal-utils.js +2 -1
  31. package/dist/components/textarea/src/RsTextarea.d.ts +2 -2
  32. package/dist/components/time-picker/src/RsTimePicker.d.ts +2 -2
  33. package/dist/components/tree/src/RsTree.css +74 -74
  34. package/dist/components/tree/src/RsTree.js +1 -1
  35. package/dist/components/tree-select/src/RsTreeSelect.d.ts +2 -2
  36. package/dist/icons/host.d.ts +11 -0
  37. package/dist/icons/host.js +30 -0
  38. package/dist/icons/lucide.js +10 -3
  39. package/dist/icons/registry.js +1 -1
  40. package/dist/index.d.ts +4 -1
  41. package/dist/index.js +7 -0
  42. package/dist/styles.css +27 -11
  43. package/dist/theme/color-theme.d.ts +64 -0
  44. package/dist/theme/color-theme.js +100 -0
  45. package/dist/utils/rs-clipboard.d.ts +1 -1
  46. package/dist/utils/rs-clipboard.js +17 -7
  47. package/dist/vite-plugins/niuma-ui-host.d.ts +2 -1
  48. package/dist/vite-plugins/niuma-ui-host.js +25 -6
  49. package/package.json +1 -1
package/dist/styles.css CHANGED
@@ -360,29 +360,33 @@ html {
360
360
  --rs-dropdown-max-height: 16rem;
361
361
  --rs-dropdown-disabled-opacity: 0.38;
362
362
 
363
- /* Context menu。尺寸在此;颜色别名语义 token,随 data-rs-theme。挂到 body 须盖住 Dialog。 */
363
+ /*
364
+ * Context menu。macOS 菜单:12px 面板、6px 选中条、约 26px 行、13px 字。
365
+ * 选中用主题色铺底、文字反白。颜色别名语义 token,随 data-rs-theme。
366
+ * 挂到 body 须盖住 Dialog。实色底,不用 backdrop-filter。
367
+ */
364
368
  --rs-ctx-z: calc(var(--rs-z-modal) + 2);
365
- --rs-ctx-min-width: 11rem;
369
+ --rs-ctx-min-width: 11.5rem;
366
370
  --rs-ctx-max-width: 22rem;
367
371
  --rs-ctx-pad: 5px;
368
- --rs-ctx-radius: 10px;
369
- --rs-ctx-item-height: 1.5rem;
372
+ --rs-ctx-radius: 12px;
373
+ --rs-ctx-item-height: 1.625rem;
370
374
  --rs-ctx-item-radius: 6px;
371
- --rs-ctx-font-size: var(--rs-font-size-xs);
372
- --rs-ctx-icon-col: 28px;
375
+ --rs-ctx-font-size: 0.8125rem;
376
+ --rs-ctx-icon-col: 1.75rem;
373
377
  --rs-ctx-disabled-opacity: 0.38;
374
- --rs-ctx-motion-in: 0.13s;
378
+ --rs-ctx-motion-in: 0.14s;
375
379
  --rs-ctx-motion-sub: 0.1s;
376
380
  --rs-ctx-bg: var(--rs-surface-elevated);
377
381
  --rs-ctx-fg: var(--rs-text-primary);
378
382
  --rs-ctx-muted: var(--rs-text-tertiary);
379
- --rs-ctx-border: var(--rs-border);
380
- --rs-ctx-separator: var(--rs-border-subtle);
381
- --rs-ctx-shadow: var(--rs-shadow-lg);
383
+ --rs-ctx-border: color-mix(in srgb, var(--rs-text-primary) 8%, transparent);
384
+ --rs-ctx-separator: color-mix(in srgb, var(--rs-text-primary) 10%, transparent);
385
+ --rs-ctx-shadow: 0 16px 40px rgb(0 0 0 / 0.12), 0 2px 8px rgb(0 0 0 / 0.06);
382
386
  --rs-ctx-danger: var(--rs-danger);
383
387
  --rs-ctx-item-active-bg: var(--rs-primary);
384
388
  --rs-ctx-item-active-fg: var(--rs-primary-foreground);
385
- --rs-ctx-item-active-muted: color-mix(in srgb, var(--rs-primary-foreground) 75%, transparent);
389
+ --rs-ctx-item-active-muted: color-mix(in srgb, var(--rs-primary-foreground) 78%, transparent);
386
390
 
387
391
  /* Popover(气泡卡片)。尺寸静态;颜色在主题块内。 */
388
392
  --rs-popover-pad: 0.75rem;
@@ -977,6 +981,7 @@ html {
977
981
  --rs-shadow-sm: 0 1px 3px rgb(0 0 0 / 0.4);
978
982
  --rs-shadow: 0 4px 16px rgb(0 0 0 / 0.45), 0 0 0 0.5px rgb(255 255 255 / 0.08);
979
983
  --rs-shadow-lg: 0 12px 32px rgb(0 0 0 / 0.5), 0 0 0 0.5px rgb(255 255 255 / 0.1);
984
+ --rs-ctx-shadow: 0 16px 40px rgb(0 0 0 / 0.46), 0 2px 8px rgb(0 0 0 / 0.28);
980
985
  }
981
986
 
982
987
  /* ── 公共亮色:无属性 = light,避免盖住后面的 dark(:root 与属性选择器同权)── */
@@ -1362,6 +1367,7 @@ html {
1362
1367
  --rs-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.04), 0 0 0 0.5px rgb(0 0 0 / 0.04);
1363
1368
  --rs-shadow: 0 4px 16px rgb(0 0 0 / 0.08), 0 0 0 0.5px rgb(0 0 0 / 0.06);
1364
1369
  --rs-shadow-lg: 0 12px 32px rgb(0 0 0 / 0.12), 0 0 0 0.5px rgb(0 0 0 / 0.08);
1370
+ --rs-ctx-shadow: 0 16px 40px rgb(0 0 0 / 0.12), 0 2px 8px rgb(0 0 0 / 0.06);
1365
1371
  }
1366
1372
 
1367
1373
  /**
@@ -1419,6 +1425,16 @@ html {
1419
1425
  --rs-shadow-sm: none;
1420
1426
  --rs-shadow: none;
1421
1427
  --rs-shadow-lg: none;
1428
+ --rs-ctx-bg: Canvas;
1429
+ --rs-ctx-fg: CanvasText;
1430
+ --rs-ctx-muted: GrayText;
1431
+ --rs-ctx-border: CanvasText;
1432
+ --rs-ctx-separator: CanvasText;
1433
+ --rs-ctx-shadow: none;
1434
+ --rs-ctx-danger: Mark;
1435
+ --rs-ctx-item-active-bg: Highlight;
1436
+ --rs-ctx-item-active-fg: HighlightText;
1437
+ --rs-ctx-item-active-muted: HighlightText;
1422
1438
  --rs-card-border: CanvasText;
1423
1439
  --rs-card-separator: CanvasText;
1424
1440
  --rs-card-header-bg: Canvas;
@@ -0,0 +1,64 @@
1
+ import { type RsResolvedTheme } from './types';
2
+ /**
3
+ * 颜色主题身份。只标记当前皮肤,组件样式不要用它做选择器。
4
+ * 明暗仍只写 `data-rs-theme="light|dark"`。
5
+ */
6
+ export declare const colorThemeAttribute = "data-rs-color-theme";
7
+ /** 文档级编辑器要同时观察明暗和颜色主题,否则同为暗色时换皮肤不会重读 token。 */
8
+ export declare const documentThemeAttributes: readonly ["data-rs-theme", "data-rs-color-theme"];
9
+ /**
10
+ * 主题包可以覆盖的语义令牌。表格、树、按钮等已用 var() 指向这些名字。
11
+ * 键是主题文件里的字段,值是要写到元素上的 CSS 变量。
12
+ */
13
+ export declare const RS_COLOR_THEME_VARS: {
14
+ readonly primary: "--rs-primary";
15
+ readonly primaryHover: "--rs-primary-hover";
16
+ readonly primaryForeground: "--rs-primary-foreground";
17
+ readonly primaryContainer: "--rs-primary-container";
18
+ readonly onPrimaryContainer: "--rs-on-primary-container";
19
+ readonly bg: "--rs-bg";
20
+ readonly surface: "--rs-surface";
21
+ readonly surfaceElevated: "--rs-surface-elevated";
22
+ readonly surfaceHover: "--rs-surface-hover";
23
+ readonly itemHover: "--rs-item-hover";
24
+ readonly inputBg: "--rs-input-bg";
25
+ readonly inputBorder: "--rs-input-border";
26
+ readonly inputBorderHover: "--rs-input-border-hover";
27
+ readonly border: "--rs-border";
28
+ readonly borderSubtle: "--rs-border-subtle";
29
+ readonly text: "--rs-text-primary";
30
+ readonly muted: "--rs-text-secondary";
31
+ readonly placeholder: "--rs-text-tertiary";
32
+ readonly textDisabled: "--rs-text-disabled";
33
+ readonly textInverse: "--rs-text-inverse";
34
+ readonly danger: "--rs-danger";
35
+ readonly dangerContainer: "--rs-danger-container";
36
+ readonly onDangerContainer: "--rs-on-danger-container";
37
+ readonly success: "--rs-success";
38
+ readonly successContainer: "--rs-success-container";
39
+ readonly onSuccessContainer: "--rs-on-success-container";
40
+ readonly warning: "--rs-warning";
41
+ readonly warningContainer: "--rs-warning-container";
42
+ readonly onWarningContainer: "--rs-on-warning-container";
43
+ readonly info: "--rs-info";
44
+ readonly infoContainer: "--rs-info-container";
45
+ readonly onInfoContainer: "--rs-on-info-container";
46
+ };
47
+ export type RsColorThemeToken = keyof typeof RS_COLOR_THEME_VARS;
48
+ /** 一份可安装的颜色主题。`id` 不翻译;`label` 用英文,宿主自己做语言包。 */
49
+ export interface RsColorTheme {
50
+ id: string;
51
+ label: string;
52
+ uiTheme: RsResolvedTheme;
53
+ colors: Partial<Record<RsColorThemeToken, string>>;
54
+ }
55
+ /** 拒绝能逃出自定义属性、注入样式或外链的值。允许 hex、函数色和 var()。 */
56
+ export declare function isSafeColorThemeValue(value: string): boolean;
57
+ export declare function isSafeColorThemeId(id: string): boolean;
58
+ /**
59
+ * 把主题包写到元素的内联 `--rs-*` 上,盖过 styles.css 与 brand.css。
60
+ * 未列出的字段保持样式表原值。非法 id 或没有目标元素时不改 DOM。
61
+ */
62
+ export declare function applyColorTheme(theme: RsColorTheme, el?: HTMLElement | null): boolean;
63
+ /** 去掉该元素上由颜色主题写上的变量,回到样式表。 */
64
+ export declare function clearColorTheme(el?: HTMLElement | null): void;
@@ -0,0 +1,100 @@
1
+ import { themeAttribute } from "./types.js";
2
+ //#region src/theme/color-theme.ts
3
+ /**
4
+ * 颜色主题身份。只标记当前皮肤,组件样式不要用它做选择器。
5
+ * 明暗仍只写 `data-rs-theme="light|dark"`。
6
+ */
7
+ var colorThemeAttribute = "data-rs-color-theme";
8
+ /** 文档级编辑器要同时观察明暗和颜色主题,否则同为暗色时换皮肤不会重读 token。 */
9
+ var documentThemeAttributes = [themeAttribute, colorThemeAttribute];
10
+ /**
11
+ * 主题包可以覆盖的语义令牌。表格、树、按钮等已用 var() 指向这些名字。
12
+ * 键是主题文件里的字段,值是要写到元素上的 CSS 变量。
13
+ */
14
+ var RS_COLOR_THEME_VARS = {
15
+ primary: "--rs-primary",
16
+ primaryHover: "--rs-primary-hover",
17
+ primaryForeground: "--rs-primary-foreground",
18
+ primaryContainer: "--rs-primary-container",
19
+ onPrimaryContainer: "--rs-on-primary-container",
20
+ bg: "--rs-bg",
21
+ surface: "--rs-surface",
22
+ surfaceElevated: "--rs-surface-elevated",
23
+ surfaceHover: "--rs-surface-hover",
24
+ itemHover: "--rs-item-hover",
25
+ inputBg: "--rs-input-bg",
26
+ inputBorder: "--rs-input-border",
27
+ inputBorderHover: "--rs-input-border-hover",
28
+ border: "--rs-border",
29
+ borderSubtle: "--rs-border-subtle",
30
+ text: "--rs-text-primary",
31
+ muted: "--rs-text-secondary",
32
+ placeholder: "--rs-text-tertiary",
33
+ textDisabled: "--rs-text-disabled",
34
+ textInverse: "--rs-text-inverse",
35
+ danger: "--rs-danger",
36
+ dangerContainer: "--rs-danger-container",
37
+ onDangerContainer: "--rs-on-danger-container",
38
+ success: "--rs-success",
39
+ successContainer: "--rs-success-container",
40
+ onSuccessContainer: "--rs-on-success-container",
41
+ warning: "--rs-warning",
42
+ warningContainer: "--rs-warning-container",
43
+ onWarningContainer: "--rs-on-warning-container",
44
+ info: "--rs-info",
45
+ infoContainer: "--rs-info-container",
46
+ onInfoContainer: "--rs-on-info-container"
47
+ };
48
+ var THEME_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
49
+ var appliedVars = /* @__PURE__ */ new WeakMap();
50
+ function themeTarget(el) {
51
+ if (el) return el;
52
+ if (typeof document === "undefined") return null;
53
+ return document.documentElement;
54
+ }
55
+ /** 拒绝能逃出自定义属性、注入样式或外链的值。允许 hex、函数色和 var()。 */
56
+ function isSafeColorThemeValue(value) {
57
+ const raw = value.trim();
58
+ if (!raw || raw.length > 240) return false;
59
+ if (/[;{}<>]|url\s*\(|expression\s*\(|@import|\/\*|\*\//i.test(raw)) return false;
60
+ return true;
61
+ }
62
+ function isSafeColorThemeId(id) {
63
+ return THEME_ID.test(id);
64
+ }
65
+ /**
66
+ * 把主题包写到元素的内联 `--rs-*` 上,盖过 styles.css 与 brand.css。
67
+ * 未列出的字段保持样式表原值。非法 id 或没有目标元素时不改 DOM。
68
+ */
69
+ function applyColorTheme(theme, el) {
70
+ const target = themeTarget(el);
71
+ if (!target || !isSafeColorThemeId(theme.id)) return false;
72
+ const previous = appliedVars.get(target) ?? /* @__PURE__ */ new Set();
73
+ const next = /* @__PURE__ */ new Set();
74
+ for (const key of Object.keys(RS_COLOR_THEME_VARS)) {
75
+ const value = theme.colors[key];
76
+ if (value == null) continue;
77
+ const raw = String(value).trim();
78
+ if (!isSafeColorThemeValue(raw)) continue;
79
+ const prop = RS_COLOR_THEME_VARS[key];
80
+ target.style.setProperty(prop, raw);
81
+ next.add(prop);
82
+ }
83
+ for (const prop of previous) if (!next.has(prop)) target.style.removeProperty(prop);
84
+ appliedVars.set(target, next);
85
+ target.setAttribute(colorThemeAttribute, theme.id);
86
+ return true;
87
+ }
88
+ /** 去掉该元素上由颜色主题写上的变量,回到样式表。 */
89
+ function clearColorTheme(el) {
90
+ const target = themeTarget(el);
91
+ if (!target) return;
92
+ const previous = appliedVars.get(target);
93
+ if (previous) {
94
+ for (const prop of previous) target.style.removeProperty(prop);
95
+ appliedVars.delete(target);
96
+ }
97
+ target.removeAttribute(colorThemeAttribute);
98
+ }
99
+ //#endregion
100
+ export { RS_COLOR_THEME_VARS, applyColorTheme, clearColorTheme, colorThemeAttribute, documentThemeAttributes, isSafeColorThemeId, isSafeColorThemeValue };
@@ -13,7 +13,7 @@ export declare function writeClipboardText(text: string): Promise<boolean>;
13
13
  export declare function copyTextWithExecCommand(text: string): boolean;
14
14
  /** HTTP / 非安全上下文没有 Clipboard API,writeText 会 SecurityError。 */
15
15
  export declare function isInsecureClipboardContext(): boolean;
16
- /** 写入系统剪贴板。HTTP 先同步 execCommand,避免 await 丢掉用户手势。 */
16
+ /** 写入系统剪贴板。先同步 execCommand,避免 await 丢掉点击手势;对话框里也要在这一拍写完。 */
17
17
  export declare function copyTextToClipboard(text: string): Promise<boolean>;
18
18
  /** @internal vitest 用 */
19
19
  export declare function __resetClipboardStateForTests(): void;
@@ -158,6 +158,19 @@ async function writeClipboardText(text) {
158
158
  return false;
159
159
  }
160
160
  }
161
+ /** 打开的 dialog 会把焦点留在框内。临时输入框必须挂在这个 dialog 里,挂到 body 上选不中,复制是空的。 */
162
+ function clipboardMount() {
163
+ const active = document.activeElement;
164
+ if (active instanceof Element) {
165
+ const dialog = active.closest("dialog");
166
+ if (dialog instanceof HTMLElement) return dialog;
167
+ }
168
+ if (typeof document.querySelector === "function") {
169
+ const open = document.querySelector("dialog[open]");
170
+ if (open instanceof HTMLElement) return open;
171
+ }
172
+ return document.body;
173
+ }
161
174
  /** execCommand 兜底:CEF / 无 Clipboard API 权限时菜单复制仍可用 */
162
175
  function copyTextWithExecCommand(text) {
163
176
  if (!text || typeof document === "undefined") return false;
@@ -166,7 +179,7 @@ function copyTextWithExecCommand(text) {
166
179
  textarea.value = text;
167
180
  textarea.setAttribute("readonly", "");
168
181
  textarea.style.cssText = "position:fixed;left:0;top:0;width:1px;height:1px;padding:0;border:0;opacity:0.01";
169
- document.body.appendChild(textarea);
182
+ clipboardMount().appendChild(textarea);
170
183
  if (typeof textarea.focus === "function") textarea.focus();
171
184
  textarea.select();
172
185
  if (typeof textarea.setSelectionRange === "function") textarea.setSelectionRange(0, text.length);
@@ -181,16 +194,13 @@ function copyTextWithExecCommand(text) {
181
194
  function isInsecureClipboardContext() {
182
195
  return typeof globalThis !== "undefined" && globalThis.isSecureContext === false;
183
196
  }
184
- /** 写入系统剪贴板。HTTP 先同步 execCommand,避免 await 丢掉用户手势。 */
197
+ /** 写入系统剪贴板。先同步 execCommand,避免 await 丢掉点击手势;对话框里也要在这一拍写完。 */
185
198
  async function copyTextToClipboard(text) {
186
199
  if (!text) return false;
187
- if (isInsecureClipboardContext()) {
188
- if (copyTextWithExecCommand(text)) return true;
189
- return writeClipboardViaShell(text);
190
- }
200
+ if (copyTextWithExecCommand(text)) return true;
201
+ if (isInsecureClipboardContext()) return writeClipboardViaShell(text);
191
202
  await syncClipboardPermissionState();
192
203
  if (!writeApiBlocked && await writeClipboardText(text)) return true;
193
- if (copyTextWithExecCommand(text)) return true;
194
204
  return writeClipboardViaShell(text);
195
205
  }
196
206
  //#endregion
@@ -64,7 +64,8 @@ export declare function emitLiveReexportIndex(map: Map<string, NiumaUiBinding>):
64
64
  */
65
65
  export declare function parseRuntimeBindings(source: string): Map<string, NiumaUiBinding>;
66
66
  /**
67
- * FollowSourceBarrels 把 `./components/button` 这类目录再导出展开到实现文件。
67
+ * FollowSourceBarrels 把目录 index,以及 `icons/registry.ts` 这类纯再导出,展开到实现文件。
68
68
  * 只跟一层,避免评估整桶 `src/index.ts`。
69
+ * 非 index 只有名字本身是 `export { x } from` 时才改指向,这样 `isRsBrandIconName` 落到 `brand.ts`,不会把同文件再导出的 Lucide 一起求值。
69
70
  */
70
71
  export declare function followSourceBarrels(root: string, map: Map<string, NiumaUiBinding>): Map<string, NiumaUiBinding>;
@@ -123,7 +123,16 @@ function niumaUiHostRewrite(ctx) {
123
123
  return null;
124
124
  if (!code.includes('@niuma/ui') && !code.includes('niuma-ui'))
125
125
  return null;
126
- return rewriteHostModule(code, id, ctx.map, (from, spec) => resolveTarget(from, spec, ctx.root, ctx.useSource));
126
+ const rewrite = () => rewriteHostModule(code, id, ctx.map, (from, spec) => resolveTarget(from, spec, ctx.root, ctx.useSource));
127
+ try {
128
+ return await rewrite();
129
+ }
130
+ catch (err) {
131
+ if (!(err instanceof Error) || !err.message.includes('未找到运行时导出'))
132
+ throw err;
133
+ ctx.map = loadRuntimeBindings(ctx.root, ctx.useSource);
134
+ return rewrite();
135
+ }
127
136
  },
128
137
  };
129
138
  }
@@ -400,21 +409,31 @@ function loadRuntimeBindings(root, useSource) {
400
409
  return map;
401
410
  }
402
411
  /**
403
- * FollowSourceBarrels 把 `./components/button` 这类目录再导出展开到实现文件。
412
+ * FollowSourceBarrels 把目录 index,以及 `icons/registry.ts` 这类纯再导出,展开到实现文件。
404
413
  * 只跟一层,避免评估整桶 `src/index.ts`。
414
+ * 非 index 只有名字本身是 `export { x } from` 时才改指向,这样 `isRsBrandIconName` 落到 `brand.ts`,不会把同文件再导出的 Lucide 一起求值。
405
415
  */
406
416
  export function followSourceBarrels(root, map) {
407
417
  const next = new Map();
418
+ const parsed = new Map();
419
+ const bindingsIn = (file) => {
420
+ const cached = parsed.get(file);
421
+ if (cached)
422
+ return cached;
423
+ const child = parseRuntimeBindings(readFileSync(file, 'utf8'));
424
+ parsed.set(file, child);
425
+ return child;
426
+ };
408
427
  for (const [name, binding] of map) {
409
428
  const file = resolveSourceModule(root, binding.from);
410
- if (!file || !/[/\\]index\.(ts|js)$/.test(file)) {
429
+ if (!file) {
411
430
  next.set(name, binding);
412
431
  continue;
413
432
  }
414
- const child = parseRuntimeBindings(readFileSync(file, 'utf8'));
415
- const inner = child.get(name);
433
+ const barrel = /[/\\]index\.(ts|js)$/.test(file);
434
+ const inner = bindingsIn(file).get(name);
416
435
  if (!inner) {
417
- next.set(name, { ...binding, from: toSrcRel(root, file) });
436
+ next.set(name, barrel ? { ...binding, from: toSrcRel(root, file) } : binding);
418
437
  continue;
419
438
  }
420
439
  const innerAbs = resolveRelativeModule(file, inner.from);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "niuma-ui",
3
- "version": "2.1.0",
3
+ "version": "2.1.3",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "description": "Vue 3 workbench design system — Rs* components, --rs-* tokens, optional Monaco / CodeMirror / xterm",