@trendr/core 0.4.9 → 0.4.11

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
@@ -305,15 +305,15 @@ const { status, data } = useAsync(fetchUsers, { immediate: true })
305
305
 
306
306
  ```jsx
307
307
  useMouse((event) => {
308
- // event.action: 'press' | 'release' | 'drag' | 'scroll'
309
- // event.button: 'left' | 'middle' | 'right' (press/release only)
310
- // event.direction: 'up' | 'down' (scroll only)
308
+ // event.action: 'press' | 'release' | 'drag' | 'move' | 'scroll'
309
+ // event.button: 'left' | 'middle' | 'right' (press/release/drag only)
310
+ // event.direction: 'up' | 'down' | 'left' | 'right' (scroll only)
311
311
  // event.x, event.y: 0-based terminal coordinates
312
312
  // event.stopPropagation(): prevent other handlers from receiving this event
313
313
  })
314
314
  ```
315
315
 
316
- Mouse is enabled automatically. Built-in components support click, scroll wheel, and scrollbar dragging.
316
+ Mouse is enabled automatically. Passive pointer movement is reported as `move`, so it can be combined with `useLayout()` to derive hover state. Built-in components support click, scroll wheel, and scrollbar dragging.
317
317
 
318
318
  ### useStdout
319
319
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trendr/core",
3
- "version": "0.4.9",
3
+ "version": "0.4.11",
4
4
  "description": "direct-mode TUI renderer with JSX, signals, and per-cell diffing",
5
5
  "license": "MIT",
6
6
  "author": "Jonathan Pyers",
package/src/ansi.js CHANGED
@@ -19,8 +19,8 @@ export const sgrReset = `${ESC}0m`
19
19
  export const setTitle = (title) => `\x1b]2;${title}\x07`
20
20
  export const osc52Copy = (text) => `\x1b]52;c;${Buffer.from(text, 'utf8').toString('base64')}\x07`
21
21
 
22
- export const enableMouse = `${ESC}?1002h${ESC}?1006h`
23
- export const disableMouse = `${ESC}?1002l${ESC}?1006l`
22
+ export const enableMouse = `${ESC}?1003h${ESC}?1006h`
23
+ export const disableMouse = `${ESC}?1003l${ESC}?1006l`
24
24
 
25
25
  export const BOLD = 1
26
26
  export const DIM = 2
@@ -28,6 +28,9 @@ export const ITALIC = 4
28
28
  export const UNDERLINE = 8
29
29
  export const INVERSE = 16
30
30
  export const STRIKETHROUGH = 32
31
+ // never emitted as sgr: marks ui chrome cells (scrollbars, counters) that
32
+ // text selection should skip when extracting copy text
33
+ export const COPY_IGNORE = 64
31
34
 
