@danxbot/ui 3.4.3 → 3.5.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.
@@ -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
- onClick?: () => void;
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
- title: ReactNode;
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
+ }>>;
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from "react";
1
+ import { type ReactNode } from "react";
2
2
  import type { DragSessionCallbacks } from "../../lib/dnd";
3
3
  import type { KanbanLane, KanbanMove, KanbanRefusal } from "./types";
4
4
  export type { KanbanLane, KanbanMove, KanbanRefusal };
@@ -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
  *
@@ -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";