@danxbot/ui 3.4.3 → 3.5.1
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 +9948 -9289
- package/dist/index.js.map +1 -1
- package/dist/types/components/AppShell.d.ts +32 -2
- package/dist/types/components/Board.d.ts +131 -0
- package/dist/types/components/Callout.d.ts +163 -0
- package/dist/types/components/RecordCard.d.ts +145 -1
- package/dist/types/components/board/context.d.ts +60 -0
- package/dist/types/components/board/recipe.d.ts +52 -0
- package/dist/types/components/kanban/KanbanBoard.d.ts +1 -1
- package/dist/types/components/kanban/types.d.ts +10 -0
- package/dist/types/index.d.ts +5 -1
- package/dist/types/lib/board/index.d.ts +14 -0
- package/dist/types/lib/board/model.d.ts +43 -0
- package/dist/types/lib/board/move.d.ts +162 -0
- package/dist/types/lib/board/types.d.ts +158 -0
- package/dist/types/lib/board/use-board.d.ts +47 -0
- package/package.json +5 -5
- package/dist/types/components/kanban/resolve.d.ts +0 -31
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
1
|
+
import type { MouseEvent, ReactNode } from "react";
|
|
2
2
|
import { type IconName } from "./Icon";
|
|
3
3
|
export type NavItem = {
|
|
4
4
|
id: string;
|
|
@@ -7,7 +7,37 @@ export type NavItem = {
|
|
|
7
7
|
/** A count or status shown at the trailing edge. */
|
|
8
8
|
badge?: ReactNode;
|
|
9
9
|
href?: string;
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Receives the click event, which a client-side router NEEDS in order to
|
|
12
|
+
* suppress the browser's own navigation.
|
|
13
|
+
*
|
|
14
|
+
* IT USED TO RECEIVE NOTHING, and that made this component quietly
|
|
15
|
+
* unusable with a history router. The anchor only calls `preventDefault()`
|
|
16
|
+
* when `href` is absent, so an item with BOTH `href` and `onClick` did the
|
|
17
|
+
* client-side navigation AND a full page load — tearing down the app tree
|
|
18
|
+
* and every live connection it held, on every nav click. The design system's
|
|
19
|
+
* own demo could not surface it: a hash router's `href="#/x"` never reloads
|
|
20
|
+
* either way. It showed up the moment a real consumer wired history routing.
|
|
21
|
+
*
|
|
22
|
+
* Dropping `href` to force the `preventDefault` branch works and costs too
|
|
23
|
+
* much — a nav item without an `href` is not a link, so it loses the hover
|
|
24
|
+
* URL, ctrl/cmd-click-to-new-tab and copy-link-address. Keep the `href`,
|
|
25
|
+
* take the event:
|
|
26
|
+
*
|
|
27
|
+
* ```tsx
|
|
28
|
+
* onClick: (e) => {
|
|
29
|
+
* // Let the browser have the clicks that mean "not here" — a modified
|
|
30
|
+
* // click or a middle click is an explicit request for a new tab, and
|
|
31
|
+
* // swallowing it is the most-reported bug in hand-rolled SPA links.
|
|
32
|
+
* if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
33
|
+
* e.preventDefault();
|
|
34
|
+
* navigate(item.href);
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Still router-agnostic: the shell hands over the event and decides nothing.
|
|
39
|
+
*/
|
|
40
|
+
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
11
41
|
};
|
|
12
42
|
export type NavSection = {
|
|
13
43
|
label?: string;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { AutoScrollOptions, DragStrings } from "../lib/dnd";
|
|
3
|
+
import type { BoardColumnModel, BoardItemId, UseBoardOptions, UseBoardResult } from "../lib/board";
|
|
4
|
+
export interface BoardProps<T> extends UseBoardOptions<T> {
|
|
5
|
+
/** Forwarded to `DragDrop` — announcement grammar, localisation. */
|
|
6
|
+
strings?: Partial<DragStrings>;
|
|
7
|
+
/** Forwarded to `DragDrop` — see its own doc; cannot be turned off. */
|
|
8
|
+
autoScroll?: AutoScrollOptions;
|
|
9
|
+
className?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Applied to the row the columns lay out in, NOT to the board root that
|
|
12
|
+
* `className` targets.
|
|
13
|
+
*
|
|
14
|
+
* Two seams rather than one because the two boxes take genuinely different
|
|
15
|
+
* decisions: the root is where a consumer sets the board's own size and
|
|
16
|
+
* chrome, and this row is where the columns' overflow behaviour lives —
|
|
17
|
+
* horizontal scroll on a wide board, wrapping on a narrow one. The first
|
|
18
|
+
* real consumer of this component hit the gap immediately and had to reach
|
|
19
|
+
* `overflow-x-auto` onto the root, which is the wrong box: it scrolls the
|
|
20
|
+
* live region and the instructions along with the columns.
|
|
21
|
+
*/
|
|
22
|
+
columnsClassName?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The card while it is being carried. Defaults to the card's own children.
|
|
25
|
+
*
|
|
26
|
+
* The default is the version that cannot drift from the row it stands for,
|
|
27
|
+
* which is why it is the default. But a carried card is read at a glance
|
|
28
|
+
* while it moves, and a dense resting card is the wrong thing to read that
|
|
29
|
+
* way — the two or three fields that identify the record are all anybody
|
|
30
|
+
* takes off it mid-drag.
|
|
31
|
+
*
|
|
32
|
+
* It changes what the carried card SHOWS and nothing else. Whether a card is
|
|
33
|
+
* carried, and how, is not a board's decision: the engine lifts every dragged
|
|
34
|
+
* card into a portalled clone either way.
|
|
35
|
+
*/
|
|
36
|
+
renderDragging?: (item: T) => ReactNode;
|
|
37
|
+
/** The rendered board, given the live model to map over — same shape
|
|
38
|
+
* `DragDropOverlay`'s own `children` already uses in this package for the
|
|
39
|
+
* identical reason: `Board` is generic over the consumer's item type, and
|
|
40
|
+
* a render prop is how that generic reaches the consumer's JSX without a
|
|
41
|
+
* second, parallel context API duplicating what `useBoard` already
|
|
42
|
+
* returns. */
|
|
43
|
+
children: (board: UseBoardResult<T>) => ReactNode;
|
|
44
|
+
}
|
|
45
|
+
export declare function Board<T>({ items, columns, accessors, validateMove, onMove, selection, strings, autoScroll, className, columnsClassName, renderDragging, children, }: BoardProps<T>): import("react").JSX.Element;
|
|
46
|
+
export interface BoardCardSurfaceProps {
|
|
47
|
+
className?: string;
|
|
48
|
+
children?: ReactNode;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Makes the WHOLE card a drag source, instead of the grip alone.
|
|
52
|
+
*
|
|
53
|
+
* RENDERING IT IS WHAT TURNS IT ON — there is no `wholeCardDrag` boolean, the
|
|
54
|
+
* same rule the rest of this package follows and `drag-drop.test.tsx` enforces
|
|
55
|
+
* on its own component layer. A board that wants a grip renders no surface; a
|
|
56
|
+
* board that wants the card to drag wraps its content in one.
|
|
57
|
+
*
|
|
58
|
+
* WHY THIS IS SAFE HERE, and it was not safe before. The obvious objection is
|
|
59
|
+
* that a card usually opens something when clicked, and a card that is entirely
|
|
60
|
+
* a drag handle swallows that click. True of a source that starts on
|
|
61
|
+
* `pointerdown`; false of this engine, which holds a press in `pending` until
|
|
62
|
+
* it passes an activation constraint — 5px of travel for a mouse, a 250ms dwell
|
|
63
|
+
* for a finger. A press that does not move is still a click. A press that does
|
|
64
|
+
* becomes a drag, and its trailing click is swallowed. The card can be both,
|
|
65
|
+
* and `audit:dnd` proves it on every run: a 2px wobble never enters a drag and
|
|
66
|
+
* still counts as a click.
|
|
67
|
+
*
|
|
68
|
+
* THE 2.5.7 CONTROL IS NOT AFFECTED. The menu the card hands out is the
|
|
69
|
+
* single-pointer, non-dragging route to every move, and it stays exactly where
|
|
70
|
+
* it was. What the surface removes is the GRIP, which would otherwise be a
|
|
71
|
+
* second drag source for the same card.
|
|
72
|
+
*
|
|
73
|
+
* It also cannot produce a button inside a button: `DragDropSurface` takes a
|
|
74
|
+
* role only when it owns focus — when it contains no focusable of its own —
|
|
75
|
+
* and a card carrying the move menu never does.
|
|
76
|
+
*/
|
|
77
|
+
export declare function BoardCardSurface({ className, children }: BoardCardSurfaceProps): import("react").JSX.Element;
|
|
78
|
+
export interface BoardColumnProps<T> {
|
|
79
|
+
/** `useBoard`'s own computed column — id, label, items, count, wipLimit,
|
|
80
|
+
* overWip. Passed straight through; nothing here re-derives it. */
|
|
81
|
+
column: BoardColumnModel<T>;
|
|
82
|
+
/**
|
|
83
|
+
* Rendered in place of `children` when the column has no cards. Content,
|
|
84
|
+
* not a boolean — supplying THIS is what changes it, matching the
|
|
85
|
+
* package-wide rule against a `show*`/`with*` switch. Defaults to a
|
|
86
|
+
* generic message built on `EmptyState` (REUSE: "An empty list, or a
|
|
87
|
+
* zero-state screen"), sized down for a column rather than a full page.
|
|
88
|
+
*/
|
|
89
|
+
emptyState?: ReactNode;
|
|
90
|
+
className?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Applied to the droppable list, NOT to the column shell that `className`
|
|
93
|
+
* targets — this is where a column's own scrolling belongs
|
|
94
|
+
* (`max-h-… overflow-y-auto`).
|
|
95
|
+
*
|
|
96
|
+
* It has to be the inner box: put the scroll on the shell and the header
|
|
97
|
+
* scrolls away with the cards, so a column whose cards have been scrolled
|
|
98
|
+
* loses the label and count that say what the column IS. The drag engine
|
|
99
|
+
* already resolves whichever scroller sits under the pointer, so a column
|
|
100
|
+
* that scrolls here auto-scrolls during a drag with nothing further wired.
|
|
101
|
+
*/
|
|
102
|
+
listClassName?: string;
|
|
103
|
+
/** The column's cards — a `BoardCard` per item, mapped by the consumer
|
|
104
|
+
* exactly as `DragDropContainer`'s own children already are. This is the
|
|
105
|
+
* virtualization seam — see the file header. */
|
|
106
|
+
children?: ReactNode;
|
|
107
|
+
}
|
|
108
|
+
export declare function BoardColumn<T>({ column, emptyState, className, listClassName, children, }: BoardColumnProps<T>): import("react").JSX.Element;
|
|
109
|
+
export interface BoardCardProps {
|
|
110
|
+
id: BoardItemId;
|
|
111
|
+
/** Position within its OWN column right now — same contract as
|
|
112
|
+
* `DragDropItem.index`: the real index in the consumer's data, never a
|
|
113
|
+
* filtered render order. */
|
|
114
|
+
index: number;
|
|
115
|
+
/** Spoken by the drag engine's announcements and this card's own "Move
|
|
116
|
+
* <label>" menu trigger label. Falls back to `id`, which is speakable and
|
|
117
|
+
* not great — supply it. */
|
|
118
|
+
label?: string;
|
|
119
|
+
className?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Card content, 100% consumer-owned — `Board` and `BoardCard` do not know
|
|
122
|
+
* what is inside. `handle` is the dual-purpose grip-and-menu control (see
|
|
123
|
+
* the file header); RES-GAME's evidence is that a board renders this
|
|
124
|
+
* INSIDE its `RecordCardHandle` slot (`RecordCard.tsx` reserves exactly
|
|
125
|
+
* this region), but nothing here requires that specific composition — it
|
|
126
|
+
* is a plain `ReactNode`, placeable anywhere the consumer's markup wants a
|
|
127
|
+
* pointer-operable, non-dragging route to every move this card can make.
|
|
128
|
+
*/
|
|
129
|
+
children: (handle: ReactNode) => ReactNode;
|
|
130
|
+
}
|
|
131
|
+
export declare function BoardCard({ id, index, label, className, children }: BoardCardProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode, Ref } from "react";
|
|
2
|
+
import { type VariantProps } from "tailwind-variants";
|
|
3
|
+
declare const callout: import("tailwind-variants").TVReturnType<{
|
|
4
|
+
tone: {
|
|
5
|
+
neutral: {
|
|
6
|
+
root: string;
|
|
7
|
+
glyph: string;
|
|
8
|
+
title: string;
|
|
9
|
+
body: string;
|
|
10
|
+
};
|
|
11
|
+
info: {
|
|
12
|
+
root: string;
|
|
13
|
+
glyph: string;
|
|
14
|
+
title: string;
|
|
15
|
+
body: string;
|
|
16
|
+
};
|
|
17
|
+
success: {
|
|
18
|
+
root: string;
|
|
19
|
+
glyph: string;
|
|
20
|
+
title: string;
|
|
21
|
+
body: string;
|
|
22
|
+
};
|
|
23
|
+
warning: {
|
|
24
|
+
root: string;
|
|
25
|
+
glyph: string;
|
|
26
|
+
title: string;
|
|
27
|
+
body: string;
|
|
28
|
+
};
|
|
29
|
+
danger: {
|
|
30
|
+
root: string;
|
|
31
|
+
glyph: string;
|
|
32
|
+
title: string;
|
|
33
|
+
body: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
emphasis: {
|
|
37
|
+
subtle: {};
|
|
38
|
+
strong: {
|
|
39
|
+
root: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
}, {
|
|
43
|
+
root: string;
|
|
44
|
+
glyph: string;
|
|
45
|
+
content: string;
|
|
46
|
+
title: string;
|
|
47
|
+
body: string;
|
|
48
|
+
actions: string;
|
|
49
|
+
}, undefined, {
|
|
50
|
+
tone: {
|
|
51
|
+
neutral: {
|
|
52
|
+
root: string;
|
|
53
|
+
glyph: string;
|
|
54
|
+
title: string;
|
|
55
|
+
body: string;
|
|
56
|
+
};
|
|
57
|
+
info: {
|
|
58
|
+
root: string;
|
|
59
|
+
glyph: string;
|
|
60
|
+
title: string;
|
|
61
|
+
body: string;
|
|
62
|
+
};
|
|
63
|
+
success: {
|
|
64
|
+
root: string;
|
|
65
|
+
glyph: string;
|
|
66
|
+
title: string;
|
|
67
|
+
body: string;
|
|
68
|
+
};
|
|
69
|
+
warning: {
|
|
70
|
+
root: string;
|
|
71
|
+
glyph: string;
|
|
72
|
+
title: string;
|
|
73
|
+
body: string;
|
|
74
|
+
};
|
|
75
|
+
danger: {
|
|
76
|
+
root: string;
|
|
77
|
+
glyph: string;
|
|
78
|
+
title: string;
|
|
79
|
+
body: string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
emphasis: {
|
|
83
|
+
subtle: {};
|
|
84
|
+
strong: {
|
|
85
|
+
root: string;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
}, {
|
|
89
|
+
root: string;
|
|
90
|
+
glyph: string;
|
|
91
|
+
content: string;
|
|
92
|
+
title: string;
|
|
93
|
+
body: string;
|
|
94
|
+
actions: string;
|
|
95
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
96
|
+
tone: {
|
|
97
|
+
neutral: {
|
|
98
|
+
root: string;
|
|
99
|
+
glyph: string;
|
|
100
|
+
title: string;
|
|
101
|
+
body: string;
|
|
102
|
+
};
|
|
103
|
+
info: {
|
|
104
|
+
root: string;
|
|
105
|
+
glyph: string;
|
|
106
|
+
title: string;
|
|
107
|
+
body: string;
|
|
108
|
+
};
|
|
109
|
+
success: {
|
|
110
|
+
root: string;
|
|
111
|
+
glyph: string;
|
|
112
|
+
title: string;
|
|
113
|
+
body: string;
|
|
114
|
+
};
|
|
115
|
+
warning: {
|
|
116
|
+
root: string;
|
|
117
|
+
glyph: string;
|
|
118
|
+
title: string;
|
|
119
|
+
body: string;
|
|
120
|
+
};
|
|
121
|
+
danger: {
|
|
122
|
+
root: string;
|
|
123
|
+
glyph: string;
|
|
124
|
+
title: string;
|
|
125
|
+
body: string;
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
emphasis: {
|
|
129
|
+
subtle: {};
|
|
130
|
+
strong: {
|
|
131
|
+
root: string;
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
}, {
|
|
135
|
+
root: string;
|
|
136
|
+
glyph: string;
|
|
137
|
+
content: string;
|
|
138
|
+
title: string;
|
|
139
|
+
body: string;
|
|
140
|
+
actions: string;
|
|
141
|
+
}>>;
|
|
142
|
+
export interface CalloutProps extends Omit<HTMLAttributes<HTMLDivElement>, "title">, VariantProps<typeof callout> {
|
|
143
|
+
/** The condition, in one line. */
|
|
144
|
+
title: ReactNode;
|
|
145
|
+
/**
|
|
146
|
+
* Override the per-tone default shape. Pass `null` to render no icon at all
|
|
147
|
+
* — for a tone that is genuinely not a severity.
|
|
148
|
+
*/
|
|
149
|
+
icon?: ReactNode | null;
|
|
150
|
+
/** What to do about it. The half that makes a callout useful rather than a complaint. */
|
|
151
|
+
children?: ReactNode;
|
|
152
|
+
/** Buttons or links. Rendered under the body, never beside the title. */
|
|
153
|
+
actions?: ReactNode;
|
|
154
|
+
/**
|
|
155
|
+
* Announce assertively via `role="alert"`. Opt-in — see the header. Reserve
|
|
156
|
+
* for a condition that appears in response to a change, not one present at
|
|
157
|
+
* load.
|
|
158
|
+
*/
|
|
159
|
+
live?: boolean;
|
|
160
|
+
ref?: Ref<HTMLDivElement>;
|
|
161
|
+
}
|
|
162
|
+
export declare function Callout({ tone, emphasis, title, icon, children, actions, live, className, ref, ...props }: CalloutProps): import("react").JSX.Element;
|
|
163
|
+
export { callout as calloutVariants };
|
|
@@ -116,6 +116,76 @@ declare const record: import("tailwind-variants").TVReturnType<{
|
|
|
116
116
|
metricValue: string;
|
|
117
117
|
footer: string;
|
|
118
118
|
}>>;
|
|
119
|
+
declare const recordCard: import("tailwind-variants").TVReturnType<{
|
|
120
|
+
/**
|
|
121
|
+
* Layout, not content. `corner` is the assignee-avatar shape (small,
|
|
122
|
+
* square, sits beside the title); `cover` is the banner-image shape (full
|
|
123
|
+
* width, wide aspect). Same slot, same DOM position — only the geometry
|
|
124
|
+
* changes, which is the whole argument for not splitting this into two
|
|
125
|
+
* props.
|
|
126
|
+
*/
|
|
127
|
+
placement: {
|
|
128
|
+
corner: {
|
|
129
|
+
media: string;
|
|
130
|
+
};
|
|
131
|
+
cover: {
|
|
132
|
+
media: string;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
}, {
|
|
136
|
+
handle: string;
|
|
137
|
+
eyebrow: string;
|
|
138
|
+
title: string;
|
|
139
|
+
badges: string;
|
|
140
|
+
media: string;
|
|
141
|
+
meta: string;
|
|
142
|
+
}, undefined, {
|
|
143
|
+
/**
|
|
144
|
+
* Layout, not content. `corner` is the assignee-avatar shape (small,
|
|
145
|
+
* square, sits beside the title); `cover` is the banner-image shape (full
|
|
146
|
+
* width, wide aspect). Same slot, same DOM position — only the geometry
|
|
147
|
+
* changes, which is the whole argument for not splitting this into two
|
|
148
|
+
* props.
|
|
149
|
+
*/
|
|
150
|
+
placement: {
|
|
151
|
+
corner: {
|
|
152
|
+
media: string;
|
|
153
|
+
};
|
|
154
|
+
cover: {
|
|
155
|
+
media: string;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
}, {
|
|
159
|
+
handle: string;
|
|
160
|
+
eyebrow: string;
|
|
161
|
+
title: string;
|
|
162
|
+
badges: string;
|
|
163
|
+
media: string;
|
|
164
|
+
meta: string;
|
|
165
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
166
|
+
/**
|
|
167
|
+
* Layout, not content. `corner` is the assignee-avatar shape (small,
|
|
168
|
+
* square, sits beside the title); `cover` is the banner-image shape (full
|
|
169
|
+
* width, wide aspect). Same slot, same DOM position — only the geometry
|
|
170
|
+
* changes, which is the whole argument for not splitting this into two
|
|
171
|
+
* props.
|
|
172
|
+
*/
|
|
173
|
+
placement: {
|
|
174
|
+
corner: {
|
|
175
|
+
media: string;
|
|
176
|
+
};
|
|
177
|
+
cover: {
|
|
178
|
+
media: string;
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
}, {
|
|
182
|
+
handle: string;
|
|
183
|
+
eyebrow: string;
|
|
184
|
+
title: string;
|
|
185
|
+
badges: string;
|
|
186
|
+
media: string;
|
|
187
|
+
meta: string;
|
|
188
|
+
}>>;
|
|
119
189
|
export interface RecordCardMetric {
|
|
120
190
|
label: ReactNode;
|
|
121
191
|
value: ReactNode;
|
|
@@ -123,7 +193,13 @@ export interface RecordCardMetric {
|
|
|
123
193
|
export interface RecordCardProps extends VariantProps<typeof record> {
|
|
124
194
|
/** The record's own id — rendered mono, above the title. */
|
|
125
195
|
identifier?: ReactNode;
|
|
126
|
-
|
|
196
|
+
/**
|
|
197
|
+
* Optional ONLY so a caller can compose the parts instead (see the header).
|
|
198
|
+
* For prop-driven use it is effectively required — a record card with no
|
|
199
|
+
* title is not a record card — and omitting it drops the whole top row
|
|
200
|
+
* rather than rendering an empty one.
|
|
201
|
+
*/
|
|
202
|
+
title?: ReactNode;
|
|
127
203
|
/** What kind of record this is, or who it belongs to. One line. */
|
|
128
204
|
subtitle?: ReactNode;
|
|
129
205
|
/** State chips. A slot, so their tones and behaviour stay the consumer's. */
|
|
@@ -150,4 +226,72 @@ export interface RecordCardProps extends VariantProps<typeof record> {
|
|
|
150
226
|
onClick?: (event: React.MouseEvent) => void;
|
|
151
227
|
}
|
|
152
228
|
export declare function RecordCard({ identifier, title, subtitle, badges, metrics, media, action, footer, emphasis, interactive, selected, render, className, children, ref, ...props }: RecordCardProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
229
|
+
export interface RecordCardHandleProps {
|
|
230
|
+
className?: string;
|
|
231
|
+
/** Whatever the board wants reachable here — a drag handle, a menu trigger,
|
|
232
|
+
* a dual-purpose control combining both. This component owns none of that
|
|
233
|
+
* behaviour; it only reserves the shape (shrink-resistant, stretches to
|
|
234
|
+
* match a flex-row sibling) so the board's control does not have to fight
|
|
235
|
+
* the record's own layout for space. */
|
|
236
|
+
children: ReactNode;
|
|
237
|
+
ref?: Ref<HTMLSpanElement>;
|
|
238
|
+
}
|
|
239
|
+
/** The region a board can slot a drag handle into. Absent entirely when a
|
|
240
|
+
* card is rendered outside any board — nothing here assumes one exists. */
|
|
241
|
+
export declare function RecordCardHandle({ className, children, ref }: RecordCardHandleProps): import("react").JSX.Element;
|
|
242
|
+
export interface RecordCardEyebrowProps {
|
|
243
|
+
className?: string;
|
|
244
|
+
children: ReactNode;
|
|
245
|
+
ref?: Ref<HTMLSpanElement>;
|
|
246
|
+
}
|
|
247
|
+
/** The identifier line — an id, a code, a short kicker. Answers WHICH record
|
|
248
|
+
* this is, which is a different question from the one `Title` answers. */
|
|
249
|
+
export declare function RecordCardEyebrow({ className, children, ref }: RecordCardEyebrowProps): import("react").JSX.Element;
|
|
250
|
+
export interface RecordCardTitleProps {
|
|
251
|
+
/**
|
|
252
|
+
* The heading level this title renders as.
|
|
253
|
+
*
|
|
254
|
+
* See `CardHeader.titleAs` — the reasoning is identical and does not bear
|
|
255
|
+
* repeating differently: only the caller knows what sits above this card in
|
|
256
|
+
* the page outline.
|
|
257
|
+
*
|
|
258
|
+
* @default "h3"
|
|
259
|
+
*/
|
|
260
|
+
as?: "h2" | "h3" | "h4" | "h5" | "h6";
|
|
261
|
+
className?: string;
|
|
262
|
+
children: ReactNode;
|
|
263
|
+
ref?: Ref<HTMLHeadingElement>;
|
|
264
|
+
}
|
|
265
|
+
/** Clamped to two lines by default — a collapsed record has a fixed budget of
|
|
266
|
+
* vertical space, and a title that runs on pushes the meta row an
|
|
267
|
+
* unpredictable distance down the column instead of wrapping in place. */
|
|
268
|
+
export declare function RecordCardTitle({ as: Title, className, children, ref }: RecordCardTitleProps): import("react").JSX.Element;
|
|
269
|
+
export interface RecordCardBadgesProps {
|
|
270
|
+
className?: string;
|
|
271
|
+
children: ReactNode;
|
|
272
|
+
ref?: Ref<HTMLDivElement>;
|
|
273
|
+
}
|
|
274
|
+
/** A wrapping row for a SMALL set of status/priority badges — `Badge` from
|
|
275
|
+
* this same library, composed by the consumer. This component supplies only
|
|
276
|
+
* the row layout; it has no opinion on how many badges is too many. */
|
|
277
|
+
export declare function RecordCardBadges({ className, children, ref }: RecordCardBadgesProps): import("react").JSX.Element;
|
|
278
|
+
export interface RecordCardMediaProps extends VariantProps<typeof recordCard> {
|
|
279
|
+
className?: string;
|
|
280
|
+
children: ReactNode;
|
|
281
|
+
ref?: Ref<HTMLDivElement>;
|
|
282
|
+
}
|
|
283
|
+
/** The media/cover region — an assignee avatar (`placement="corner"`, the
|
|
284
|
+
* default) or a banner image (`placement="cover"`). See the file header for
|
|
285
|
+
* why these are one slot rather than two. */
|
|
286
|
+
export declare function RecordCardMedia({ placement, className, children, ref }: RecordCardMediaProps): import("react").JSX.Element;
|
|
287
|
+
export interface RecordCardMetaProps {
|
|
288
|
+
className?: string;
|
|
289
|
+
children: ReactNode;
|
|
290
|
+
ref?: Ref<HTMLDivElement>;
|
|
291
|
+
}
|
|
292
|
+
/** The one compact secondary-metadata row — comment count, dependency count,
|
|
293
|
+
* a due date. Full description, comment threads and history are explicitly
|
|
294
|
+
* not this component's problem; they live behind a click, on whatever detail
|
|
295
|
+
* surface the consumer opens from here. */
|
|
296
|
+
export declare function RecordCardMeta({ className, children, ref }: RecordCardMetaProps): import("react").JSX.Element;
|
|
153
297
|
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { BoardColumnId, BoardColumnModel, BoardItemId, BoardMoveRequest, BoardMoveVerdict } from "../../lib/board";
|
|
2
|
+
export declare const BoardCardSurfaceContext: import("react").Context<boolean>;
|
|
3
|
+
/** `true` when an ancestor `BoardCardSurface` makes this whole card draggable. */
|
|
4
|
+
export declare function useBoardCardIsDragSource(): boolean;
|
|
5
|
+
export interface BoardContextValue<T> {
|
|
6
|
+
/** Every declared column, in order, as `useBoard` last computed it. The
|
|
7
|
+
* "Move to…" menu reads `id` / `label` / `count` off this to offer every
|
|
8
|
+
* OTHER column as a destination and to compute an append index. */
|
|
9
|
+
columns: readonly BoardColumnModel<T>[];
|
|
10
|
+
/**
|
|
11
|
+
* The single funnel — see `lib/board/use-board.ts`. Every input source
|
|
12
|
+
* (drag, keyboard, the menu) calls exactly THIS and nothing else.
|
|
13
|
+
*
|
|
14
|
+
* This is `Board.tsx`'s own wrapper around `useBoard`'s `requestMove`, not
|
|
15
|
+
* the raw hook result — it ALSO surfaces a rejected verdict's reason (see
|
|
16
|
+
* `types.ts`'s own doc on `BoardMoveVerdict`: "written for a person to
|
|
17
|
+
* read, not logged") before returning it. Routing that through the same
|
|
18
|
+
* function every caller already has to call — rather than a second
|
|
19
|
+
* `reportRejection` a caller could forget — is what makes "a rejected move
|
|
20
|
+
* never fails silently" true of every source by construction, not by
|
|
21
|
+
* convention.
|
|
22
|
+
*/
|
|
23
|
+
requestMove: (request: BoardMoveRequest) => BoardMoveVerdict;
|
|
24
|
+
}
|
|
25
|
+
export interface BoardColumnContextValue {
|
|
26
|
+
columnId: BoardColumnId;
|
|
27
|
+
label: string;
|
|
28
|
+
}
|
|
29
|
+
export interface BoardCardContextValue {
|
|
30
|
+
itemId: BoardItemId;
|
|
31
|
+
/** Position within ITS OWN column right now — the `from.index` half of any
|
|
32
|
+
* move this card's handle constructs. */
|
|
33
|
+
index: number;
|
|
34
|
+
label: string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Called by the card's move control on mount, returning its own cleanup.
|
|
37
|
+
*
|
|
38
|
+
* WHY A REGISTRATION RATHER THAN TRUST. `BoardCard` hands its control out
|
|
39
|
+
* through a render prop, which is what keeps card layout entirely
|
|
40
|
+
* consumer-owned — but a render prop can be received and never placed, and
|
|
41
|
+
* the thing that would go missing is the WCAG 2.2 SC 2.5.7 pointer
|
|
42
|
+
* alternative: the one control a touchscreen user with no keyboard has. That
|
|
43
|
+
* failure has no error, no type error and no visible symptom for anyone
|
|
44
|
+
* testing with a mouse, which is precisely the class this project keeps
|
|
45
|
+
* finding.
|
|
46
|
+
*
|
|
47
|
+
* So the control announces itself and `BoardCard` checks. React runs child
|
|
48
|
+
* effects before parent effects, so by the time the card's own effect runs
|
|
49
|
+
* the answer is already known. This is the same shape `DragDrop` uses to
|
|
50
|
+
* learn whether an overlay was rendered (`registerOverlay`) — a part reports
|
|
51
|
+
* its own existence rather than the parent trying to inspect its children.
|
|
52
|
+
*/
|
|
53
|
+
registerHandle: () => () => void;
|
|
54
|
+
}
|
|
55
|
+
export declare const BoardProvider: import("react").Provider<BoardContextValue<unknown> | null>;
|
|
56
|
+
export declare const BoardColumnProvider: import("react").Provider<BoardColumnContextValue | null>;
|
|
57
|
+
export declare const BoardCardProvider: import("react").Provider<BoardCardContextValue | null>;
|
|
58
|
+
export declare function useBoardContext<T>(component: string): BoardContextValue<T>;
|
|
59
|
+
export declare function useBoardColumnContext(component: string): BoardColumnContextValue;
|
|
60
|
+
export declare function useBoardCardContext(component: string): BoardCardContextValue;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare const board: import("tailwind-variants").TVReturnType<{
|
|
2
|
+
overWip: {
|
|
3
|
+
true: {
|
|
4
|
+
header: string;
|
|
5
|
+
label: string;
|
|
6
|
+
};
|
|
7
|
+
false: {};
|
|
8
|
+
};
|
|
9
|
+
}, {
|
|
10
|
+
column: string;
|
|
11
|
+
header: string[];
|
|
12
|
+
label: string;
|
|
13
|
+
list: string;
|
|
14
|
+
empty: string;
|
|
15
|
+
handleCluster: string;
|
|
16
|
+
menuTrigger: string[];
|
|
17
|
+
rejection: string[];
|
|
18
|
+
}, undefined, {
|
|
19
|
+
overWip: {
|
|
20
|
+
true: {
|
|
21
|
+
header: string;
|
|
22
|
+
label: string;
|
|
23
|
+
};
|
|
24
|
+
false: {};
|
|
25
|
+
};
|
|
26
|
+
}, {
|
|
27
|
+
column: string;
|
|
28
|
+
header: string[];
|
|
29
|
+
label: string;
|
|
30
|
+
list: string;
|
|
31
|
+
empty: string;
|
|
32
|
+
handleCluster: string;
|
|
33
|
+
menuTrigger: string[];
|
|
34
|
+
rejection: string[];
|
|
35
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
36
|
+
overWip: {
|
|
37
|
+
true: {
|
|
38
|
+
header: string;
|
|
39
|
+
label: string;
|
|
40
|
+
};
|
|
41
|
+
false: {};
|
|
42
|
+
};
|
|
43
|
+
}, {
|
|
44
|
+
column: string;
|
|
45
|
+
header: string[];
|
|
46
|
+
label: string;
|
|
47
|
+
list: string;
|
|
48
|
+
empty: string;
|
|
49
|
+
handleCluster: string;
|
|
50
|
+
menuTrigger: string[];
|
|
51
|
+
rejection: string[];
|
|
52
|
+
}>>;
|
|
@@ -16,6 +16,16 @@ export interface KanbanLane<T> {
|
|
|
16
16
|
limit?: number;
|
|
17
17
|
/** In the order they should appear. Their index is what a move reports. */
|
|
18
18
|
items: readonly T[];
|
|
19
|
+
/**
|
|
20
|
+
* Shown in THIS lane when it has no cards, overriding the board's own
|
|
21
|
+
* `emptyLane`.
|
|
22
|
+
*
|
|
23
|
+
* One message for a whole board is right until one lane means something
|
|
24
|
+
* different from the others — an empty backlog reads "nothing waiting" and an
|
|
25
|
+
* empty released column reads "nothing shipped yet", and a single string has
|
|
26
|
+
* to be vague enough to be true of both, which makes it useless for either.
|
|
27
|
+
*/
|
|
28
|
+
empty?: ReactNode;
|
|
19
29
|
/**
|
|
20
30
|
* Why a card may not be dropped here. Absent means the lane accepts drops.
|
|
21
31
|
*
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { coreIcons, type CoreIconName } from "./icons/data";
|
|
|
15
15
|
export { Button, buttonVariants, type ButtonProps } from "./components/Button";
|
|
16
16
|
export { IconButton, type IconButtonProps, type IconButtonVariant, type IconButtonTone, } from "./components/IconButton";
|
|
17
17
|
export { Badge, badgeVariants, type BadgeProps } from "./components/Badge";
|
|
18
|
+
export { Callout, calloutVariants, type CalloutProps } from "./components/Callout";
|
|
18
19
|
export { Spinner, type SpinnerProps } from "./components/Spinner";
|
|
19
20
|
export { Skeleton, SkeletonText, LoadingOverlay, type SkeletonProps, type SkeletonTextProps, type LoadingOverlayProps, } from "./components/Loading";
|
|
20
21
|
export { ErrorBoundary } from "./components/ErrorBoundary";
|
|
@@ -38,7 +39,7 @@ export { Combobox, ComboboxItem, ComboboxGroup, MultiCombobox, type ComboboxProp
|
|
|
38
39
|
export { Select, SelectItem, SelectGroup, SelectSeparator, type SelectProps, type SelectItemProps, type SelectGroupProps, } from "./components/Select";
|
|
39
40
|
export { StatusSelect, type StatusSelectProps, type StatusOption } from "./components/StatusSelect";
|
|
40
41
|
export { Card, CardHeader, CardFooter, type CardProps, type CardHeaderProps, } from "./components/Card";
|
|
41
|
-
export { RecordCard, type RecordCardProps, type RecordCardMetric, } from "./components/RecordCard";
|
|
42
|
+
export { RecordCard, RecordCardHandle, RecordCardEyebrow, RecordCardTitle, RecordCardBadges, RecordCardMedia, RecordCardMeta, type RecordCardProps, type RecordCardMetric, type RecordCardHandleProps, type RecordCardEyebrowProps, type RecordCardTitleProps, type RecordCardBadgesProps, type RecordCardMediaProps, type RecordCardMetaProps, } from "./components/RecordCard";
|
|
42
43
|
export { Tabs, TabList, Tab, TabPanel, type TabsProps, type TabListProps, type TabProps, type TabPanelProps, } from "./components/Tabs";
|
|
43
44
|
export { Accordion, AccordionItem, type AccordionProps, type AccordionItemProps, } from "./components/Accordion";
|
|
44
45
|
export { Breadcrumb, Pagination, type BreadcrumbProps, type PaginationProps, type Crumb, } from "./components/Navigation";
|
|
@@ -72,6 +73,9 @@ export { parseMarkdown, MarkdownNodes, sanitizeHref, type MdNode, type MdInline,
|
|
|
72
73
|
export { DragDrop, DragDropContainer, DragDropItem, DragDropHandle, DragDropSurface, type DragDropProps, type DragDropContainerProps, type DragDropItemProps, type DragDropHandleProps, type DragDropSurfaceProps, } from "./components/DragDrop";
|
|
73
74
|
export { KanbanBoard, type KanbanBoardProps, type KanbanLane, type KanbanMove, type KanbanRefusal, } from "./components/kanban/KanbanBoard";
|
|
74
75
|
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";
|
|
76
|
+
export { Board, BoardColumn, BoardCard, BoardCardSurface, type BoardProps, type BoardColumnProps, type BoardCardProps, type BoardCardSurfaceProps, } from "./components/Board";
|
|
77
|
+
export { buildBoardModel, resolveMove, applyBoardMoves, useBoard, type BoardModel, type UseBoardResult, } from "./lib/board";
|
|
78
|
+
export type { BoardAccessors, BoardColumnDef, BoardColumnId, BoardColumnModel, BoardItemId, BoardMove, BoardMoveRequest, BoardMoveSource, BoardMoveVerdict, UseBoardOptions, } from "./lib/board";
|
|
75
79
|
export type { MessageRole, MessagePart, MessagePartType, TextPart, CodePart, ReasoningPart, ToolPart, ToolStatus, FilePart, ComponentPart, ChatFile, ChatMessage, RenderContext, PartRenderer, PartRenderers, ChatComponentRenderer, ChatComponents, } from "./components/chat/types";
|
|
76
80
|
export { Chat, ChatPopover, type ChatProps, type ChatPopoverProps, type ChatSurface, } from "./components/chat/Chat";
|
|
77
81
|
export { Message, MessagePartView, ToolCall, ChatMarker, type MessageProps, type MessageAction, type MessagePartViewProps, type ToolCallProps, type ChatMarkerProps, } from "./components/chat/Message";
|