32
35
  const ATTR_CODES = [
33
36
  [BOLD, '1'],
package/src/diff-view.js CHANGED
@@ -236,7 +236,7 @@ export function Diff({
236
236
  const isThumb = i >= thumbStart && i < thumbStart + thumbH
237
237
  bar.push(jsx('text', {
238
238
  key: i,
239
- style: { color: isThumb ? palette.lineNo : palette.lineNo, dim: !isThumb },
239
+ style: { color: palette.lineNo, dim: !isThumb, copyIgnore: true },
240
240
  children: isThumb ? '█' : '│',
241
241
  }))
242
242
  }
package/src/dropdown.js CHANGED
@@ -126,7 +126,7 @@ export function Dropdown({ items, cursor, scroll, visibleCount, width, onSubmit,
126
126
  children: [
127
127
  content,
128
128
  jsx('text', {
129
- style: { color: barIsThumb ? s.accent : muted, dim: !barIsThumb },
129
+ style: { color: barIsThumb ? s.accent : muted, dim: !barIsThumb, copyIgnore: true },
130
130
  children: ' ' + (barIsThumb ? '█' : '│'),
131
131
  }),
132
132
  ],
package/src/input.js CHANGED
@@ -53,6 +53,8 @@ export function parseMouse(raw) {
53
53
  return { type: 'mouse', action: 'scroll', direction, x, y }
54
54
  }
55
55
 
56
+ if (motion && button === 3) return { type: 'mouse', action: 'move', x, y }
57
+
56
58
  const buttonName = extended
57
59
  ? (button === 0 ? 'back' : button === 1 ? 'forward' : button === 2 ? 'button10' : 'button11')
58
60
  : (button === 0 ? 'left' : button === 1 ? 'middle' : 'right')
package/src/list.js CHANGED
@@ -190,7 +190,7 @@ export function List({ items = [], selected: selectedProp, onSelect, onCursorCha
190
190
  barChildren.push(
191
191
  jsx('text', {
192
192
  key: i,
193
- style: { color: isThumb ? (focused ? accent : muted) : muted, dim: !isThumb },
193
+ style: { color: isThumb ? (focused ? accent : muted) : muted, dim: !isThumb, copyIgnore: true },
194
194
  children: isThumb ? '\u2588' : '\u2502',
195
195
  })
196
196
  )
package/src/renderer.js CHANGED
@@ -98,6 +98,7 @@ function resolveAttrs(style) {
98
98
  if (style.underline) attrs |= ansi.UNDERLINE
99
99
  if (style.inverse) attrs |= ansi.INVERSE
100
100
  if (style.strikethrough) attrs |= ansi.STRIKETHROUGH
101
+ if (style.copyIgnore) attrs |= ansi.COPY_IGNORE
101
102
  return attrs
102
103
  }
103
104
 
package/src/scroll-box.js CHANGED
@@ -93,7 +93,7 @@ export function ScrollBox({ children, focused = true, scrollOffset: offsetProp,
93
93
  barChildren.push(
94
94
  jsx('text', {
95
95
  key: i,
96
- style: { color: isThumb ? (focused ? accent : muted) : muted, dim: !isThumb },
96
+ style: { color: isThumb ? (focused ? accent : muted) : muted, dim: !isThumb, copyIgnore: true },
97
97
  children: isThumb ? thumbChar : trackChar,
98
98
  })
99
99
  )
@@ -89,7 +89,7 @@ export function ScrollableText({ content = '', focused = true, scrollOffset: off
89
89
  style: { flexDirection: 'row', height: 1 },
90
90
  children: [
91
91
  jsx('text', { style: { flexGrow: 1, ...textStyle }, children: line || ' ' }),
92
- jsx('text', { style: { color: barColor, dim: !isThumb }, children: ' ' + barChar }),
92
+ jsx('text', { style: { color: barColor, dim: !isThumb, copyIgnore: true }, children: ' ' + barChar }),
93
93
  ],
94
94
  })
95
95
  })
package/src/selection.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useMouse } from './hooks.js'
2
2
  import { getContext, registerHook } from './renderer.js'
3
- import { osc52Copy } from './ansi.js'
3
+ import { osc52Copy, COPY_IGNORE } from './ansi.js'
4
4
 
5
5
  function normalize(a, b) {
6
6
  const forward = a.y < b.y || (a.y === b.y && a.x <= b.x)
@@ -22,8 +22,10 @@ export function extractSelectionText(buf, sel) {
22
22
  const to = y === sel.ey ? Math.min(sel.ex, buf.width - 1) : buf.width - 1
23
23
  let text = ''
24
24
  for (let x = 0; x <= to; x++) {
25
- const ch = buf.cells[y * buf.width + x].ch
26
- if (ch === '') continue
25
+ const cell = buf.cells[y * buf.width + x]
26
+ if (cell.ch === '') continue
27
+ // chrome cells (scrollbars, counters) never belong in copied text
28
+ const ch = cell.attrs & COPY_IGNORE ? ' ' : cell.ch
27
29
  text += y === sel.sy && x < sel.sx ? ' ' : ch
28
30
  }
29
31
  rows.push({ text: text.replace(/\s+$/, ''), soft: !!buf.softWrap[y] })
package/src/text-area.js CHANGED
@@ -372,7 +372,7 @@ export function TextArea({ onSubmit, onCancel, onChange, onKeyDown, placeholder,
372
372
  const counter = counterActive
373
373
  ? jsx('box', {
374
374
  style: { flexDirection: 'row', height: 1 },
375
- children: jsx('text', { style: { color: muted, dim: true }, children: `${displayPos.row + 1}/${lineMap.length}` }),
375
+ children: jsx('text', { style: { color: muted, dim: true, copyIgnore: true }, children: `${displayPos.row + 1}/${lineMap.length}` }),
376
376
  })
377
377
  : null
378
378