@danxbot/ui 20.18.3 → 20.20.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.
@@ -23,6 +23,23 @@ export interface StepperProps {
23
23
  * consumer driving its own buttons omits this and keeps the rail.
24
24
  */
25
25
  onCurrentChange?: (index: number) => void;
26
+ /**
27
+ * Draw the built-in Back / Next / Finish row. Default `true`.
28
+ *
29
+ * `false` keeps the rail clickable (`onCurrentChange` still fires for a click
30
+ * on an earlier step, and only for that) and draws no row, so a consumer
31
+ * whose content owns its own forward / back movement, such as a step that
32
+ * pages through several screens, renders its own buttons without a second
33
+ * row of them. Without it the only way to drop the row was to drop
34
+ * `onCurrentChange`, which also made the rail a read-out, and a rail click on
35
+ * the adjacent earlier step is indistinguishable from the built-in Back
36
+ * button (both call `onCurrentChange(current - 1)`).
37
+ *
38
+ * Nothing prints a step's `blocked` reason when the row is hidden: it is
39
+ * rendered beside the forward control. The consumer's own forward control
40
+ * reads it from `advanceBlockReason` and shows it.
41
+ */
42
+ showControls?: boolean;
26
43
  /**
27
44
  * What the last step's forward control does. Absent means no control is drawn
28
45
  * on the last step — a wizard whose final action lives in its own form.
@@ -41,4 +58,4 @@ export interface StepperProps {
41
58
  children?: ReactNode;
42
59
  className?: string;
43
60
  }
44
- export declare function Stepper({ label, steps, current, onCurrentChange, onFinish, backLabel, nextLabel, finishLabel, orientation, children, className, }: StepperProps): import("react").JSX.Element;
61
+ export declare function Stepper({ label, steps, current, onCurrentChange, showControls, onFinish, backLabel, nextLabel, finishLabel, orientation, children, className, }: StepperProps): import("react").JSX.Element;
@@ -116,7 +116,7 @@ export { Board, BoardColumn, BoardCard, BoardCardSurface, type BoardProps, type
116
116
  export { buildBoardModel, resolveMove, applyBoardMoves, useBoard, moveAnchor, columnLength, positionInColumn, type BoardModel, type MoveAnchor, type UseBoardResult, } from "./lib/board";
117
117
  export type { BoardAccessors, BoardColumnDef, BoardEdge, BoardColumnId, BoardColumnModel, BoardItemId, BoardMove, BoardMoveTarget, BoardMoveRequest, BoardMoveSource, BoardMoveVerdict, BoardReorderLabels, UseBoardOptions, } from "./lib/board";
118
118
  export { PagedWindowList, type PagedWindowItemPosition, type PagedWindowListProps, type PagedWindowStrings, } from "./components/PagedWindowList";
119
- export { PagedWindowStore, usePagedWindow, windowPageNumbers, type LoadCount, type LoadPage, type LoadPageContext, type PageResponse, type PageSnapshot, type PageStatus, type PagedWindow, type PagedWindowMode, type PagedWindowOptions, type PagedWindowSnapshot, type UsePagedWindowOptions, } from "./lib/paged-window";
119
+ export { PAGED_WINDOW_SETTLE_MS, PagedWindowStore, usePagedWindow, windowPageNumbers, type LoadCount, type LoadPage, type LoadPageContext, type PageResponse, type PageSnapshot, type PageStatus, type PagedWindow, type PagedWindowMode, type PagedWindowOptions, type PagedWindowSnapshot, type UsePagedWindowOptions, } from "./lib/paged-window";
120
120
  export type { MessageRole, MessagePart, TextPart, CodePart, ReasoningPart, ToolPart, ToolStatus, FilePart, ComponentPart, ChatFile, ChatMessage, RenderContext, PartRenderer, PartRenderers, ChatComponentRenderer, ChatComponents, } from "./components/chat/types";
121
121
  export { Chat, ChatPopover, type ChatProps, type ChatPopoverProps, type ChatSurface, } from "./components/chat/Chat";
122
122
  export { Message, MessagePartView, ToolCall, type MessageProps, type MessageAction, type MessagePartViewProps, type ToolCallProps, } from "./components/chat/Message";
@@ -1,2 +1,2 @@
1
- export { PagedWindowStore, windowPageNumbers, type LoadCount, type LoadPage, type LoadPageContext, type PageResponse, type PageSnapshot, type PageStatus, type PagedWindowMode, type PagedWindowOptions, type PagedWindowSnapshot, } from "./store";
1
+ export { PAGED_WINDOW_SETTLE_MS, PagedWindowStore, windowPageNumbers, type LoadCount, type LoadPage, type LoadPageContext, type PageResponse, type PageSnapshot, type PageStatus, type PagedWindowMode, type PagedWindowOptions, type PagedWindowSnapshot, } from "./store";
2
2
  export { usePagedWindow, type PagedWindow, type UsePagedWindowOptions } from "./use-paged-window";
@@ -12,6 +12,8 @@ export type LoadPage<T> = (page: number, context: LoadPageContext) => Promise<Pa
12
12
  /** Answers the list's length alone — no items. What a hidden (`count` mode) lane asks. */
13
13
  export type LoadCount = (context: LoadPageContext) => Promise<number>;
14
14
  export type PagedWindowMode = "pages" | "count";
15
+ /** How long the viewer's page must stay put before the window moves to it, in ms. */
16
+ export declare const PAGED_WINDOW_SETTLE_MS = 200;
15
17
  export type PageStatus = "loading" | "ready" | "error";
16
18
  export interface PageSnapshot<T> {
17
19
  page: number;
@@ -54,6 +56,12 @@ export interface PagedWindowOptions<T> {
54
56
  loadCount?: LoadCount;
55
57
  /** @default "pages" */
56
58
  mode?: PagedWindowMode;
59
+ /**
60
+ * How long the viewer's page must stay put before the window moves to it; 0
61
+ * moves it synchronously. A negative or fractional value throws.
62
+ * @default PAGED_WINDOW_SETTLE_MS
63
+ */
64
+ settleMs?: number;
57
65
  }
58
66
  /**
59
67
  * The pages to hold for an anchor: `windowPages` of them centred on it (the
@@ -64,13 +72,17 @@ export declare function windowPageNumbers(anchorPage: number, pageCount: number,
64
72
  export declare class PagedWindowStore<T> {
65
73
  private readonly pageSize;
66
74
  private readonly windowPages;
75
+ private readonly settleMs;
67
76
  private loadPage;
68
77
  private loadCount;
69
78
  private held;
70
79
  private total;
80
+ /** Where the viewer is; moves the instant they do. */
71
81
  private anchor;
72
- /** The anchor the held pages were last synced to; differs from `anchor` only while frozen. */
82
+ /** The anchor the held pages were last synced to; differs from `anchor` while the viewer is still moving, or frozen. */
73
83
  private appliedAnchor;
84
+ /** Moves the window to `anchor` once it has been still for `settleMs`; null when no move is waiting. */
85
+ private settleTimer;
74
86
  private mode;
75
87
  private frozen;
76
88
  private epoch;
@@ -85,7 +97,7 @@ export declare class PagedWindowStore<T> {
85
97
  private countError;
86
98
  private snapshot;
87
99
  private listeners;
88
- constructor({ pageSize, windowPages, loadPage, loadCount, mode }: PagedWindowOptions<T>);
100
+ constructor({ pageSize, windowPages, loadPage, loadCount, mode, settleMs, }: PagedWindowOptions<T>);
89
101
  /**
90
102
  * Replace the loaders. The React binding calls this after every commit so a
91
103
  * consumer's loaders can close over fresh state without the store being
@@ -95,7 +107,10 @@ export declare class PagedWindowStore<T> {
95
107
  setLoaders(loadPage: LoadPage<T>, loadCount: LoadCount | undefined): void;
96
108
  getSnapshot: () => PagedWindowSnapshot<T>;
97
109
  subscribe: (listener: () => void) => (() => void);
98
- /** The viewer moved to another page. Ignored while frozen, applied on thaw. */
110
+ /**
111
+ * The viewer moved to another page. The window follows once they have stayed
112
+ * there for `settleMs`; while frozen it follows on thaw.
113
+ */
99
114
  setAnchorPage(page: number): void;
100
115
  /**
101
116
  * While true nothing about the window changes: it neither loads nor drops
@@ -130,7 +145,16 @@ export declare class PagedWindowStore<T> {
130
145
  private wanted;
131
146
  /** Bring the held pages to the wanted ones — unless frozen, when that waits for the thaw. */
132
147
  private sync;
133
- /** `force` is `reset()`'s alone: it brings the window to its (new) list even while frozen. */
148
+ /** The viewer has settled on `anchor`: the window moves to it, in one step. */
149
+ private applyAnchor;
150
+ private clearSettle;
151
+ /**
152
+ * Moves the held pages to the window around `appliedAnchor` — which only
153
+ * `applyAnchor`, `thaw` and `reset` move, so a response arriving while the
154
+ * viewer is still moving brings in no page of the unsettled position.
155
+ * `force` is `reset()`'s alone: it brings the window to its (new) list even
156
+ * while frozen.
157
+ */
134
158
  private reconcile;
135
159
  /** Everything the frozen window put off, in the order the header promises. */
136
160
  private thaw;
@@ -34,8 +34,14 @@ export interface PagedWindow<T> extends PagedWindowSnapshot<T> {
34
34
  * view which ones to show. `loadPage` answers one page AND the list's current
35
35
  * length, so the scrollbar can span `total` before most of it is loaded.
36
36
  *
37
+ * The window moves to the viewer's page only after it has stayed put for
38
+ * `settleMs` (200 ms by default), so a fast scroll loads the pages it lands
39
+ * on, never the ones it passes (DX-4614); a read for a page that leaves the
40
+ * window is aborted through its `signal`, and an aborted read is never an error.
41
+ *
37
42
  * `pageSize` and `windowPages` are fixed for the life of the hook: changing one
38
43
  * means every held page is cut differently, which is a different list — give it
39
- * a new `queryKey` and a new mount instead. It throws rather than guessing.
44
+ * a new `queryKey` and a new mount instead. `settleMs` is fixed too: the store
45
+ * reads it once. All three throw rather than guess.
40
46
  */
41
- export declare function usePagedWindow<T>({ pageSize, windowPages, loadPage, loadCount, queryKey, mode, }: UsePagedWindowOptions<T>): PagedWindow<T>;
47
+ export declare function usePagedWindow<T>({ pageSize, windowPages, loadPage, loadCount, queryKey, mode, settleMs, }: UsePagedWindowOptions<T>): PagedWindow<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "20.18.3",
3
+ "version": "20.20.0",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",