hiwork-core 0.0.2 → 0.0.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.
package/README.md CHANGED
@@ -103,6 +103,9 @@ ctx.inject(['hiworkFeatureCenter'], (scope) => {
103
103
  其余项按 order 排序。`icon` 是内联 SVG 字符串;缺省用兜底图标,保证侧栏折叠成
104
104
  56px 图标栏时每个入口仍有可辨识图形(折叠态由宿主加在侧栏根上的 `*_collapsed`
105
105
  类驱动纯 CSS:隐藏文字、图标放大到 18px,与原生控件同形)。
106
+ 折叠态悬停 500ms 弹出提示气泡,黑底白字、圆角与字号逐项对齐框架 `ui-primitives`
107
+ 的 `Tooltip`(`--dsw-alias-tooltip-bg`),取代浏览器自带的浅色 `title` 提示;
108
+ 展开态文字已可见,与原生控件一致(`Tooltip disabled={wide}`)不出气泡。
106
109
  找不到原生按钮时不抛错、不隐藏任何入口,菜单只列 feature(安全降级)。
107
110
  - **中央区 takeover**:挂一个 `[data-hiwork-feature-root]` React root,用
108
111
  `html[data-hiwork-active-page]` 上的纯 CSS 规则隐藏原生会话子树(保持挂载、保留状态);
package/lib/client.js CHANGED
@@ -2352,6 +2352,8 @@ var MENU_ATTRIBUTE = "data-hiwork-feature-menu";
2352
2352
  var MENU_ITEM_ATTRIBUTE = "data-hiwork-feature-menu-item";
2353
2353
  var MENU_ICON_ATTRIBUTE = "data-hiwork-feature-menu-icon";
2354
2354
  var MENU_LABEL_ATTRIBUTE = "data-hiwork-feature-menu-label";
2355
+ var TOOLTIP_ATTRIBUTE = "data-hiwork-feature-tooltip";
2356
+ var TOOLTIP_VISIBLE_ATTRIBUTE = "data-hiwork-feature-tooltip-visible";
2355
2357
  var NATIVE_HIDDEN_ATTRIBUTE = "data-hiwork-native-new-session";
2356
2358
  var FEATURE_ROOT_ATTRIBUTE = "data-hiwork-feature-root";
2357
2359
  var OWNER_ATTRIBUTE = "data-hiwork-owner";
@@ -2359,6 +2361,8 @@ var ACTIVE_PAGE_ATTRIBUTE = "data-hiwork-active-page";
2359
2361
  var NATIVE_MENU_ITEM_ID = "__native_new_session__";
2360
2362
  var DEFAULT_NEW_SESSION_LABEL = "\u65B0\u4F1A\u8BDD";
2361
2363
  var STYLE_ELEMENT_ID = "hiwork-feature-center-styles";
2364
+ var TOOLTIP_DELAY_MS = 500;
2365
+ var TOOLTIP_GAP_PX = 8;
2362
2366
  var DEFAULT_NEW_SESSION_ICON = '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M8 3.4v9.2M3.4 8h9.2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>';
2363
2367
  var DEFAULT_FEATURE_ICON = '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><rect x="2.75" y="2.75" width="10.5" height="10.5" rx="3" stroke="currentColor" stroke-width="1.5"/><circle cx="8" cy="8" r="1.4" fill="currentColor"/></svg>';
2364
2368
  var SESSION_ROW_SELECTOR = [
@@ -2382,6 +2386,12 @@ var featureCenterCss = [
2382
2386
  `[class*="sidebarCol"] [class*="collapsed"] [${MENU_LABEL_ATTRIBUTE}] { display: none; }`,
2383
2387
  `[class*="sidebarCol"] [class*="collapsed"] [${MENU_ITEM_ATTRIBUTE}] { justify-content: center; padding: 8px 0; }`,
2384
2388
  `[class*="sidebarCol"] [class*="collapsed"] [${MENU_ICON_ATTRIBUTE}], [class*="sidebarCol"] [class*="collapsed"] [${MENU_ICON_ATTRIBUTE}] > svg { width: 18px; height: 18px; }`,
2389
+ // 折叠态提示气泡:几何与配色逐项对齐框架 `ui-primitives` 的 `Tooltip.module.css`
2390
+ // (黑底白字、3px 7px 内边距、8px 圆角、13/20 字号、150ms 淡入、最大半屏宽)。
2391
+ `[${TOOLTIP_ATTRIBUTE}] { position: fixed; z-index: 100; display: none; width: max-content; max-width: 50vw; padding: 3px 7px; border-radius: 8px; background: var(--dsw-alias-tooltip-bg, #2c2c2e); color: var(--dsw-static-neutral-bluish-00, #fff); font-size: 13px; line-height: 20px; white-space: pre-line; overflow-wrap: break-word; pointer-events: none; transform: translateY(-50%); }`,
2392
+ `[${TOOLTIP_ATTRIBUTE}][${TOOLTIP_VISIBLE_ATTRIBUTE}="true"] { display: block; animation: hiwork-feature-tooltip-in 150ms var(--ds-ease-in-out, ease); }`,
2393
+ `@keyframes hiwork-feature-tooltip-in { from { opacity: 0; } }`,
2394
+ `@media (prefers-reduced-motion: reduce) { [${TOOLTIP_ATTRIBUTE}][${TOOLTIP_VISIBLE_ATTRIBUTE}="true"] { animation: none; } }`,
2385
2395
  // 与原生会话根同一背景(`background: var(--dsw-alias-bg-base)`);不显式上色的话
2386
2396
  // takeover 区会透出框架灰底,和侧栏同色而不是原生页面的白色/深色。
2387
2397
  `[${FEATURE_ROOT_ATTRIBUTE}] { display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0; overflow: hidden; background: var(--dsw-alias-bg-base, #fff); }`,
@@ -2418,6 +2428,12 @@ function nativeNewSessionButton(root) {
2418
2428
  function conversationContainer() {
2419
2429
  return document.querySelector(CONVERSATION_SELECTOR) ?? void 0;
2420
2430
  }
2431
+ function isCollapsedRail(item) {
2432
+ const host = item.closest('[class*="collapsed"]');
2433
+ if (host === null) return false;
2434
+ const column = item.closest(SIDEBAR_SELECTOR);
2435
+ return column === null || column.contains(host);
2436
+ }
2421
2437
  function mountFeatureCenter(options) {
2422
2438
  const { registry } = options;
2423
2439
  const interval = options.retryIntervalMs ?? 200;
@@ -2428,7 +2444,7 @@ function mountFeatureCenter(options) {
2428
2444
  return { dispose: () => void 0, openNativeHome: () => void 0 };
2429
2445
  }
2430
2446
  const isActiveOwner = () => activeOwner === owner;
2431
- for (const stale of Array.from(document.querySelectorAll(`[${MENU_ATTRIBUTE}], [${FEATURE_ROOT_ATTRIBUTE}], #${STYLE_ELEMENT_ID}`))) {
2447
+ for (const stale of Array.from(document.querySelectorAll(`[${MENU_ATTRIBUTE}], [${FEATURE_ROOT_ATTRIBUTE}], [${TOOLTIP_ATTRIBUTE}], #${STYLE_ELEMENT_ID}`))) {
2432
2448
  stale.remove();
2433
2449
  }
2434
2450
  for (const hidden of Array.from(document.querySelectorAll(`[${NATIVE_HIDDEN_ATTRIBUTE}]`))) {
@@ -2449,6 +2465,58 @@ function mountFeatureCenter(options) {
2449
2465
  let retryTimer;
2450
2466
  let retries = 0;
2451
2467
  let disposed = false;
2468
+ let tooltipElement;
2469
+ let tooltipTimer;
2470
+ let tooltipItem;
2471
+ const hideTooltip = () => {
2472
+ if (tooltipTimer !== void 0) {
2473
+ clearTimeout(tooltipTimer);
2474
+ tooltipTimer = void 0;
2475
+ }
2476
+ tooltipItem = void 0;
2477
+ tooltipElement?.removeAttribute(TOOLTIP_VISIBLE_ATTRIBUTE);
2478
+ };
2479
+ const ensureTooltip = () => {
2480
+ let element = tooltipElement;
2481
+ if (element === void 0) {
2482
+ element = document.createElement("div");
2483
+ element.setAttribute(TOOLTIP_ATTRIBUTE, "");
2484
+ element.setAttribute(OWNER_ATTRIBUTE, owner);
2485
+ element.setAttribute("role", "tooltip");
2486
+ document.body.appendChild(element);
2487
+ tooltipElement = element;
2488
+ }
2489
+ return element;
2490
+ };
2491
+ const placeTooltip = (item, element) => {
2492
+ const rect = item.getBoundingClientRect();
2493
+ const width = element.offsetWidth;
2494
+ const overflowRight = rect.right + TOOLTIP_GAP_PX + width > window.innerWidth;
2495
+ const left = overflowRight ? rect.left - TOOLTIP_GAP_PX - width : rect.right + TOOLTIP_GAP_PX;
2496
+ element.style.left = `${Math.max(0, left)}px`;
2497
+ element.style.top = `${rect.top + rect.height / 2}px`;
2498
+ };
2499
+ const showTooltip = (item, label) => {
2500
+ const element = ensureTooltip();
2501
+ element.textContent = label;
2502
+ element.setAttribute(TOOLTIP_VISIBLE_ATTRIBUTE, "true");
2503
+ tooltipItem = item;
2504
+ placeTooltip(item, element);
2505
+ };
2506
+ const bindTooltip = (item, label) => {
2507
+ item.addEventListener("pointerenter", () => {
2508
+ hideTooltip();
2509
+ tooltipTimer = setTimeout(() => {
2510
+ tooltipTimer = void 0;
2511
+ if (disposed || !item.isConnected || !isCollapsedRail(item)) return;
2512
+ showTooltip(item, label);
2513
+ }, TOOLTIP_DELAY_MS);
2514
+ });
2515
+ item.addEventListener("pointerleave", () => {
2516
+ if (tooltipItem === item || tooltipTimer !== void 0) hideTooltip();
2517
+ });
2518
+ };
2519
+ document.addEventListener("scroll", hideTooltip, true);
2452
2520
  const clearTakeover = () => {
2453
2521
  const reactRoot = root;
2454
2522
  root = void 0;
@@ -2494,6 +2562,7 @@ function mountFeatureCenter(options) {
2494
2562
  if (!(target instanceof Element)) return;
2495
2563
  const item = target.closest(`[${MENU_ITEM_ATTRIBUTE}]`);
2496
2564
  if (item === null || !(menuElement?.contains(item) ?? false)) return;
2565
+ hideTooltip();
2497
2566
  const id = item.getAttribute(MENU_ITEM_ATTRIBUTE);
2498
2567
  if (id === null) return;
2499
2568
  if (id === NATIVE_MENU_ITEM_ID) {
@@ -2507,7 +2576,8 @@ function mountFeatureCenter(options) {
2507
2576
  item.type = "button";
2508
2577
  item.setAttribute(MENU_ITEM_ATTRIBUTE, id);
2509
2578
  if (active) item.setAttribute("data-hiwork-feature-active", "true");
2510
- item.title = label;
2579
+ item.setAttribute("aria-label", label);
2580
+ bindTooltip(item, label);
2511
2581
  const iconSpan = document.createElement("span");
2512
2582
  iconSpan.setAttribute(MENU_ICON_ATTRIBUTE, "");
2513
2583
  iconSpan.innerHTML = icon;
@@ -2538,6 +2608,7 @@ function mountFeatureCenter(options) {
2538
2608
  ].join("|");
2539
2609
  if (signature === menuSignature) return;
2540
2610
  menuSignature = signature;
2611
+ hideTooltip();
2541
2612
  const items = [];
2542
2613
  if (native !== void 0) items.push(createMenuItem(NATIVE_MENU_ITEM_ID, newSessionLabel, nativeIcon(native), false));
2543
2614
  for (const item of features) {
@@ -2675,6 +2746,11 @@ function mountFeatureCenter(options) {
2675
2746
  unsubscribeRegistry();
2676
2747
  unsubscribeLocale?.();
2677
2748
  document.removeEventListener("click", onDocumentClickCapture, true);
2749
+ document.removeEventListener("scroll", hideTooltip, true);
2750
+ hideTooltip();
2751
+ const tooltip = tooltipElement;
2752
+ tooltipElement = void 0;
2753
+ if (tooltip !== void 0 && tooltip.getAttribute(OWNER_ATTRIBUTE) === owner) tooltip.remove();
2678
2754
  clearTakeover();
2679
2755
  const element = menuElement;
2680
2756
  menuElement = void 0;
package/lib/index.js CHANGED
@@ -3137,7 +3137,7 @@ function isUnloading(ctx) {
3137
3137
  }
3138
3138
 
3139
3139
  // src/version.ts
3140
- var PKG_VERSION = false ? "dev" : "0.0.2";
3140
+ var PKG_VERSION = false ? "dev" : "0.0.3";
3141
3141
 
3142
3142
  // src/ai-router-client.ts
3143
3143
  var GatewayError = class extends Error {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hiwork-core",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "description": "HiWork 企业统一登录与模型自动供给插件(ai-router 网关登录,Web 表单,无 CLI 认证)",
6
6
  "license": "UNLICENSED",