panelui-native 0.7.0 → 0.9.0
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/lib/module/components/attachment/index.js +219 -0
- package/lib/module/components/attachment/index.js.map +1 -0
- package/lib/module/components/bottom-sheet/index.js +15 -1
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/dialog/index.js +6 -2
- package/lib/module/components/dialog/index.js.map +1 -1
- package/lib/module/components/empty-state/index.js +94 -17
- package/lib/module/components/empty-state/index.js.map +1 -1
- package/lib/module/components/line-chart/index.js +1024 -0
- package/lib/module/components/line-chart/index.js.map +1 -0
- package/lib/module/components/marker/index.js +190 -0
- package/lib/module/components/marker/index.js.map +1 -0
- package/lib/module/components/message/index.js +24 -8
- package/lib/module/components/message/index.js.map +1 -1
- package/lib/module/components/message-scroller/index.js +451 -0
- package/lib/module/components/message-scroller/index.js.map +1 -0
- package/lib/module/components/popover/index.js +500 -0
- package/lib/module/components/popover/index.js.map +1 -0
- package/lib/module/components/radio-group/index.js +104 -16
- package/lib/module/components/radio-group/index.js.map +1 -1
- package/lib/module/components/separator/index.js +91 -0
- package/lib/module/components/separator/index.js.map +1 -0
- package/lib/module/components/surface/index.js +21 -2
- package/lib/module/components/surface/index.js.map +1 -1
- package/lib/module/icons/index.js +69 -0
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +7 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/primitives/scrim.js +72 -0
- package/lib/module/primitives/scrim.js.map +1 -0
- package/lib/typescript/src/components/attachment/index.d.ts +93 -0
- package/lib/typescript/src/components/attachment/index.d.ts.map +1 -0
- package/lib/typescript/src/components/bottom-sheet/index.d.ts +6 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/dialog/index.d.ts +7 -1
- package/lib/typescript/src/components/dialog/index.d.ts.map +1 -1
- package/lib/typescript/src/components/empty-state/index.d.ts +152 -2
- package/lib/typescript/src/components/empty-state/index.d.ts.map +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts +247 -0
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -0
- package/lib/typescript/src/components/marker/index.d.ts +137 -0
- package/lib/typescript/src/components/marker/index.d.ts.map +1 -0
- package/lib/typescript/src/components/message/index.d.ts +8 -1
- package/lib/typescript/src/components/message/index.d.ts.map +1 -1
- package/lib/typescript/src/components/message-scroller/index.d.ts +150 -0
- package/lib/typescript/src/components/message-scroller/index.d.ts.map +1 -0
- package/lib/typescript/src/components/popover/index.d.ts +130 -0
- package/lib/typescript/src/components/popover/index.d.ts.map +1 -0
- package/lib/typescript/src/components/radio-group/index.d.ts +32 -0
- package/lib/typescript/src/components/radio-group/index.d.ts.map +1 -1
- package/lib/typescript/src/components/separator/index.d.ts +47 -0
- package/lib/typescript/src/components/separator/index.d.ts.map +1 -0
- package/lib/typescript/src/components/surface/index.d.ts +51 -2
- package/lib/typescript/src/components/surface/index.d.ts.map +1 -1
- package/lib/typescript/src/icons/index.d.ts +6 -0
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +7 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/primitives/scrim.d.ts +21 -0
- package/lib/typescript/src/primitives/scrim.d.ts.map +1 -0
- package/package.json +5 -1
- package/src/components/attachment/index.tsx +279 -0
- package/src/components/bottom-sheet/index.tsx +20 -0
- package/src/components/dialog/index.tsx +10 -1
- package/src/components/empty-state/index.tsx +60 -14
- package/src/components/line-chart/index.tsx +1224 -0
- package/src/components/marker/index.tsx +194 -0
- package/src/components/message/index.tsx +29 -5
- package/src/components/message-scroller/index.tsx +574 -0
- package/src/components/popover/index.tsx +599 -0
- package/src/components/radio-group/index.tsx +108 -17
- package/src/components/separator/index.tsx +97 -0
- package/src/components/surface/index.tsx +29 -3
- package/src/icons/index.tsx +48 -0
- package/src/index.ts +60 -0
- package/src/primitives/scrim.tsx +95 -0
- package/theme.css +58 -0
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MessageScroller — the scroll behaviour a chat transcript needs.
|
|
5
|
+
*
|
|
6
|
+
* A transcript is the one list where the interesting end is the bottom, the
|
|
7
|
+
* content grows while you are reading it, and history is added to the top. A
|
|
8
|
+
* plain scroll view gets all three wrong: it opens at the top, it stays put
|
|
9
|
+
* while a reply streams in below the fold, and it jumps a screen when older
|
|
10
|
+
* messages load. This owns those three behaviours so a screen does not have to
|
|
11
|
+
* rebuild them.
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <MessageScroller autoScroll className="flex-1">
|
|
15
|
+
* <MessageScroller.Viewport>
|
|
16
|
+
* <MessageScroller.Content>
|
|
17
|
+
* {messages.map((m) => (
|
|
18
|
+
* <MessageScroller.Item key={m.id} messageId={m.id} scrollAnchor={m.role === 'user'}>
|
|
19
|
+
* <Message>…</Message>
|
|
20
|
+
* </MessageScroller.Item>
|
|
21
|
+
* ))}
|
|
22
|
+
* </MessageScroller.Content>
|
|
23
|
+
* </MessageScroller.Viewport>
|
|
24
|
+
* <MessageScroller.Button />
|
|
25
|
+
* </MessageScroller>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* The rule behind every part of it: **the reader's position is theirs**. New
|
|
29
|
+
* content follows the bottom only while they are already at the bottom, and
|
|
30
|
+
* scrolling away hands control back to them until they ask for it again.
|
|
31
|
+
* Content added above them never moves what they are looking at.
|
|
32
|
+
*
|
|
33
|
+
* Needs a bounded height — from `flex-1` in a column, or an explicit one.
|
|
34
|
+
* Given an unbounded parent it grows to fit its content and never scrolls.
|
|
35
|
+
*/
|
|
36
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
37
|
+
import { View } from 'react-native';
|
|
38
|
+
import Animated, { runOnJS, useAnimatedRef, useAnimatedScrollHandler, useAnimatedStyle, useDerivedValue, useSharedValue, withTiming } from 'react-native-reanimated';
|
|
39
|
+
import { useCSSVariable } from 'uniwind';
|
|
40
|
+
import { ChevronDownIcon } from "../../icons/index.js";
|
|
41
|
+
import { AnimatedPressable } from "../../primitives/animated-pressable.js";
|
|
42
|
+
import { cn } from "../../utils/cn.js";
|
|
43
|
+
|
|
44
|
+
/** Within this many pixels of the bottom still counts as being at the bottom. */
|
|
45
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
46
|
+
const END_THRESHOLD = 24;
|
|
47
|
+
/**
|
|
48
|
+
* How much of the previous turn is left showing above an anchored one. Scrolling
|
|
49
|
+
* a turn flush to the top reads as content having been cut off; a sliver of the
|
|
50
|
+
* message before it says "this is where you are", not "this is the beginning".
|
|
51
|
+
*/
|
|
52
|
+
const ANCHOR_PEEK = 24;
|
|
53
|
+
const MessageScrollerContext = /*#__PURE__*/createContext(null);
|
|
54
|
+
function useScroller(component) {
|
|
55
|
+
const context = useContext(MessageScrollerContext);
|
|
56
|
+
if (!context) {
|
|
57
|
+
throw new Error(`${component} must be used within a <MessageScroller>`);
|
|
58
|
+
}
|
|
59
|
+
return context;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Scroll commands, for a control that lives outside the viewport. */
|
|
63
|
+
export function useMessageScroller() {
|
|
64
|
+
const {
|
|
65
|
+
scrollToEnd,
|
|
66
|
+
scrollToStart,
|
|
67
|
+
scrollToMessage
|
|
68
|
+
} = useScroller('useMessageScroller');
|
|
69
|
+
return {
|
|
70
|
+
scrollToEnd,
|
|
71
|
+
scrollToStart,
|
|
72
|
+
scrollToMessage
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Where the reader is: the turn they are inside, and whether they are at the
|
|
78
|
+
* live edge. Both settle after a scroll rather than updating per frame — this
|
|
79
|
+
* is for a header that names the current turn, not for anything animated.
|
|
80
|
+
*/
|
|
81
|
+
export function useMessageScrollerVisibility() {
|
|
82
|
+
const {
|
|
83
|
+
currentAnchorId,
|
|
84
|
+
atEndJS
|
|
85
|
+
} = useScroller('useMessageScrollerVisibility');
|
|
86
|
+
return {
|
|
87
|
+
currentAnchorId,
|
|
88
|
+
atEnd: atEndJS
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function MessageScrollerRoot({
|
|
92
|
+
className,
|
|
93
|
+
autoScroll = false,
|
|
94
|
+
preserveScrollOnPrepend = true,
|
|
95
|
+
defaultScrollPosition = 'end',
|
|
96
|
+
children,
|
|
97
|
+
...props
|
|
98
|
+
}) {
|
|
99
|
+
const scrollRef = useAnimatedRef();
|
|
100
|
+
const atEnd = useSharedValue(1);
|
|
101
|
+
const [atEndJS, setAtEndJS] = useState(true);
|
|
102
|
+
const [currentAnchorId, setCurrentAnchorId] = useState(null);
|
|
103
|
+
const itemY = useRef(new Map());
|
|
104
|
+
const anchors = useRef([]);
|
|
105
|
+
const following = useRef(autoScroll);
|
|
106
|
+
const registerItem = useCallback((id, y, anchor) => {
|
|
107
|
+
itemY.current.set(id, y);
|
|
108
|
+
const list = anchors.current;
|
|
109
|
+
if (anchor && !list.includes(id)) list.push(id);
|
|
110
|
+
if (!anchor && list.includes(id)) anchors.current = list.filter(a => a !== id);
|
|
111
|
+
}, []);
|
|
112
|
+
const unregisterItem = useCallback(id => {
|
|
113
|
+
itemY.current.delete(id);
|
|
114
|
+
anchors.current = anchors.current.filter(a => a !== id);
|
|
115
|
+
}, []);
|
|
116
|
+
const scrollToEnd = useCallback((animated = true) => {
|
|
117
|
+
following.current = true;
|
|
118
|
+
scrollRef.current?.scrollToEnd({
|
|
119
|
+
animated
|
|
120
|
+
});
|
|
121
|
+
}, [scrollRef]);
|
|
122
|
+
const scrollToStart = useCallback((animated = true) => {
|
|
123
|
+
following.current = false;
|
|
124
|
+
scrollRef.current?.scrollTo({
|
|
125
|
+
y: 0,
|
|
126
|
+
animated
|
|
127
|
+
});
|
|
128
|
+
}, [scrollRef]);
|
|
129
|
+
const scrollToMessage = useCallback((id, animated = true) => {
|
|
130
|
+
const y = itemY.current.get(id);
|
|
131
|
+
if (y === undefined) return;
|
|
132
|
+
following.current = false;
|
|
133
|
+
scrollRef.current?.scrollTo({
|
|
134
|
+
y: Math.max(0, y - ANCHOR_PEEK),
|
|
135
|
+
animated
|
|
136
|
+
});
|
|
137
|
+
}, [scrollRef]);
|
|
138
|
+
const context = useMemo(() => ({
|
|
139
|
+
scrollRef,
|
|
140
|
+
atEnd,
|
|
141
|
+
atEndJS,
|
|
142
|
+
setAtEndJS,
|
|
143
|
+
autoScroll,
|
|
144
|
+
preserveScrollOnPrepend,
|
|
145
|
+
defaultScrollPosition,
|
|
146
|
+
itemY,
|
|
147
|
+
anchors,
|
|
148
|
+
following,
|
|
149
|
+
registerItem,
|
|
150
|
+
unregisterItem,
|
|
151
|
+
scrollToEnd,
|
|
152
|
+
scrollToStart,
|
|
153
|
+
scrollToMessage,
|
|
154
|
+
currentAnchorId,
|
|
155
|
+
setCurrentAnchorId
|
|
156
|
+
}), [scrollRef, atEnd, atEndJS, autoScroll, preserveScrollOnPrepend, defaultScrollPosition, registerItem, unregisterItem, scrollToEnd, scrollToStart, scrollToMessage, currentAnchorId]);
|
|
157
|
+
return /*#__PURE__*/_jsx(MessageScrollerContext.Provider, {
|
|
158
|
+
value: context,
|
|
159
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
160
|
+
className: cn('relative overflow-hidden', className),
|
|
161
|
+
...props,
|
|
162
|
+
children: children
|
|
163
|
+
})
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
MessageScrollerRoot.displayName = 'MessageScroller';
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The four scroll events are owned by the component and taken off the props
|
|
170
|
+
* type rather than merged with a consumer's. They are not decoration on top of
|
|
171
|
+
* a scroll view — they *are* the behaviour, and a call site that quietly
|
|
172
|
+
* replaced one would look like a bug in the scrolling.
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* The scrollable itself. Owns the three behaviours, because all three are
|
|
177
|
+
* reactions to scroll and content-size events and this is where they arrive.
|
|
178
|
+
*/
|
|
179
|
+
function MessageScrollerViewport({
|
|
180
|
+
className,
|
|
181
|
+
children,
|
|
182
|
+
...props
|
|
183
|
+
}) {
|
|
184
|
+
const {
|
|
185
|
+
scrollRef,
|
|
186
|
+
atEnd,
|
|
187
|
+
setAtEndJS,
|
|
188
|
+
autoScroll,
|
|
189
|
+
preserveScrollOnPrepend,
|
|
190
|
+
defaultScrollPosition,
|
|
191
|
+
itemY,
|
|
192
|
+
anchors,
|
|
193
|
+
following,
|
|
194
|
+
scrollToEnd,
|
|
195
|
+
scrollToMessage,
|
|
196
|
+
setCurrentAnchorId
|
|
197
|
+
} = useScroller('MessageScroller.Viewport');
|
|
198
|
+
const contentHeight = useRef(0);
|
|
199
|
+
const previousY = useRef(new Map());
|
|
200
|
+
const opened = useRef(false);
|
|
201
|
+
/*
|
|
202
|
+
* The live scroll offset, written on the UI thread and read straight from JS
|
|
203
|
+
* when the prepend correction needs it. A shared value rather than a ref
|
|
204
|
+
* updated through `runOnJS`: this is read a few times a second and written
|
|
205
|
+
* sixty, so the cheap side should be the write.
|
|
206
|
+
*/
|
|
207
|
+
const offsetY = useSharedValue(0);
|
|
208
|
+
|
|
209
|
+
/*
|
|
210
|
+
* The at-end test runs per frame on the UI thread, but it only ever produces
|
|
211
|
+
* a boolean — so JS is told about it when the boolean flips, not when the
|
|
212
|
+
* offset changes. A transcript scrolls constantly; re-rendering on every
|
|
213
|
+
* frame of it would be the most expensive thing on the screen.
|
|
214
|
+
*/
|
|
215
|
+
const publishAtEnd = useCallback(next => {
|
|
216
|
+
following.current = autoScroll && next;
|
|
217
|
+
setAtEndJS(next);
|
|
218
|
+
}, [autoScroll, following, setAtEndJS]);
|
|
219
|
+
const scrollHandler = useAnimatedScrollHandler({
|
|
220
|
+
onScroll: event => {
|
|
221
|
+
const {
|
|
222
|
+
contentOffset,
|
|
223
|
+
contentSize,
|
|
224
|
+
layoutMeasurement
|
|
225
|
+
} = event;
|
|
226
|
+
offsetY.value = contentOffset.y;
|
|
227
|
+
const distance = contentSize.height - layoutMeasurement.height - contentOffset.y;
|
|
228
|
+
const next = distance <= END_THRESHOLD ? 1 : 0;
|
|
229
|
+
if (next !== atEnd.value) {
|
|
230
|
+
atEnd.value = next;
|
|
231
|
+
runOnJS(publishAtEnd)(next === 1);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Which turn the reader is inside: the last anchor that has passed the top of
|
|
238
|
+
* the viewport. Settled after a scroll rather than tracked per frame — the
|
|
239
|
+
* answer is for a header, and a header that changes mid-flick is worse than
|
|
240
|
+
* one that changes when the flick lands.
|
|
241
|
+
*/
|
|
242
|
+
const settleAnchor = () => {
|
|
243
|
+
let current = null;
|
|
244
|
+
let bestY = -Infinity;
|
|
245
|
+
for (const id of anchors.current) {
|
|
246
|
+
const y = itemY.current.get(id);
|
|
247
|
+
if (y === undefined) continue;
|
|
248
|
+
if (y <= offsetY.value + ANCHOR_PEEK && y > bestY) {
|
|
249
|
+
bestY = y;
|
|
250
|
+
current = id;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
setCurrentAnchorId(current);
|
|
254
|
+
};
|
|
255
|
+
const onContentSizeChange = (_width, height) => {
|
|
256
|
+
const previousHeight = contentHeight.current;
|
|
257
|
+
contentHeight.current = height;
|
|
258
|
+
|
|
259
|
+
// The very first measurement is the transcript opening, not new content.
|
|
260
|
+
if (!opened.current) {
|
|
261
|
+
opened.current = true;
|
|
262
|
+
previousY.current = new Map(itemY.current);
|
|
263
|
+
openAt(defaultScrollPosition);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const grew = height - previousHeight;
|
|
267
|
+
if (grew > 0) {
|
|
268
|
+
if (following.current) {
|
|
269
|
+
scrollToEnd(true);
|
|
270
|
+
} else if (preserveScrollOnPrepend) {
|
|
271
|
+
// Content that appeared *above* the reader pushes everything down by
|
|
272
|
+
// the same amount. Measuring that shift on a message they can already
|
|
273
|
+
// see — rather than trusting the height delta — is what makes this
|
|
274
|
+
// correct when a message is prepended and another edits itself in the
|
|
275
|
+
// same commit.
|
|
276
|
+
const shift = topmostShift(previousY.current, itemY.current);
|
|
277
|
+
if (shift > 0.5) {
|
|
278
|
+
scrollRef.current?.scrollTo({
|
|
279
|
+
y: offsetY.value + shift,
|
|
280
|
+
animated: false
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
previousY.current = new Map(itemY.current);
|
|
286
|
+
settleAnchor();
|
|
287
|
+
};
|
|
288
|
+
const openAt = position => {
|
|
289
|
+
if (position === 'start') return;
|
|
290
|
+
if (position === 'end') {
|
|
291
|
+
scrollToEnd(false);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const last = anchors.current[anchors.current.length - 1];
|
|
295
|
+
if (last) scrollToMessage(last, false);else scrollToEnd(false);
|
|
296
|
+
};
|
|
297
|
+
useEffect(() => {
|
|
298
|
+
following.current = autoScroll && atEnd.value === 1;
|
|
299
|
+
}, [autoScroll, following, atEnd]);
|
|
300
|
+
return /*#__PURE__*/_jsx(Animated.ScrollView, {
|
|
301
|
+
ref: scrollRef,
|
|
302
|
+
accessibilityRole: "list",
|
|
303
|
+
accessibilityLabel: "Messages",
|
|
304
|
+
scrollEventThrottle: 16,
|
|
305
|
+
showsVerticalScrollIndicator: false,
|
|
306
|
+
className: cn('flex-1', className),
|
|
307
|
+
...props,
|
|
308
|
+
// After the spread: these four are the component's reason to exist, and
|
|
309
|
+
// silently losing one of them to a passed-through prop would look like a
|
|
310
|
+
// bug in the scrolling rather than in the call site.
|
|
311
|
+
onScroll: scrollHandler,
|
|
312
|
+
onScrollEndDrag: settleAnchor,
|
|
313
|
+
onMomentumScrollEnd: settleAnchor,
|
|
314
|
+
onContentSizeChange: onContentSizeChange,
|
|
315
|
+
children: children
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
MessageScrollerViewport.displayName = 'MessageScroller.Viewport';
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* How far the transcript shifted, measured on the message closest to the top
|
|
322
|
+
* that was there before and is still there.
|
|
323
|
+
*/
|
|
324
|
+
function topmostShift(before, after) {
|
|
325
|
+
let bestY = Infinity;
|
|
326
|
+
let shift = 0;
|
|
327
|
+
for (const [id, y] of before) {
|
|
328
|
+
const now = after.get(id);
|
|
329
|
+
if (now === undefined || y >= bestY) continue;
|
|
330
|
+
bestY = y;
|
|
331
|
+
shift = now - y;
|
|
332
|
+
}
|
|
333
|
+
return shift;
|
|
334
|
+
}
|
|
335
|
+
/** The transcript column. Announces additions rather than the whole list. */
|
|
336
|
+
function MessageScrollerContent({
|
|
337
|
+
className,
|
|
338
|
+
children,
|
|
339
|
+
...props
|
|
340
|
+
}) {
|
|
341
|
+
return /*#__PURE__*/_jsx(View, {
|
|
342
|
+
accessibilityLiveRegion: "polite"
|
|
343
|
+
// Extra room at the foot so the last turn clears the floating jump
|
|
344
|
+
// button instead of scrolling under it.
|
|
345
|
+
,
|
|
346
|
+
className: cn('gap-3 p-4 pb-16', className),
|
|
347
|
+
...props,
|
|
348
|
+
children: children
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
MessageScrollerContent.displayName = 'MessageScroller.Content';
|
|
352
|
+
/**
|
|
353
|
+
* One row of the transcript. It exists to be measured: without a boundary per
|
|
354
|
+
* turn there is nothing to scroll *to*, and nothing to measure the prepend
|
|
355
|
+
* shift against.
|
|
356
|
+
*/
|
|
357
|
+
function MessageScrollerItem({
|
|
358
|
+
className,
|
|
359
|
+
messageId,
|
|
360
|
+
scrollAnchor = false,
|
|
361
|
+
children,
|
|
362
|
+
...props
|
|
363
|
+
}) {
|
|
364
|
+
const {
|
|
365
|
+
registerItem,
|
|
366
|
+
unregisterItem
|
|
367
|
+
} = useScroller('MessageScroller.Item');
|
|
368
|
+
const onLayout = event => {
|
|
369
|
+
registerItem(messageId, event.nativeEvent.layout.y, scrollAnchor);
|
|
370
|
+
props.onLayout?.(event);
|
|
371
|
+
};
|
|
372
|
+
useEffect(() => () => unregisterItem(messageId), [messageId, unregisterItem]);
|
|
373
|
+
return /*#__PURE__*/_jsx(View, {
|
|
374
|
+
className: className,
|
|
375
|
+
...props,
|
|
376
|
+
onLayout: onLayout,
|
|
377
|
+
children: children
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
MessageScrollerItem.displayName = 'MessageScroller.Item';
|
|
381
|
+
/**
|
|
382
|
+
* The way back to the live edge, shown only when there is one to go back to.
|
|
383
|
+
*
|
|
384
|
+
* Its visibility is driven from the same shared value the scroll handler
|
|
385
|
+
* writes, so it fades on the UI thread while the transcript is still moving.
|
|
386
|
+
*/
|
|
387
|
+
function MessageScrollerButton({
|
|
388
|
+
className,
|
|
389
|
+
target = 'end',
|
|
390
|
+
accessibilityLabel,
|
|
391
|
+
children,
|
|
392
|
+
...props
|
|
393
|
+
}) {
|
|
394
|
+
const {
|
|
395
|
+
atEnd,
|
|
396
|
+
scrollToEnd,
|
|
397
|
+
scrollToStart
|
|
398
|
+
} = useScroller('MessageScroller.Button');
|
|
399
|
+
const tint = useCSSVariable('--color-foreground');
|
|
400
|
+
|
|
401
|
+
// Shown when away from the edge the button points at.
|
|
402
|
+
const shown = useDerivedValue(() => withTiming(target === 'end' ? 1 - atEnd.value : atEnd.value, {
|
|
403
|
+
duration: 160
|
|
404
|
+
}));
|
|
405
|
+
const style = useAnimatedStyle(() => ({
|
|
406
|
+
opacity: shown.value,
|
|
407
|
+
transform: [{
|
|
408
|
+
translateY: (1 - shown.value) * 8
|
|
409
|
+
}, {
|
|
410
|
+
scale: 0.92 + 0.08 * shown.value
|
|
411
|
+
}]
|
|
412
|
+
}));
|
|
413
|
+
const [interactive, setInteractive] = useState(false);
|
|
414
|
+
useDerivedValue(() => {
|
|
415
|
+
const next = shown.value > 0.5;
|
|
416
|
+
if (next !== interactive) runOnJS(setInteractive)(next);
|
|
417
|
+
});
|
|
418
|
+
return /*#__PURE__*/_jsx(Animated.View, {
|
|
419
|
+
// Never a focus stop while it is invisible — a screen reader landing on
|
|
420
|
+
// a button nobody can see is worse than not having one.
|
|
421
|
+
pointerEvents: interactive ? 'auto' : 'none',
|
|
422
|
+
accessibilityElementsHidden: !interactive,
|
|
423
|
+
importantForAccessibility: interactive ? 'auto' : 'no-hide-descendants',
|
|
424
|
+
style: style,
|
|
425
|
+
className: cn('absolute bottom-6 self-center', className),
|
|
426
|
+
...props,
|
|
427
|
+
children: /*#__PURE__*/_jsx(AnimatedPressable, {
|
|
428
|
+
accessibilityRole: "button",
|
|
429
|
+
accessibilityLabel: accessibilityLabel ?? (target === 'end' ? 'Jump to the latest message' : 'Jump to the start'),
|
|
430
|
+
onPress: () => target === 'end' ? scrollToEnd(true) : scrollToStart(true),
|
|
431
|
+
className: "h-10 w-10 items-center justify-center rounded-full border border-border bg-surface shadow-lg",
|
|
432
|
+
children: children ?? /*#__PURE__*/_jsx(ChevronDownIcon, {
|
|
433
|
+
size: 18,
|
|
434
|
+
color: typeof tint === 'string' ? tint : undefined,
|
|
435
|
+
style: target === 'start' ? {
|
|
436
|
+
transform: [{
|
|
437
|
+
rotate: '180deg'
|
|
438
|
+
}]
|
|
439
|
+
} : undefined
|
|
440
|
+
})
|
|
441
|
+
})
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
MessageScrollerButton.displayName = 'MessageScroller.Button';
|
|
445
|
+
export const MessageScroller = Object.assign(MessageScrollerRoot, {
|
|
446
|
+
Viewport: MessageScrollerViewport,
|
|
447
|
+
Content: MessageScrollerContent,
|
|
448
|
+
Item: MessageScrollerItem,
|
|
449
|
+
Button: MessageScrollerButton
|
|
450
|
+
});
|
|
451
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","View","Animated","runOnJS","useAnimatedRef","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useCSSVariable","ChevronDownIcon","AnimatedPressable","cn","jsx","_jsx","END_THRESHOLD","ANCHOR_PEEK","MessageScrollerContext","useScroller","component","context","Error","useMessageScroller","scrollToEnd","scrollToStart","scrollToMessage","useMessageScrollerVisibility","currentAnchorId","atEndJS","atEnd","MessageScrollerRoot","className","autoScroll","preserveScrollOnPrepend","defaultScrollPosition","children","props","scrollRef","setAtEndJS","setCurrentAnchorId","itemY","Map","anchors","following","registerItem","id","y","anchor","current","set","list","includes","push","filter","a","unregisterItem","delete","animated","scrollTo","get","undefined","Math","max","Provider","value","displayName","MessageScrollerViewport","contentHeight","previousY","opened","offsetY","publishAtEnd","next","scrollHandler","onScroll","event","contentOffset","contentSize","layoutMeasurement","distance","height","settleAnchor","bestY","Infinity","onContentSizeChange","_width","previousHeight","openAt","grew","shift","topmostShift","position","last","length","ScrollView","ref","accessibilityRole","accessibilityLabel","scrollEventThrottle","showsVerticalScrollIndicator","onScrollEndDrag","onMomentumScrollEnd","before","after","now","MessageScrollerContent","accessibilityLiveRegion","MessageScrollerItem","messageId","scrollAnchor","onLayout","nativeEvent","layout","MessageScrollerButton","target","tint","shown","duration","style","opacity","transform","translateY","scale","interactive","setInteractive","pointerEvents","accessibilityElementsHidden","importantForAccessibility","onPress","size","color","rotate","MessageScroller","Object","assign","Viewport","Content","Item","Button"],"sourceRoot":"../../../../src","sources":["components/message-scroller/index.tsx"],"mappings":"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","ignoreList":[]}
|