@particle-academy/react-fancy 5.33.0 → 5.34.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/CHANGELOG.md +86 -0
- package/dist/activity-light.cjs +13 -0
- package/dist/activity-light.cjs.map +1 -0
- package/dist/activity-light.d.cts +64 -0
- package/dist/activity-light.d.ts +64 -0
- package/dist/activity-light.js +4 -0
- package/dist/activity-light.js.map +1 -0
- package/dist/button.cjs +4 -4
- package/dist/button.js +2 -2
- package/dist/{chunk-ZYVWKYPO.js → chunk-2OMB3OOR.js} +3 -3
- package/dist/{chunk-ZYVWKYPO.js.map → chunk-2OMB3OOR.js.map} +1 -1
- package/dist/{chunk-G6VMNSCM.js → chunk-46IPQEUP.js} +3 -3
- package/dist/{chunk-G6VMNSCM.js.map → chunk-46IPQEUP.js.map} +1 -1
- package/dist/{chunk-H6PXIB35.cjs → chunk-5Q7EQQTT.cjs} +4 -4
- package/dist/{chunk-H6PXIB35.cjs.map → chunk-5Q7EQQTT.cjs.map} +1 -1
- package/dist/{chunk-BQ77ZWFM.js → chunk-6ASZUE4T.js} +4 -4
- package/dist/{chunk-BQ77ZWFM.js.map → chunk-6ASZUE4T.js.map} +1 -1
- package/dist/{chunk-WEKQD4BQ.js → chunk-DCDW3LW6.js} +3 -3
- package/dist/{chunk-WEKQD4BQ.js.map → chunk-DCDW3LW6.js.map} +1 -1
- package/dist/{chunk-YMU3SS6D.cjs → chunk-E2SZBIAV.cjs} +16 -16
- package/dist/{chunk-YMU3SS6D.cjs.map → chunk-E2SZBIAV.cjs.map} +1 -1
- package/dist/chunk-EHNMKQ4O.cjs +71 -0
- package/dist/chunk-EHNMKQ4O.cjs.map +1 -0
- package/dist/chunk-IR6JSQ4O.cjs +233 -0
- package/dist/chunk-IR6JSQ4O.cjs.map +1 -0
- package/dist/{chunk-VRJTPXJ7.cjs → chunk-J2KYNK63.cjs} +5 -5
- package/dist/{chunk-VRJTPXJ7.cjs.map → chunk-J2KYNK63.cjs.map} +1 -1
- package/dist/{chunk-B4PFNSX7.js → chunk-KM4R4XWB.js} +3 -3
- package/dist/{chunk-B4PFNSX7.js.map → chunk-KM4R4XWB.js.map} +1 -1
- package/dist/{chunk-5TUZENNJ.cjs → chunk-MTUH2X3W.cjs} +4 -4
- package/dist/{chunk-5TUZENNJ.cjs.map → chunk-MTUH2X3W.cjs.map} +1 -1
- package/dist/chunk-PZTA6NCD.js +69 -0
- package/dist/chunk-PZTA6NCD.js.map +1 -0
- package/dist/{chunk-UWL6U3L7.cjs → chunk-RMJGF7MN.cjs} +3 -3
- package/dist/{chunk-UWL6U3L7.cjs.map → chunk-RMJGF7MN.cjs.map} +1 -1
- package/dist/{chunk-EIUS2K72.js → chunk-TX6VUYBC.js} +3 -3
- package/dist/{chunk-EIUS2K72.js.map → chunk-TX6VUYBC.js.map} +1 -1
- package/dist/{chunk-LQFQ2UKU.cjs → chunk-WWUKTXPX.cjs} +3 -3
- package/dist/{chunk-LQFQ2UKU.cjs.map → chunk-WWUKTXPX.cjs.map} +1 -1
- package/dist/chunk-Z4CW3U6C.js +231 -0
- package/dist/chunk-Z4CW3U6C.js.map +1 -0
- package/dist/editor.cjs +4 -4
- package/dist/editor.js +2 -2
- package/dist/index.cjs +148 -138
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +27 -25
- package/dist/inputs.cjs +9 -9
- package/dist/inputs.js +3 -3
- package/dist/json-editor.cjs +15 -15
- package/dist/json-editor.js +4 -4
- package/dist/magic-wand.cjs +4 -4
- package/dist/magic-wand.js +3 -3
- package/dist/prompt-input.cjs +4 -4
- package/dist/prompt-input.js +3 -3
- package/dist/reason-tag.cjs +4 -4
- package/dist/reason-tag.js +3 -3
- package/dist/virtual-list.cjs +13 -0
- package/dist/virtual-list.cjs.map +1 -0
- package/dist/virtual-list.d.cts +125 -0
- package/dist/virtual-list.d.ts +125 -0
- package/dist/virtual-list.js +4 -0
- package/dist/virtual-list.js.map +1 -0
- package/package.json +23 -2
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode, Ref } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The one thing `VirtualList` requires of a row: a stable id.
|
|
6
|
+
*
|
|
7
|
+
* It is required rather than derived from the array index because every feature
|
|
8
|
+
* here outlives a reindex — `scrollToId` resolves a deep link after rows have
|
|
9
|
+
* been prepended, and a measured height must follow its row rather than its
|
|
10
|
+
* position.
|
|
11
|
+
*/
|
|
12
|
+
interface VirtualListRow {
|
|
13
|
+
id: string;
|
|
14
|
+
}
|
|
15
|
+
interface VirtualListProps<T extends VirtualListRow> extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "onScroll"> {
|
|
16
|
+
/** The full list. Only the visible window is ever rendered. */
|
|
17
|
+
items: readonly T[];
|
|
18
|
+
/** Render one row. Called only for rows inside the window. */
|
|
19
|
+
renderRow: (item: T, index: number) => ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* Height of the scroll viewport. A number is also used as the viewport height
|
|
22
|
+
* for windowing before the element has been measured, so prefer one when you
|
|
23
|
+
* know it — `"100%"` works, it just renders a conservative first window.
|
|
24
|
+
*/
|
|
25
|
+
height?: number | string;
|
|
26
|
+
/**
|
|
27
|
+
* Seed height for rows that have not been measured yet. Only affects rows
|
|
28
|
+
* never rendered: a row's real height replaces it the moment it is on screen.
|
|
29
|
+
* Pick the common case, not the average.
|
|
30
|
+
*/
|
|
31
|
+
estimateRowHeight?: number;
|
|
32
|
+
/** Rows to render beyond each edge of the viewport. */
|
|
33
|
+
overscan?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Stick to the bottom as rows arrive. **Controlled** — this component never
|
|
36
|
+
* flips it on its own, so an agent can read and write the follow state
|
|
37
|
+
* through a bridge. Pair it with {@link onFollowChange}.
|
|
38
|
+
*/
|
|
39
|
+
followTail?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* The list asking to change {@link followTail}: `false` the instant the human
|
|
42
|
+
* scrolls up, `true` when they return to the bottom. Honour it by updating
|
|
43
|
+
* your own state — until you do, nothing changes.
|
|
44
|
+
*/
|
|
45
|
+
onFollowChange?: (following: boolean) => void;
|
|
46
|
+
/**
|
|
47
|
+
* How many rows have arrived since tail-following stopped. Drives a
|
|
48
|
+
* `↓ n new` pill, which is yours to render. Always `0` while following.
|
|
49
|
+
*/
|
|
50
|
+
onUnseenChange?: (count: number) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Put the row with this id at the top of the viewport — the `?at=<rowId>`
|
|
53
|
+
* deep link. Resolution is not instant for a row far down an unmeasured list:
|
|
54
|
+
* the target settles as the rows above it are measured. See
|
|
55
|
+
* {@link onScrollToIdResolved}.
|
|
56
|
+
*/
|
|
57
|
+
scrollToId?: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Fired once the component has stopped moving for a given `scrollToId`.
|
|
60
|
+
* `landed` is `false` when the id is not in `items` — a deep link to a pruned
|
|
61
|
+
* row, which must be distinguishable from a successful scroll to the top.
|
|
62
|
+
*/
|
|
63
|
+
onScrollToIdResolved?: (id: string, landed: boolean) => void;
|
|
64
|
+
/** The scroll viewport element. */
|
|
65
|
+
ref?: Ref<HTMLDivElement>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A windowed list for ledgers that run to tens of thousands of rows — only the
|
|
70
|
+
* visible slice is in the DOM, with **measured** variable row heights, deep
|
|
71
|
+
* links by row id, and sticky-bottom tail-following.
|
|
72
|
+
*
|
|
73
|
+
* Built for an agent event stream, where every one of those three is load
|
|
74
|
+
* bearing at once: message rows wrap and event rows do not, a link carries
|
|
75
|
+
* `?at=<rowId>` to the exact row under discussion, and new rows arrive while
|
|
76
|
+
* the human is reading older ones.
|
|
77
|
+
*
|
|
78
|
+
* ## Heights are measured, never predicted
|
|
79
|
+
*
|
|
80
|
+
* `estimateRowHeight` only seeds rows that have never been on screen. The
|
|
81
|
+
* moment a row renders, its real height is measured and replaces the estimate,
|
|
82
|
+
* and every offset after it moves. The alternative — a `rowHeight(item)`
|
|
83
|
+
* callback — is a prediction about text wrapping, font loading and container
|
|
84
|
+
* width, and when it is wrong the error accumulates down the list: rows draw in
|
|
85
|
+
* the wrong place and `scrollToId` lands on a neighbour. Measuring is slower to
|
|
86
|
+
* settle and correct when it does.
|
|
87
|
+
*
|
|
88
|
+
* ## Tail-follow breaks on INTENT, not on position
|
|
89
|
+
*
|
|
90
|
+
* Any upward gesture — wheel, drag, PageUp, Home — stops following
|
|
91
|
+
* immediately, even when the list is still pinned to the bottom and
|
|
92
|
+
* `scrollTop` has not changed yet. Position cannot tell "the human scrolled
|
|
93
|
+
* up" from "content grew downward", so a position-only implementation keeps
|
|
94
|
+
* following through a wheel-up and yanks the reader back on the next append.
|
|
95
|
+
*
|
|
96
|
+
* ## It is controlled
|
|
97
|
+
*
|
|
98
|
+
* `followTail` is the consumer's state. This component only ever *asks* via
|
|
99
|
+
* `onFollowChange`, so the follow state is readable and writable by an agent
|
|
100
|
+
* over a bridge, as the Human+ component contract requires. The `↓ n new` pill
|
|
101
|
+
* is the consumer's to render, from `onUnseenChange`.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```tsx
|
|
105
|
+
* const [following, setFollowing] = useState(true);
|
|
106
|
+
* const [unseen, setUnseen] = useState(0);
|
|
107
|
+
*
|
|
108
|
+
* <VirtualList
|
|
109
|
+
* items={events}
|
|
110
|
+
* renderRow={(e) => <StreamRow event={e} />}
|
|
111
|
+
* height="100%"
|
|
112
|
+
* estimateRowHeight={28}
|
|
113
|
+
* followTail={following}
|
|
114
|
+
* onFollowChange={setFollowing}
|
|
115
|
+
* onUnseenChange={setUnseen}
|
|
116
|
+
* scrollToId={params.at}
|
|
117
|
+
* />
|
|
118
|
+
* {!following && unseen > 0 && (
|
|
119
|
+
* <Button onClick={() => setFollowing(true)}>↓ {unseen} new</Button>
|
|
120
|
+
* )}
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
declare function VirtualList<T extends VirtualListRow>({ items, renderRow, height, estimateRowHeight, overscan, followTail, onFollowChange, onUnseenChange, scrollToId, onScrollToIdResolved, className, ref, ...props }: VirtualListProps<T>): react.JSX.Element;
|
|
124
|
+
|
|
125
|
+
export { VirtualList, type VirtualListProps, type VirtualListRow };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"virtual-list.js"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@particle-academy/react-fancy",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.34.0",
|
|
4
4
|
"description": "React UI component library for Human+ UX — controlled, agent-bridgeable primitives",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -423,6 +423,26 @@
|
|
|
423
423
|
"default": "./dist/image-viewer.cjs"
|
|
424
424
|
}
|
|
425
425
|
},
|
|
426
|
+
"./activity-light": {
|
|
427
|
+
"import": {
|
|
428
|
+
"types": "./dist/activity-light.d.ts",
|
|
429
|
+
"default": "./dist/activity-light.js"
|
|
430
|
+
},
|
|
431
|
+
"require": {
|
|
432
|
+
"types": "./dist/activity-light.d.cts",
|
|
433
|
+
"default": "./dist/activity-light.cjs"
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
"./virtual-list": {
|
|
437
|
+
"import": {
|
|
438
|
+
"types": "./dist/virtual-list.d.ts",
|
|
439
|
+
"default": "./dist/virtual-list.js"
|
|
440
|
+
},
|
|
441
|
+
"require": {
|
|
442
|
+
"types": "./dist/virtual-list.d.cts",
|
|
443
|
+
"default": "./dist/virtual-list.cjs"
|
|
444
|
+
}
|
|
445
|
+
},
|
|
426
446
|
"./index-list": {
|
|
427
447
|
"import": {
|
|
428
448
|
"types": "./dist/index-list.d.ts",
|
|
@@ -982,7 +1002,8 @@
|
|
|
982
1002
|
"overrides": {
|
|
983
1003
|
"esbuild": "^0.28.1",
|
|
984
1004
|
"brace-expansion": "^5.0.12",
|
|
985
|
-
"undici": "^7.29.1"
|
|
1005
|
+
"undici": "^7.29.1",
|
|
1006
|
+
"source-map-js": "^1.2.2"
|
|
986
1007
|
},
|
|
987
1008
|
"engines": {
|
|
988
1009
|
"node": ">=22"
|