dsh-sidebar-recent 1.0.0 → 1.0.2

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 (2) hide show
  1. package/client.js +77 -25
  2. package/package.json +1 -1
package/client.js CHANGED
@@ -529,6 +529,7 @@ window.__ModuleLoader__.load({
529
529
  const onDown = function (event) {
530
530
  const el = ref.current;
531
531
  if (!el || el.contains(event.target)) return;
532
+ if (event.target && event.target.closest && event.target.closest('[data-menu-trigger]')) return;
532
533
  onClose();
533
534
  };
534
535
  const onKey = function (event) {
@@ -778,6 +779,7 @@ window.__ModuleLoader__.load({
778
779
  className: 'sr-icon-btn' + (props.active ? ' is-active' : '') + (props.className ? ' ' + props.className : ''),
779
780
  title: props.title,
780
781
  'aria-label': props.title,
782
+ 'data-menu-trigger': props.menuTrigger ? '1' : undefined,
781
783
  disabled: !!props.disabled,
782
784
  onClick: props.onClick
783
785
  }, h(Icon, { name: props.icon, size: props.size || 16 }));
@@ -1049,6 +1051,7 @@ window.__ModuleLoader__.load({
1049
1051
  icon: 'ellipsis',
1050
1052
  size: 14,
1051
1053
  title: props.tr('actions.session'),
1054
+ menuTrigger: true,
1052
1055
  onClick: props.onMore
1053
1056
  })));
1054
1057
  return out;
@@ -1102,6 +1105,7 @@ window.__ModuleLoader__.load({
1102
1105
  icon: 'ellipsis',
1103
1106
  size: 14,
1104
1107
  title: props.tr('actions.workspace'),
1108
+ menuTrigger: true,
1105
1109
  onClick: props.onMore
1106
1110
  }))
1107
1111
  ]);
