@trendr/core 0.4.14 → 0.4.15
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/package.json +1 -1
- package/src/focus.js +9 -3
- package/src/scroll-box.js +16 -1
package/package.json
CHANGED
package/src/focus.js
CHANGED
|
@@ -79,13 +79,14 @@ export function useFocus({ initial, cycle = 'tab' } = {}) {
|
|
|
79
79
|
return state.items.filter(i => i.gen === state.gen).sort((a, b) => a.seq - b.seq)
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
function item(name) {
|
|
82
|
+
function item(name, layout) {
|
|
83
83
|
const existing = state.items.find(i => i.name === name)
|
|
84
84
|
if (existing) {
|
|
85
85
|
existing.gen = state.gen
|
|
86
86
|
existing.seq = state.seq++
|
|
87
|
+
existing.layout = layout
|
|
87
88
|
} else {
|
|
88
|
-
state.items.push({ name, type: 'item', gen: state.gen, seq: state.seq
|
|
89
|
+
state.items.push({ name, type: 'item', gen: state.gen, seq: state.seq++, layout })
|
|
89
90
|
}
|
|
90
91
|
if (state.current() == null) state.setCurrent(name)
|
|
91
92
|
}
|
|
@@ -157,6 +158,11 @@ export function useFocus({ initial, cycle = 'tab' } = {}) {
|
|
|
157
158
|
return state.current()
|
|
158
159
|
}
|
|
159
160
|
|
|
161
|
+
function currentLayout() {
|
|
162
|
+
const name = state.current()
|
|
163
|
+
return state.items.find(i => i.name === name)?.layout ?? null
|
|
164
|
+
}
|
|
165
|
+
|
|
160
166
|
function findTopLevel(cur, items) {
|
|
161
167
|
const parent = state.nameToParent.get(cur)
|
|
162
168
|
if (parent) return items.findIndex(i => i.name === parent)
|
|
@@ -220,5 +226,5 @@ export function useFocus({ initial, cycle = 'tab' } = {}) {
|
|
|
220
226
|
}
|
|
221
227
|
})
|
|
222
228
|
|
|
223
|
-
return { item, group, is, focus, push, pop, current }
|
|
229
|
+
return { item, group, is, focus, push, pop, current, currentLayout }
|
|
224
230
|
}
|
package/src/scroll-box.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from '../jsx-runtime.js'
|
|
|
2
2
|
import { createSignal } from './signal.js'
|
|
3
3
|
import { useInput, useMouse, useLayout, useTheme, useScrollDrag } from './hooks.js'
|
|
4
4
|
|
|
5
|
-
export function ScrollBox({ children, focused = true, scrollOffset: offsetProp, onScroll, scrollbar = false, gap = 0, thumbChar = '\u2588', trackChar = '\u2502', style: userStyle }) {
|
|
5
|
+
export function ScrollBox({ children, focused = true, followFocus, focusPadding = 0, scrollOffset: offsetProp, onScroll, scrollbar = false, gap = 0, thumbChar = '\u2588', trackChar = '\u2502', style: userStyle }) {
|
|
6
6
|
const { accent = 'cyan', muted = 'gray' } = useTheme()
|
|
7
7
|
const [offsetInternal, setOffsetInternal] = createSignal(0)
|
|
8
8
|
const layout = useLayout()
|
|
@@ -22,6 +22,21 @@ export function ScrollBox({ children, focused = true, scrollOffset: offsetProp,
|
|
|
22
22
|
const clamp = (v) => Math.max(0, Math.min(maxOffset, v))
|
|
23
23
|
const clamped = clamp(offset)
|
|
24
24
|
|
|
25
|
+
if (followFocus) {
|
|
26
|
+
const target = typeof followFocus === 'function' ? followFocus() : followFocus.currentLayout?.()
|
|
27
|
+
if (target && visibleH > 0) {
|
|
28
|
+
const top = target.y - layout.y + clamped
|
|
29
|
+
const bottom = top + Math.max(1, target.height ?? 1)
|
|
30
|
+
const padding = Math.max(0, focusPadding)
|
|
31
|
+
const next = top < clamped + padding
|
|
32
|
+
? top - padding
|
|
33
|
+
: bottom > clamped + visibleH - padding
|
|
34
|
+
? bottom - visibleH + padding
|
|
35
|
+
: clamped
|
|
36
|
+
if (clamp(next) !== clamped) setOffset(next)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
25
40
|
useInput(({ key, ctrl }) => {
|
|
26
41
|
if (!focused) return
|
|
27
42
|
if (contentH <= visibleH) return
|