@danxbot/ui 20.8.1 → 20.10.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/dist/index.js +9762 -9380
- package/dist/index.js.map +1 -1
- package/dist/types/components/Board.d.ts +23 -3
- package/dist/types/components/PagedWindowList.d.ts +31 -0
- package/dist/types/components/board/recipe.d.ts +3 -0
- package/dist/types/components/rbac/AccessRequestPanel.d.ts +8 -3
- package/dist/types/components/rbac/PermissionRequestPanel.d.ts +7 -2
- package/dist/types/components/rbac/approvalPanelParts.d.ts +12 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/lib/dnd/index.d.ts +1 -1
- package/dist/types/lib/dnd/use-drag.d.ts +10 -0
- package/dist/types/lib/paged-window/index.d.ts +2 -0
- package/dist/types/lib/paged-window/store.d.ts +111 -0
- package/dist/types/lib/paged-window/use-paged-window.d.ts +40 -0
- package/package.json +2 -2
|
@@ -138,12 +138,32 @@ export interface BoardColumnProps<T> {
|
|
|
138
138
|
* never colour or glyph alone (WCAG 1.4.1).
|
|
139
139
|
*/
|
|
140
140
|
icon?: ReactNode;
|
|
141
|
+
/**
|
|
142
|
+
* DX-4540: the lane's real length when `column.items` holds only the cards
|
|
143
|
+
* loaded so far (a windowed lane, see the file header). The count badge, the
|
|
144
|
+
* empty-state decision and the WIP limit all read it instead of the loaded
|
|
145
|
+
* count, so a lane of 500 shows 500 while rendering 40. Omitted, they read
|
|
146
|
+
* `column.count` exactly as before.
|
|
147
|
+
*
|
|
148
|
+
* `null` is "the length is still being read" (a lane opening, or starting a
|
|
149
|
+
* new sort): the count shows a dash, and the lane is NOT empty — its cards
|
|
150
|
+
* are on their way, so the empty state stays away and the children (a
|
|
151
|
+
* `PagedWindowList` holding a loading placeholder) stay mounted.
|
|
152
|
+
*/
|
|
153
|
+
total?: number | null;
|
|
154
|
+
/**
|
|
155
|
+
* DX-4540: controls drawn at the header's end, after the count — a
|
|
156
|
+
* `SortMenu`, say. A slot of content, not a boolean: supplying it is what
|
|
157
|
+
* adds it. It sits in the header, outside the scrolling list, so it stays
|
|
158
|
+
* put while the cards scroll.
|
|
159
|
+
*/
|
|
160
|
+
actions?: ReactNode;
|
|
141
161
|
/** The column's cards — a `BoardCard` per item, mapped by the consumer
|
|
142
|
-
* exactly as `DragDropContainer`'s own children already are.
|
|
143
|
-
*
|
|
162
|
+
* exactly as `DragDropContainer`'s own children already are. A windowed
|
|
163
|
+
* lane puts a `PagedWindowList` here — see the file header. */
|
|
144
164
|
children?: ReactNode;
|
|
145
165
|
}
|
|
146
|
-
export declare function BoardColumn<T>({ column, emptyState, className, listClassName, accent, icon, children, }: BoardColumnProps<T>): import("react").JSX.Element;
|
|
166
|
+
export declare function BoardColumn<T>({ column, emptyState, className, listClassName, accent, icon, total, actions, children, }: BoardColumnProps<T>): import("react").JSX.Element;
|
|
147
167
|
export interface BoardCardProps {
|
|
148
168
|
id: BoardItemId;
|
|
149
169
|
/** Position within its OWN column right now — same contract as
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { PagedWindow } from "../lib/paged-window";
|
|
3
|
+
export interface PagedWindowStrings {
|
|
4
|
+
/** Shown in a page whose request failed. */
|
|
5
|
+
error: string;
|
|
6
|
+
/** The retry button's label. */
|
|
7
|
+
retry: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PagedWindowItemPosition {
|
|
10
|
+
/** Position among the items currently held, across every held page. */
|
|
11
|
+
local: number;
|
|
12
|
+
/** Position in the whole list: `page * pageSize + index on the page`. */
|
|
13
|
+
global: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PagedWindowListProps<T> {
|
|
16
|
+
/** The window to render — what `usePagedWindow` returned. */
|
|
17
|
+
window: PagedWindow<T>;
|
|
18
|
+
/** Stable across renders and pages. Never an array index. */
|
|
19
|
+
getKey: (item: T) => string | number;
|
|
20
|
+
renderItem: (item: T, position: PagedWindowItemPosition) => ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* One item's height INCLUDING its spacing, in px, used for placeholders until
|
|
23
|
+
* real pages have been measured. Replaced by the measured mean as pages
|
|
24
|
+
* arrive, so it only has to be close.
|
|
25
|
+
*/
|
|
26
|
+
estimatedItemHeight: number;
|
|
27
|
+
/** Words in the failed-page row. */
|
|
28
|
+
strings?: Partial<PagedWindowStrings>;
|
|
29
|
+
className?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function PagedWindowList<T>({ window: win, getKey, renderItem, estimatedItemHeight, strings, className, }: PagedWindowListProps<T>): import("react").JSX.Element;
|
|
@@ -21,6 +21,7 @@ export declare const board: import("tailwind-variants").TVReturnType<{
|
|
|
21
21
|
header: string[];
|
|
22
22
|
title: string;
|
|
23
23
|
glyph: string;
|
|
24
|
+
trailing: string;
|
|
24
25
|
label: string;
|
|
25
26
|
list: string;
|
|
26
27
|
empty: string;
|
|
@@ -50,6 +51,7 @@ export declare const board: import("tailwind-variants").TVReturnType<{
|
|
|
50
51
|
header: string[];
|
|
51
52
|
title: string;
|
|
52
53
|
glyph: string;
|
|
54
|
+
trailing: string;
|
|
53
55
|
label: string;
|
|
54
56
|
list: string;
|
|
55
57
|
empty: string;
|
|
@@ -79,6 +81,7 @@ export declare const board: import("tailwind-variants").TVReturnType<{
|
|
|
79
81
|
header: string[];
|
|
80
82
|
title: string;
|
|
81
83
|
glyph: string;
|
|
84
|
+
trailing: string;
|
|
82
85
|
label: string;
|
|
83
86
|
list: string;
|
|
84
87
|
empty: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type AccessRequestState } from "./approvalPanelParts";
|
|
1
|
+
import { type ExpiredNote, type AccessRequestState } from "./approvalPanelParts";
|
|
2
2
|
import type { Permission, Role } from "./types";
|
|
3
3
|
export type AccessRequestKind = "session" | "worker";
|
|
4
|
-
export type { AccessRequestState };
|
|
4
|
+
export type { AccessRequestState, ExpiredNote };
|
|
5
5
|
export interface AccessRequest {
|
|
6
6
|
kind: AccessRequestKind;
|
|
7
7
|
/** The session title or the worker id: what the requester calls itself. */
|
|
@@ -36,6 +36,11 @@ export interface AccessRequestPanelProps {
|
|
|
36
36
|
defaultRoleId?: string;
|
|
37
37
|
onApprove: (roleId: string) => Promise<void>;
|
|
38
38
|
onDeny: () => Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Why an expired request expired and what its requester does next. Used only in the `expired` state; without it the readout says only
|
|
41
|
+
* that nothing was granted.
|
|
42
|
+
*/
|
|
43
|
+
expiredNote?: ExpiredNote;
|
|
39
44
|
className?: string;
|
|
40
45
|
}
|
|
41
|
-
export declare function AccessRequestPanel({ request, state, roles, permissions, ownPermissionKeys, defaultRoleId, onApprove, onDeny, className, }: AccessRequestPanelProps): import("react").JSX.Element;
|
|
46
|
+
export declare function AccessRequestPanel({ request, state, roles, permissions, ownPermissionKeys, defaultRoleId, onApprove, onDeny, expiredNote, className, }: AccessRequestPanelProps): import("react").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AccessRequestState } from "./approvalPanelParts";
|
|
1
|
+
import { type AccessRequestState, type ExpiredNote } from "./approvalPanelParts";
|
|
2
2
|
import type { Permission } from "./types";
|
|
3
3
|
export interface PermissionRequest {
|
|
4
4
|
/** The name of the key that is asking: what the agent's key is called. */
|
|
@@ -26,6 +26,11 @@ export interface PermissionRequestPanelProps {
|
|
|
26
26
|
/** Receives exactly the permission keys left checked. */
|
|
27
27
|
onApprove: (permissionKeys: string[]) => Promise<void>;
|
|
28
28
|
onDeny: () => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Why an expired request expired and what its requester does next. Used only in the `expired` state; without it the readout says only
|
|
31
|
+
* that nothing was granted.
|
|
32
|
+
*/
|
|
33
|
+
expiredNote?: ExpiredNote;
|
|
29
34
|
className?: string;
|
|
30
35
|
}
|
|
31
|
-
export declare function PermissionRequestPanel({ request, state, permissions, ownPermissionKeys, onApprove, onDeny, className, }: PermissionRequestPanelProps): import("react").JSX.Element;
|
|
36
|
+
export declare function PermissionRequestPanel({ request, state, permissions, ownPermissionKeys, onApprove, onDeny, expiredNote, className, }: PermissionRequestPanelProps): import("react").JSX.Element;
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
export type AccessRequestState = "pending" | "approved" | "denied" | "expired" | "claimed";
|
|
3
|
+
/** Why a request expired and what its requester does next, in the consumer's words; the Expired readout leads with them. */
|
|
4
|
+
export interface ExpiredNote {
|
|
5
|
+
/** Why the request is over, e.g. "The agent's session ended.". */
|
|
6
|
+
reason: string;
|
|
7
|
+
/** What the requester must do to get access, e.g. "The agent must reconnect and ask again.". */
|
|
8
|
+
nextStep: string;
|
|
9
|
+
}
|
|
3
10
|
export declare function ApprovalHeader({ title, state }: {
|
|
4
11
|
title: string;
|
|
5
12
|
state: AccessRequestState;
|
|
@@ -40,4 +47,9 @@ export declare function ApprovalButtons({ busy, run, onApprove, onDeny, approveD
|
|
|
40
47
|
/** True when there is nothing valid to approve. Deny is never disabled by this. */
|
|
41
48
|
approveDisabled: boolean;
|
|
42
49
|
}): import("react").JSX.Element;
|
|
50
|
+
/** The Expired readout: with a note it names the cause and the requester's next step, without one it only says nothing was granted. */
|
|
51
|
+
export declare function ExpiredNotice({ note, fallback }: {
|
|
52
|
+
note: ExpiredNote | undefined;
|
|
53
|
+
fallback: string;
|
|
54
|
+
}): import("react").JSX.Element;
|
|
43
55
|
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -111,10 +111,12 @@ export { tokenize, listLanguages, resolveLanguage, defineGrammar, registerGramma
|
|
|
111
111
|
export { parseMarkdown, MarkdownNodes, sanitizeHref, type MdNode, type MdInline, type MdCodeRenderer, } from "./lib/syntax/markdown";
|
|
112
112
|
export { DragDrop, DragDropContainer, DragDropItem, DragDropHandle, DragDropSurface, type DragDropProps, type DragDropContainerProps, type DragDropItemProps, type DragDropHandleProps, type DragDropSurfaceProps, } from "./components/DragDrop";
|
|
113
113
|
export { KanbanBoard, type KanbanBoardProps, type KanbanLane, type KanbanMove, type KanbanRefusal, } from "./components/kanban/KanbanBoard";
|
|
114
|
-
export { DEFAULT_DRAG_STRINGS, DRAG_INSTRUCTIONS_ID, DragInstructions, DragLiveRegion, DragSession, DragSessionProvider, applyMove, attachAutoScroll, attachKeyboardSensor, attachPointerSensor, attachSessionWindowListeners, isNoOp, resolveTarget, sameTarget, scrollVelocity, useCreateDragSession, useDragAnnouncements, useDragSession, useDragState, useDraggable, useDropContainer, type ContainerId, type DragAxis, type DragCancelEvent, type DragEndEvent, type DragId, type DragMode, type DragPhase, type DragSessionCallbacks, type DragStartEvent, type DragState, type AutoScrollOptions, type DragAnnouncementContext, type DragAnnouncementOptions, type DragAnnouncements, type DragInstructionsProps, type DragLiveRegionProps, type DragStrings, type DropTarget, type KeyboardSensorOptions, type PointerActivation, } from "./lib/dnd";
|
|
114
|
+
export { DEFAULT_DRAG_STRINGS, DRAG_INSTRUCTIONS_ID, DragInstructions, DragLiveRegion, DragSession, DragSessionProvider, applyMove, attachAutoScroll, attachKeyboardSensor, attachPointerSensor, attachSessionWindowListeners, isNoOp, resolveTarget, sameTarget, scrollVelocity, useCreateDragSession, useDragAnnouncements, useDragSession, useDragState, useDragLive, useDraggable, useDropContainer, type ContainerId, type DragAxis, type DragCancelEvent, type DragEndEvent, type DragId, type DragMode, type DragPhase, type DragSessionCallbacks, type DragStartEvent, type DragState, type AutoScrollOptions, type DragAnnouncementContext, type DragAnnouncementOptions, type DragAnnouncements, type DragInstructionsProps, type DragLiveRegionProps, type DragStrings, type DropTarget, type KeyboardSensorOptions, type PointerActivation, } from "./lib/dnd";
|
|
115
115
|
export { Board, BoardColumn, BoardCard, BoardCardSurface, type BoardProps, type BoardColumnProps, type BoardCardProps, type BoardCardSurfaceProps, } from "./components/Board";
|
|
116
116
|
export { buildBoardModel, resolveMove, applyBoardMoves, useBoard, type BoardModel, type UseBoardResult, } from "./lib/board";
|
|
117
117
|
export type { BoardAccessors, BoardColumnDef, BoardColumnId, BoardColumnModel, BoardItemId, BoardMove, BoardMoveRequest, BoardMoveSource, BoardMoveVerdict, UseBoardOptions, } from "./lib/board";
|
|
118
|
+
export { PagedWindowList, type PagedWindowItemPosition, type PagedWindowListProps, type PagedWindowStrings, } from "./components/PagedWindowList";
|
|
119
|
+
export { PagedWindowStore, usePagedWindow, windowPageNumbers, type LoadPage, type LoadPageContext, type PageResponse, type PageSnapshot, type PageStatus, type PagedWindow, type PagedWindowOptions, type PagedWindowSnapshot, type UsePagedWindowOptions, } from "./lib/paged-window";
|
|
118
120
|
export type { MessageRole, MessagePart, TextPart, CodePart, ReasoningPart, ToolPart, ToolStatus, FilePart, ComponentPart, ChatFile, ChatMessage, RenderContext, PartRenderer, PartRenderers, ChatComponentRenderer, ChatComponents, } from "./components/chat/types";
|
|
119
121
|
export { Chat, ChatPopover, type ChatProps, type ChatPopoverProps, type ChatSurface, } from "./components/chat/Chat";
|
|
120
122
|
export { Message, MessagePartView, ToolCall, type MessageProps, type MessageAction, type MessagePartViewProps, type ToolCallProps, } from "./components/chat/Message";
|
|
@@ -152,7 +154,7 @@ export { cellLabel, eventLabel, formatDateRange, longDate, monthTitle, timeOfDay
|
|
|
152
154
|
export { initialFocusDay, isInMonth, nextDayForKey, useGridNavigation, type GridNavigation, type GridNavigationOptions, } from "./components/calendar/use-grid-navigation";
|
|
153
155
|
export { AmbiguousTimeError, addDays, addDuration, addMonths, atMidnight, atTime, comparePlainDate, dayFraction, dayLengthMs, dayOfWeek, daysBetween, daysInMonth, endOfMonth, hoursInDay, instantAtFraction, instantToPlainDate, instantToPlainDateTime, isSameDate, isoDateString, isoDateTimeString, monthGridDays, nextDay, offsetAt, parsePlainDate, plainDateTimeToInstant, relativeAge, startOfDay, startOfMonth, startOfWeek, weekDays, type CalendarDuration, type Disambiguation, type Instant, type PlainDate, type PlainDateTime, type TimeZone, } from "./lib/time";
|
|
154
156
|
export { allDayBandSegment, dayKey, daySlots, isAllDay, packBand, packLanes, snapFractionToInstant, timeSegments, timedBandSegment, type AllDayEvent, type BandInput, type BandOptions, type BandPlacement, type BandResult, type BandSegment, type CalendarEvent, type CalendarEventId, type CalendarView, type DaySlot, type DragKind, type EventDraft, type EventPalette, type LaneInput, type LaneOptions, type LanePlacement, type PaletteEntry, type TimeSegment, type TimedEvent, type VisibleRange, } from "./lib/calendar";
|
|
155
|
-
export { RBACProvider, useRBAC, Can, useHasPermission, AccountMenu, AccountMenuSection, TeamSwitcher, DevToolsPopover, RolePermissionMatrix, RoleEditorDialog, ProfileForm, ProfilePage, RolesPermissionsPage, MembersPanel, ChangePasswordForm, SessionsList, ApiKeysPanel, AgentKeysList, AccessRequestPanel, PermissionRequestPanel, RoleKeyPicker, isRoleSelectable, leastPrivilegeRoleId, InvitationsList, InviteMembersDialog, Brand, TeamSettingsForm, DangerZone, type RBACProviderProps, type RBACHookResult, type CanProps, type AccountMenuProps, type TeamSwitcherProps, type DevToolsPopoverProps, type RolePermissionMatrixProps, type RoleEditorDialogProps, type RoleEditorDialogSubmitInput, type ProfileFormProps, type ProfileFormAccount, type ProfileFormSaveInput, type ProfilePageProps, type RolesPermissionsPageProps, type MembersPanelProps, type MembersPanelMember, type ChangePasswordFormProps, type SessionsListProps, type Session, type ApiKeysPanelProps, type AgentKeysListProps, type ApiKey, type KeyGrant, type KeyRoleEditor, type AccessRequestPanelProps, type AccessRequest, type AccessRequestKind, type AccessRequestState, type PermissionRequestPanelProps, type PermissionRequest, type RoleKeyPickerProps, type InvitationsListProps, type InvitationsListItem, type InvitationStatus, type InviteMembersDialogProps, type Permission, type Role, type User, type Team, type TeamMembership, type BrandProps, type TeamSettingsFormProps, type TeamSettingsFormTeam, type TeamSettingsFormSaveInput, type DangerZoneProps, } from "./components/rbac";
|
|
157
|
+
export { RBACProvider, useRBAC, Can, useHasPermission, AccountMenu, AccountMenuSection, TeamSwitcher, DevToolsPopover, RolePermissionMatrix, RoleEditorDialog, ProfileForm, ProfilePage, RolesPermissionsPage, MembersPanel, ChangePasswordForm, SessionsList, ApiKeysPanel, AgentKeysList, AccessRequestPanel, PermissionRequestPanel, RoleKeyPicker, isRoleSelectable, leastPrivilegeRoleId, InvitationsList, InviteMembersDialog, Brand, TeamSettingsForm, DangerZone, type RBACProviderProps, type RBACHookResult, type CanProps, type AccountMenuProps, type TeamSwitcherProps, type DevToolsPopoverProps, type RolePermissionMatrixProps, type RoleEditorDialogProps, type RoleEditorDialogSubmitInput, type ProfileFormProps, type ProfileFormAccount, type ProfileFormSaveInput, type ProfilePageProps, type RolesPermissionsPageProps, type MembersPanelProps, type MembersPanelMember, type ChangePasswordFormProps, type SessionsListProps, type Session, type ApiKeysPanelProps, type AgentKeysListProps, type ApiKey, type KeyGrant, type KeyRoleEditor, type AccessRequestPanelProps, type AccessRequest, type AccessRequestKind, type AccessRequestState, type ExpiredNote, type PermissionRequestPanelProps, type PermissionRequest, type RoleKeyPickerProps, type InvitationsListProps, type InvitationsListItem, type InvitationStatus, type InviteMembersDialogProps, type Permission, type Role, type User, type Team, type TeamMembership, type BrandProps, type TeamSettingsFormProps, type TeamSettingsFormTeam, type TeamSettingsFormSaveInput, type DangerZoneProps, } from "./components/rbac";
|
|
156
158
|
export { AuthLayout, AcceptInvitationCard, SignupCard, TermsAcceptance, LoginForm, ForgotPasswordForm, ResetPasswordForm, type AuthLayoutProps, type AcceptInvitationCardProps, type SignupCardProps, type TermsAcceptanceProps, type LoginFormProps, type ForgotPasswordFormProps, type ResetPasswordFormProps, } from "./components/auth";
|
|
157
159
|
export { UseCaseCard, RoadmapItemCard, RoadmapSwimlaneBoard, UseCaseLedgerPage, RoadmapPage, PhaseManager, TrackManager, deriveRoadmapItemStatus, isFullyBuilt, isUnbuilt, trackIds, trackProgress, toneForIndex, CATEGORY_TONES, type Domain, type Phase, type Track, type RoadmapItem, type RoadmapItemStatus, type UseCase, type UseCaseStatus, type UseCaseDecision, type UseCaseCardProps, type RoadmapItemCardProps, type RoadmapSwimlaneBoardProps, type UseCaseLedgerPageProps, type RoadmapPageProps, type PhaseManagerProps, type TrackManagerProps, } from "./components/roadmap";
|
|
158
160
|
export { ProvenanceDisclosure, ProvenanceDetail, ProvenanceBadge, ConfidenceReadout, ConfidenceMeter, ConfidenceBar, provenanceStateLabel, confidenceBand, confidenceScore, scoredConfidence, ratedConfidence, type ProvenanceRecord, type ProvenanceState, type ProvenanceSource, type ProvenanceCheck, type ProvenanceCall, type ProvenanceSignoff, type ConfidenceBand, type ConfidenceScore, type ProvenanceConfidence, type ConfidenceReadoutProps, type ConfidenceBarProps, type ConfidenceBarSize, type ProvenanceDisclosureProps, type ProvenanceDetailProps, type ProvenanceDetailTitleAs, type ProvenanceTriggerBadge, type ProvenanceBadgeProps, type ProvenanceBadgeAppearance, type ConfidenceMeterProps, } from "./components/provenance";
|
|
@@ -12,5 +12,5 @@ export { DragSession, type StartArgs } from "./session";
|
|
|
12
12
|
export { attachPointerSensor, attachSessionWindowListeners, type PointerActivation, type PointerSensorOptions, } from "./sensors/pointer";
|
|
13
13
|
export { attachKeyboardSensor, type KeyboardSensorOptions, } from "./sensors/keyboard";
|
|
14
14
|
export { attachAutoScroll, scrollVelocity, type AutoScrollOptions, } from "./autoscroll";
|
|
15
|
-
export { DragSessionProvider, useCreateDragSession, useDragSession, useDragState, useDraggable, useDropContainer, type UseDraggableOptions, type UseDraggableResult, type UseDropContainerOptions, type UseDropContainerResult, } from "./use-drag";
|
|
15
|
+
export { DragSessionProvider, useCreateDragSession, useDragSession, useDragState, useDragLive, useDraggable, useDropContainer, type UseDraggableOptions, type UseDraggableResult, type UseDropContainerOptions, type UseDropContainerResult, } from "./use-drag";
|
|
16
16
|
export { DEFAULT_DRAG_STRINGS, DRAG_INSTRUCTIONS_ID, DragInstructions, DragLiveRegion, useDragAnnouncements, type DragAnnouncementContext, type DragAnnouncementOptions, type DragAnnouncements, type DragInstructionsProps, type DragLiveRegionProps, type DragStrings, } from "./announce";
|
|
@@ -14,6 +14,16 @@ export declare function useDragSession(component: string): DragSession;
|
|
|
14
14
|
export declare function useCreateDragSession(callbacks: DragSessionCallbacks): DragSession;
|
|
15
15
|
/** Subscribe to the session. */
|
|
16
16
|
export declare function useDragState(session: DragSession): DragState;
|
|
17
|
+
/**
|
|
18
|
+
* True while a card is being carried in the enclosing `<DragDrop>`, and false
|
|
19
|
+
* outside one — it never throws, because the callers that ask (a windowed list
|
|
20
|
+
* deciding whether it may drop a page) are ordinary components that are
|
|
21
|
+
* sometimes inside a board and sometimes not.
|
|
22
|
+
*
|
|
23
|
+
* Reads only `phase === "dragging"`, so it re-renders its caller when a drag
|
|
24
|
+
* starts or ends and not on every pointer move, which `useDragState` would.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useDragLive(): boolean;
|
|
17
27
|
export interface UseDraggableOptions {
|
|
18
28
|
id: DragId;
|
|
19
29
|
container: ContainerId;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { PagedWindowStore, windowPageNumbers, type LoadPage, type LoadPageContext, type PageResponse, type PageSnapshot, type PageStatus, type PagedWindowOptions, type PagedWindowSnapshot, } from "./store";
|
|
2
|
+
export { usePagedWindow, type PagedWindow, type UsePagedWindowOptions } from "./use-paged-window";
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export interface PageResponse<T> {
|
|
2
|
+
/** This page's items, in order. Fewer than `pageSize` only for the last page. */
|
|
3
|
+
items: readonly T[];
|
|
4
|
+
/** The WHOLE list's length right now. Every response refreshes it. */
|
|
5
|
+
total: number;
|
|
6
|
+
}
|
|
7
|
+
export interface LoadPageContext {
|
|
8
|
+
/** Aborted when the page is dropped, re-requested or the window is reset. */
|
|
9
|
+
signal: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
export type LoadPage<T> = (page: number, context: LoadPageContext) => Promise<PageResponse<T>>;
|
|
12
|
+
export type PageStatus = "loading" | "ready" | "error";
|
|
13
|
+
export interface PageSnapshot<T> {
|
|
14
|
+
page: number;
|
|
15
|
+
status: PageStatus;
|
|
16
|
+
/** Empty unless `ready`. A page being re-read keeps its old items and stays `ready`. */
|
|
17
|
+
items: readonly T[];
|
|
18
|
+
/** True while a `ready` page is being re-read in place. */
|
|
19
|
+
refreshing: boolean;
|
|
20
|
+
/** What the load rejected with. Only on `error`. */
|
|
21
|
+
error: unknown;
|
|
22
|
+
}
|
|
23
|
+
export interface PagedWindowSnapshot<T> {
|
|
24
|
+
/** The list's length as the latest response reported it; null before the first. */
|
|
25
|
+
total: number | null;
|
|
26
|
+
pageSize: number;
|
|
27
|
+
/** 0 until `total` is known, then `ceil(total / pageSize)`. */
|
|
28
|
+
pageCount: number;
|
|
29
|
+
/** The page the viewer is looking at. */
|
|
30
|
+
anchorPage: number;
|
|
31
|
+
/** Counts resets, so a view can scroll back to the top when the query changed. */
|
|
32
|
+
epoch: number;
|
|
33
|
+
/** The held pages, ascending. At most `windowPages` of them. */
|
|
34
|
+
pages: readonly PageSnapshot<T>[];
|
|
35
|
+
/** Every item of every `ready` held page, in list order. At most `windowPages * pageSize`. */
|
|
36
|
+
items: readonly T[];
|
|
37
|
+
}
|
|
38
|
+
export interface PagedWindowOptions<T> {
|
|
39
|
+
pageSize: number;
|
|
40
|
+
/** How many pages are held at once. @default 3 */
|
|
41
|
+
windowPages?: number;
|
|
42
|
+
loadPage: LoadPage<T>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The pages to hold for an anchor: `windowPages` of them centred on it (the
|
|
46
|
+
* extra page of an even window goes after), clipped to `[0, pageCount)`. Pure,
|
|
47
|
+
* so the rule is testable without a store.
|
|
48
|
+
*/
|
|
49
|
+
export declare function windowPageNumbers(anchorPage: number, pageCount: number, windowPages: number): number[];
|
|
50
|
+
export declare class PagedWindowStore<T> {
|
|
51
|
+
private readonly pageSize;
|
|
52
|
+
private readonly windowPages;
|
|
53
|
+
private loadPage;
|
|
54
|
+
private held;
|
|
55
|
+
private total;
|
|
56
|
+
private anchor;
|
|
57
|
+
/** The anchor the held pages were last synced to; differs from `anchor` only while frozen. */
|
|
58
|
+
private appliedAnchor;
|
|
59
|
+
private enabled;
|
|
60
|
+
private frozen;
|
|
61
|
+
private epoch;
|
|
62
|
+
private nextToken;
|
|
63
|
+
private snapshot;
|
|
64
|
+
private listeners;
|
|
65
|
+
constructor({ pageSize, windowPages, loadPage }: PagedWindowOptions<T>);
|
|
66
|
+
/**
|
|
67
|
+
* Replaced on every render by the React binding, so a consumer's loader can
|
|
68
|
+
* close over fresh state without the store being rebuilt (rebuilding drops
|
|
69
|
+
* every held page). A change in WHAT is loaded is a `reset`, never this.
|
|
70
|
+
*/
|
|
71
|
+
setLoader(loadPage: LoadPage<T>): void;
|
|
72
|
+
getSnapshot: () => PagedWindowSnapshot<T>;
|
|
73
|
+
subscribe: (listener: () => void) => (() => void);
|
|
74
|
+
/** The viewer moved to another page. Ignored while frozen, applied on thaw. */
|
|
75
|
+
setAnchorPage(page: number): void;
|
|
76
|
+
/**
|
|
77
|
+
* While true the window neither loads nor drops pages, whatever the anchor
|
|
78
|
+
* does. A drag needs it: the carried card is mounted in its page, and
|
|
79
|
+
* dropping that page mid-drag would unmount the card and cancel the drag.
|
|
80
|
+
*/
|
|
81
|
+
setFrozen(frozen: boolean): void;
|
|
82
|
+
/** Off, nothing is held or requested. Back on, the window loads again. */
|
|
83
|
+
setEnabled(enabled: boolean): void;
|
|
84
|
+
/** The query changed: forget everything, return to the first page. */
|
|
85
|
+
reset(): void;
|
|
86
|
+
/** Re-read one held page in place. A page that is not held loads fresh when it is next wanted. */
|
|
87
|
+
invalidatePage(page: number): void;
|
|
88
|
+
/** Re-read every held page in place. */
|
|
89
|
+
invalidateAll(): void;
|
|
90
|
+
/** Load the first window. The binding calls it on mount, and again after a `stop`. */
|
|
91
|
+
start(): void;
|
|
92
|
+
/** Abort every request and release every held page. The binding calls it on unmount. */
|
|
93
|
+
stop(): void;
|
|
94
|
+
private pageCount;
|
|
95
|
+
/**
|
|
96
|
+
* Pages to hold now. Page 0 alone before the first response (the count is
|
|
97
|
+
* unknown) and for an empty list: an empty page is still held, because it is
|
|
98
|
+
* what `invalidateAll` re-reads when the list gets its first item — an empty
|
|
99
|
+
* lane that holds nothing could never find out it was no longer empty.
|
|
100
|
+
*/
|
|
101
|
+
private wanted;
|
|
102
|
+
private sync;
|
|
103
|
+
/** Start (or restart) a page's request; whatever was in flight is abandoned. */
|
|
104
|
+
private request;
|
|
105
|
+
private settle;
|
|
106
|
+
/** The list shrank: a held page past its end has nothing to show. */
|
|
107
|
+
private dropBeyondCount;
|
|
108
|
+
private dropAll;
|
|
109
|
+
private build;
|
|
110
|
+
private publish;
|
|
111
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type PagedWindowOptions, type PagedWindowSnapshot } from "./store";
|
|
2
|
+
export interface UsePagedWindowOptions<T> extends PagedWindowOptions<T> {
|
|
3
|
+
/**
|
|
4
|
+
* Names WHAT is being listed: the filter, the sort, the time range. When it
|
|
5
|
+
* changes the window forgets every page, returns to the first and the list
|
|
6
|
+
* scrolls back to the top. A change in `loadPage`'s identity alone does not:
|
|
7
|
+
* a loader closing over fresh state must not throw away what is held.
|
|
8
|
+
*/
|
|
9
|
+
queryKey: string;
|
|
10
|
+
/**
|
|
11
|
+
* Off, nothing is held or requested (a hidden lane). Back on, the window
|
|
12
|
+
* loads again.
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface PagedWindow<T> extends PagedWindowSnapshot<T> {
|
|
18
|
+
/** The viewer moved to this page. `PagedWindowList` reports it; a custom view may too. */
|
|
19
|
+
setAnchorPage: (page: number) => void;
|
|
20
|
+
/** Re-read one held page in place — a card on it changed. */
|
|
21
|
+
invalidatePage: (page: number) => void;
|
|
22
|
+
/** Re-read every held page in place — a card was created, moved or removed. */
|
|
23
|
+
invalidateAll: () => void;
|
|
24
|
+
/**
|
|
25
|
+
* While true the window neither loads nor drops pages. `PagedWindowList`
|
|
26
|
+
* sets it for the length of a drag: the carried card is mounted in its page,
|
|
27
|
+
* and dropping that page mid-drag would unmount the card and cancel the drag.
|
|
28
|
+
*/
|
|
29
|
+
setFrozen: (frozen: boolean) => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Holds `windowPages` (default 3) pages of a long server-side list and tells a
|
|
33
|
+
* view which ones to show. `loadPage` answers one page AND the list's current
|
|
34
|
+
* length, so the scrollbar can span `total` before most of it is loaded.
|
|
35
|
+
*
|
|
36
|
+
* `pageSize` and `windowPages` are fixed for the life of the hook: changing one
|
|
37
|
+
* means every held page is cut differently, which is a different list — give it
|
|
38
|
+
* a new `queryKey` and a new mount instead. It throws rather than guessing.
|
|
39
|
+
*/
|
|
40
|
+
export declare function usePagedWindow<T>({ pageSize, windowPages, loadPage, queryKey, enabled, }: UsePagedWindowOptions<T>): PagedWindow<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danxbot/ui",
|
|
3
|
-
"version": "20.
|
|
3
|
+
"version": "20.10.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",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"gates": "npm run shoot && npm run a11y && node scripts/shoot-overlays.mjs && npm run probe",
|
|
75
75
|
"a11y": "node scripts/a11y-scan.mjs",
|
|
76
76
|
"shoot": "node scripts/shoot.mjs",
|
|
77
|
-
"probe": "node scripts/probe-scale.mjs && node scripts/probe-switch.mjs && node scripts/probe-slider.mjs && node scripts/probe-panel.mjs && node scripts/probe-popover-width.mjs && node scripts/probe-api.mjs && node scripts/probe-api-live.mjs && node scripts/probe-tabs-overflow.mjs && node scripts/probe-stat-row.mjs && node scripts/probe-packaging.mjs && node scripts/probe-containment.mjs && node scripts/probe-popover-containment.mjs && node scripts/probe-popover-panel-width.mjs && node scripts/probe-theme-menu-overflow.mjs && node scripts/probe-shell.mjs && node scripts/probe-nav-trigger-tap-target.mjs && node scripts/probe-attachment-touch.mjs && node scripts/probe-dense-button.mjs && node scripts/probe-card-header.mjs && node scripts/probe-inline-edit.mjs && node scripts/probe-read-more.mjs && node scripts/probe-section-nav.mjs && node scripts/probe-attention.mjs",
|
|
77
|
+
"probe": "node scripts/probe-scale.mjs && node scripts/probe-switch.mjs && node scripts/probe-slider.mjs && node scripts/probe-panel.mjs && node scripts/probe-popover-width.mjs && node scripts/probe-api.mjs && node scripts/probe-api-live.mjs && node scripts/probe-tabs-overflow.mjs && node scripts/probe-stat-row.mjs && node scripts/probe-packaging.mjs && node scripts/probe-containment.mjs && node scripts/probe-popover-containment.mjs && node scripts/probe-popover-panel-width.mjs && node scripts/probe-theme-menu-overflow.mjs && node scripts/probe-shell.mjs && node scripts/probe-nav-trigger-tap-target.mjs && node scripts/probe-attachment-touch.mjs && node scripts/probe-dense-button.mjs && node scripts/probe-card-header.mjs && node scripts/probe-inline-edit.mjs && node scripts/probe-read-more.mjs && node scripts/probe-section-nav.mjs && node scripts/probe-attention.mjs && node scripts/probe-paged-window.mjs",
|
|
78
78
|
"sync": "node scripts/sync.mjs",
|
|
79
79
|
"visual": "node scripts/visual-docker.mjs",
|
|
80
80
|
"visual:update": "node scripts/visual-docker.mjs --update-snapshots",
|