@@ -1196,7 +1200,12 @@ window.__ModuleLoader__.load({
1196
1200
  let frame = 0;
1197
1201
  function measure() {
1198
1202
  frame = 0;
1199
- const next = Math.round(el.getBoundingClientRect().height * 100) / 100;
1203
+ const root = el.parentElement;
1204
+ if (!root) return;
1205
+ const headEl = el.previousElementSibling;
1206
+ const headH = headEl ? headEl.offsetHeight : 0;
1207
+ const raw = root.clientHeight - headH - 6;
1208
+ const next = raw > 0 ? Math.round(raw * 100) / 100 : 0;
1200
1209
  setBodyH(function (prev) { return Math.abs(prev - next) < 0.5 ? prev : next; });
1201
1210
  }
1202
1211
  function schedule() {
@@ -1206,7 +1215,7 @@ window.__ModuleLoader__.load({
1206
1215
  measure();
1207
1216
  if (typeof ResizeObserver === 'function') {
1208
1217
  const ro = new ResizeObserver(schedule);
1209
- ro.observe(el);
1218
+ ro.observe(el.parentElement || el);
1210
1219
  return function () {
1211
1220
  if (frame) window.cancelAnimationFrame(frame);
1212
1221
  ro.disconnect();
@@ -1823,7 +1832,15 @@ window.__ModuleLoader__.load({
1823
1832
  function openMenuAt(kind, event, extra) {
1824
1833
  const rect = event && event.currentTarget ? event.currentTarget.getBoundingClientRect() : null;
1825
1834
  const point = event && typeof event.clientX === 'number' ? { x: event.clientX, y: event.clientY } : null;
1826
- setMenu(Object.assign({ kind: kind, anchor: rect, point: point }, extra || {}));
1835
+ const next = Object.assign({ kind: kind, anchor: rect, point: point }, extra || {});
1836
+ setMenu(function (current) {
1837
+ if (current && current.kind === next.kind) {
1838
+ if (kind === 'view') return null;
1839
+ if (kind === 'session' && current.id === next.id) return null;
1840
+ if (kind === 'workspace' && current.group && next.group && current.group.id === next.group.id) return null;
1841
+ }
1842
+ return next;
1843
+ });
1827
1844
  }
1828
1845
 
1829
1846
  function renderSession(id, opts) {
@@ -2052,6 +2069,7 @@ window.__ModuleLoader__.load({
2052
2069
  key: 'view',
2053
2070
  type: 'button',
2054
2071
  className: 'sr-icon-btn' + (menu && menu.kind === 'view' ? ' is-active' : ''),
2072
+ 'data-menu-trigger': '1',
2055
2073
  title: tr('viewOptions.label'),
2056
2074
  'aria-label': tr('viewOptions.label'),
2057
2075
  onClick: function (event) {
@@ -2110,8 +2128,8 @@ window.__ModuleLoader__.load({
2110
2128
  const wsRatio = resizeLive && typeof resizeLive.ws === 'number'
2111
2129
  ? resizeLive.ws
2112
2130
  : (typeof view.wsRatio === 'number' ? view.wsRatio : null);
2113
- const availH = bodyH > 0
2114
- ? Math.max(120, bodyH - BODY_PAD - (HANDLE_H + BODY_GAP))
2131
+ const availH = bodyH >= 80
2132
+ ? bodyH - BODY_PAD - (HANDLE_H + BODY_GAP)
2115
2133
  : 0;
2116
2134
  let wsH = WS_HEAD_H;
2117
2135
  let recentH = WS_HEAD_H;
@@ -2121,7 +2139,8 @@ window.__ModuleLoader__.load({
2121
2139
  wsH = WS_HEAD_H;
2122
2140
  recentH = WS_HEAD_H;
2123
2141
  } else if (view.recentCollapsed) {
2124
- wsH = Math.max(WS_HEAD_H, pair - WS_HEAD_H);
2142
+ const fitH = wsContentH > 0 ? wsContentH + WS_HEAD_H : (pair - WS_HEAD_H);
2143
+ wsH = Math.max(WS_HEAD_H, Math.min(fitH, pair - WS_HEAD_H));
2125
2144
  recentH = WS_HEAD_H;
2126
2145
  } else if (view.wsCollapsed) {
2127
2146
  wsH = WS_HEAD_H;
@@ -2317,31 +2336,55 @@ window.__ModuleLoader__.load({
2317
2336
  event.preventDefault();
2318
2337
  const bodyEl = event.currentTarget.closest('.sr-body');
2319
2338
  if (!bodyEl) return;
2320
- const rect = bodyEl.getBoundingClientRect();
2321
- if (!rect.height) return;
2322
- const live = { ws: wsRatio === null ? 0.46 : wsRatio };
2323
- setResizeLive({ ws: live.ws });
2339
+ const wsEl = bodyEl.querySelector('.sr-section-ws');
2340
+ const recentEl = bodyEl.querySelector('.sr-section-recent');
2341
+ if (!wsEl || !recentEl) return;
2342
+ const rootEl = bodyEl.closest('.sr-root');
2343
+ const startWsH = wsEl.getBoundingClientRect().height;
2344
+ const startRecentH = recentEl.getBoundingClientRect().height;
2345
+ const pairH = startWsH + startRecentH;
2346
+ if (pairH <= 120) return;
2347
+ const MIN_H = 34;
2348
+ const startY = event.clientY;
2349
+ let wsH = startWsH;
2350
+ let lastY = startY;
2351
+ let rafId = 0;
2352
+ if (rootEl) rootEl.classList.add('is-resizing');
2353
+ wsEl.style.transition = 'none';
2354
+ recentEl.style.transition = 'none';
2355
+ document.body.style.userSelect = 'none';
2356
+ const paint = function () {
2357
+ rafId = 0;
2358
+ let next = startWsH + (lastY - startY);
2359
+ if (next < MIN_H) next = MIN_H;
2360
+ if (next > pairH - MIN_H) next = pairH - MIN_H;
2361
+ if (Math.abs(next - wsH) < 0.5) return;
2362
+ wsH = next;
2363
+ wsEl.style.height = next + 'px';
2364
+ recentEl.style.height = (pairH - next) + 'px';
2365
+ };
2324
2366
  const onMove = function (moveEvent) {
2325
- const ratio = (moveEvent.clientY - rect.top) / rect.height;
2326
- live.ws = Math.min(0.9, Math.max(0.12, ratio));
2327
- setResizeLive({ ws: live.ws });
2367
+ lastY = moveEvent.clientY;
2368
+ if (rafId) return;
2369
+ rafId = window.requestAnimationFrame(paint);
2328
2370
  };
2329
- const stop = function () {
2371
+ const finish = function () {
2330
2372
  document.removeEventListener('pointermove', onMove);
2331
2373
  document.removeEventListener('mousemove', onMove);
2332
- document.removeEventListener('pointerup', stop);
2333
- document.removeEventListener('mouseup', stop);
2374
+ document.removeEventListener('pointerup', finish);
2375
+ document.removeEventListener('mouseup', finish);
2376
+ if (rafId) { window.cancelAnimationFrame(rafId); rafId = 0; }
2334
2377
  document.body.style.cursor = '';
2335
2378
  document.body.style.userSelect = '';
2336
- setResizeLive(null);
2337
- patchView({ wsRatio: Math.round(live.ws * 1000) / 1000, recentRatio: null });
2379
+ wsEl.style.transition = '';
2380
+ recentEl.style.transition = '';
2381
+ if (rootEl) rootEl.classList.remove('is-resizing');
2382
+ patchView({ wsRatio: Math.round((wsH / pairH) * 1000) / 1000, recentRatio: null });
2338
2383
  };
2339
2384
  document.addEventListener('pointermove', onMove);
2340
2385
  document.addEventListener('mousemove', onMove);
2341
- document.addEventListener('pointerup', stop);
2342
- document.addEventListener('mouseup', stop);
2343
- document.body.style.cursor = 'row-resize';
2344
- document.body.style.userSelect = 'none';
2386
+ document.addEventListener('pointerup', finish);
2387
+ document.addEventListener('mouseup', finish);
2345
2388
  };
2346
2389
  }
2347
2390
 
@@ -2376,6 +2419,7 @@ window.__ModuleLoader__.load({
2376
2419
  key: 'body',
2377
2420
  ref: bodyRef,
2378
2421
  className: 'sr-body'
2422
+ + (availH > 0 ? ' is-sized' : '')
2379
2423
  + (view.wsCollapsed ? ' is-ws-collapsed' : '')
2380
2424
  + (view.recentCollapsed ? ' is-recent-collapsed' : '')
2381
2425
  }, query.trim() ? renderSearchResults() : [
@@ -2452,19 +2496,22 @@ window.__ModuleLoader__.load({
2452
2496
  '.sr-body{position:relative;flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:4px;padding-top:2px}',
2453
2497
  '.sr-section{display:flex;flex-direction:column;min-height:0;border-radius:10px;overflow:hidden;transition:height .3s cubic-bezier(.4,0,.2,1),flex-grow .3s cubic-bezier(.4,0,.2,1),flex-basis .3s cubic-bezier(.4,0,.2,1),min-height .3s cubic-bezier(.4,0,.2,1);background:rgba(127,127,127,.055);background:color-mix(in srgb,var(--dsw-alias-bg-layer-2,#f4f4f5) 46%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-border-l1,rgba(0,0,0,.08)) 66%,transparent);box-shadow:inset 0 1px 0 rgba(255,255,255,.06);backdrop-filter:blur(10px) saturate(140%);-webkit-backdrop-filter:blur(10px) saturate(140%)}',
2454
2498
  '.sr-section-ws{flex:0 0 auto;min-height:0;overflow:hidden}',
2499
+ '.sr-body:not(.is-sized) .sr-section-ws{flex:0 0 auto;max-height:62%}',
2455
2500
  '.sr-section-recent{flex:0 0 auto;min-height:34px;overflow:hidden}',
2501
+ '.sr-body:not(.is-sized) .sr-section-recent{flex:1 1 0;min-height:34px}',
2456
2502
 
2457
2503
  '.sr-section-body{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;overflow:hidden}',
2458
2504
  '.sr-section-inner{flex:1 1 auto;min-height:0;overflow:hidden;display:flex;flex-direction:column}',
2459
2505
  '.sr-root.is-animating .sr-scroll{-webkit-mask-image:none;mask-image:none}',
2460
2506
  '.sr-root.is-animating .sr-section{will-change:height}',
2461
- '.sr-resize{position:relative;flex:none;height:10px;margin:0 4px -3px;display:flex;align-items:center;justify-content:center;cursor:row-resize;border-radius:6px;touch-action:none;user-select:none;opacity:0;transition:opacity .18s ease,height .3s cubic-bezier(.4,0,.2,1),margin .3s cubic-bezier(.4,0,.2,1)}',
2507
+ '.sr-resize{position:relative;flex:none;height:10px;margin:0 4px -3px;display:flex;align-items:center;justify-content:center;cursor:default;border-radius:6px;touch-action:none;user-select:none;opacity:0;transition:opacity .18s ease,height .3s cubic-bezier(.4,0,.2,1),margin .3s cubic-bezier(.4,0,.2,1)}',
2462
2508
  '.sr-body.is-ws-collapsed .sr-resize,.sr-body.is-recent-collapsed .sr-resize{opacity:0;pointer-events:none}',
2463
2509
  '.sr-resize::before{content:"";position:absolute;left:0;right:0;top:-3px;bottom:-3px}',
2464
2510
  '.sr-resize:hover,.sr-resize.is-dragging{opacity:1}',
2465
2511
  '.sr-resize:hover{background:color-mix(in srgb,var(--dsw-alias-interactive-bg-hover,rgba(127,127,127,.14)) 75%,transparent)}',
2466
2512
  '.sr-resize-grip{width:40px;height:3px;border-radius:2px;background:var(--dsw-alias-border-l2,rgba(0,0,0,.18));transition:background .12s ease,width .12s ease}',
2467
- '.sr-resize:hover .sr-resize-grip,.sr-resize.is-dragging .sr-resize-grip{background:var(--dsw-alias-brand-primary,#4d6bfe);width:44px}',
2513
+ '.sr-resize:hover .sr-resize-grip{width:44px;background:rgba(0,0,0,.30);background:color-mix(in srgb,var(--dsw-alias-label-primary,#111) 30%,transparent)}',
2514
+ '.sr-root.is-resizing .sr-resize-grip{width:46px;background:rgba(0,0,0,.52);background:color-mix(in srgb,var(--dsw-alias-label-primary,#111) 52%,transparent)}',
2468
2515
  '.sr-root[data-panel="blend"] .sr-glass{opacity:0}',
2469
2516
  '.sr-root[data-panel="blend"] .sr-section{background:transparent;border-color:transparent;box-shadow:none;border-radius:6px;backdrop-filter:none;-webkit-backdrop-filter:none}',
2470
2517
  '.sr-root[data-panel="contrast"] .sr-glass{background:linear-gradient(180deg,color-mix(in srgb,var(--dsw-alias-bg-layer-1,#fff) 52%,transparent),color-mix(in srgb,var(--dsw-alias-bg-base,#fff) 28%,transparent))}',
@@ -2476,10 +2523,11 @@ window.__ModuleLoader__.load({
2476
2523
  '.sr-collapse:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(127,127,127,.14))}',
2477
2524
  '.sr-collapse svg{transform:rotate(90deg);transition:transform .16s ease}',
2478
2525
  '.sr-collapse.is-collapsed svg{transform:rotate(0deg)}',
2479
- '.sr-scroll{flex:1 1 0;min-height:0;overflow-y:auto;overflow-x:hidden;padding:12px 1px 11px;scrollbar-gutter:stable;-webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 12px,#000 calc(100% - 12px),transparent 100%);mask-image:linear-gradient(to bottom,transparent 0,#000 12px,#000 calc(100% - 12px),transparent 100%)}',
2526
+ '.sr-scroll{flex:1 1 0;min-height:0;overflow-y:auto;overflow-x:hidden;padding:12px 1px 10px;scrollbar-gutter:stable;-webkit-mask-image:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.30) 4px,rgba(0,0,0,.78) 7px,#000 10px,#000 calc(100% - 10px),rgba(0,0,0,.78) calc(100% - 7px),rgba(0,0,0,.30) calc(100% - 4px),transparent 100%);mask-image:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.30) 4px,rgba(0,0,0,.78) 7px,#000 10px,#000 calc(100% - 10px),rgba(0,0,0,.78) calc(100% - 7px),rgba(0,0,0,.30) calc(100% - 4px),transparent 100%)}',
2480
2527
  '.sr-section-ws .sr-scroll{flex:0 1 auto}',
2481
2528
  '.sr-section-inner .sr-scroll{flex:1 1 auto;min-height:0}',
2482
2529
  '.sr-section-recent .sr-scroll{display:flex;flex-direction:column;gap:5px}',
2530
+ '.sr-section-recent .sr-scroll{padding-top:6px}',
2483
2531
  '.sr-scroll::-webkit-scrollbar{width:5px}',
2484
2532
  '.sr-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--dsw-alias-label-tertiary,rgba(0,0,0,.3)) 42%,transparent);border-radius:3px}',
2485
2533
  '.sr-scroll::-webkit-scrollbar-track{background:transparent}',
@@ -2513,6 +2561,9 @@ window.__ModuleLoader__.load({
2513
2561
  '.sr-row-snippet{font-size:10.5px;color:var(--dsw-alias-label-primary,#111);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}',
2514
2562
  '.sr-group{margin-bottom:0}',
2515
2563
  '.sr-group-list{display:flex;flex-direction:column;gap:5px}',
2564
+ '.sr-group:has(.sr-group-body.is-open){margin-bottom:3px}',
2565
+ '.sr-root.is-resizing .sr-section{transition:none !important}',
2566
+ '.sr-root.is-resizing .sr-resize{opacity:1}',
2516
2567
  '.sr-ws-row{display:flex;flex:0 0 auto;align-items:center;border-radius:10px;transition:background .16s ease,box-shadow .16s ease}',
2517
2568
  '.sr-ws-row:hover{background:rgba(0,0,0,.04);background:color-mix(in srgb,var(--dsw-alias-label-primary,#111) 5%,transparent);box-shadow:0 1px 2px rgba(0,0,0,.05)}',
2518
2569
  '.sr-ws-head{display:flex;align-items:center;gap:5px;flex:1 1 auto;min-width:0;height:32px;padding:0 7px 0 5px;border:none;background:transparent;cursor:pointer;text-align:left;font-family:inherit;font-size:var(--sr-fs-group);font-weight:400;color:var(--dsw-alias-label-primary,#111)}',
@@ -2540,6 +2591,7 @@ window.__ModuleLoader__.load({
2540
2591
  '.sr-results-label{padding:8px 6px 3px;font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--dsw-alias-label-primary,#111)}',
2541
2592
  '.sr-results-note{padding:6px;font-size:11px;color:var(--dsw-alias-label-primary,#111)}',
2542
2593
  '.sr-menu{position:fixed;z-index:1200;min-width:170px;max-width:212px;max-height:min(86vh,900px);overflow-y:auto;overscroll-behavior:contain;padding:4px;border-radius:var(--dsw-radius-lg,10px);background:#FCFDFD;background:color-mix(in srgb,#FCFDFD 88%,transparent);-webkit-backdrop-filter:blur(26px) saturate(180%);backdrop-filter:blur(26px) saturate(180%);border:.5px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1));box-shadow:var(--dsw-elevation-prominent,0 12px 28px rgba(0,0,0,.16),0 2px 6px rgba(0,0,0,.08));animation:sr-fade .12s ease}',
2594
+ 'body[data-ds-dark-theme] .sr-menu{background:#29292D;background:color-mix(in srgb,#29292D 90%,transparent);border-color:rgba(255,255,255,.10);box-shadow:var(--dsw-elevation-prominent,0 12px 28px rgba(0,0,0,.52),0 2px 6px rgba(0,0,0,.34))}',
2543
2595
  '.sr-menu::-webkit-scrollbar{width:5px}',
2544
2596
  '.sr-menu::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--dsw-alias-label-tertiary,rgba(0,0,0,.3)) 42%,transparent);border-radius:3px}',
2545
2597
  '.sr-menu-chips{display:flex;align-items:center;gap:6px;padding:2px 8px 6px}',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-sidebar-recent",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Sidebar Recent: a project-grouped session browser with a chronological Recent list for DeepSeek Harness.",