gridsmith-ui 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +969 -0
- package/README.md +21 -5
- package/dist/charts.d.ts +2 -2
- package/dist/charts.js +58 -43
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +4 -3
- package/dist/chat.js.map +1 -1
- package/dist/{chunk-CYN5O567.js → chunk-2CKSSWYG.js} +9 -5
- package/dist/chunk-2CKSSWYG.js.map +1 -0
- package/dist/chunk-3BRQRKDO.js +1 -0
- package/dist/chunk-3BRQRKDO.js.map +1 -1
- package/dist/{chunk-RWKCAKN3.js → chunk-5TUVX4B2.js} +6 -5
- package/dist/chunk-5TUVX4B2.js.map +1 -0
- package/dist/{chunk-X2HEV7FB.js → chunk-64TXZ4L7.js} +23 -33
- package/dist/chunk-64TXZ4L7.js.map +1 -0
- package/dist/chunk-7Q46JXSK.js +1 -0
- package/dist/chunk-7Q46JXSK.js.map +1 -1
- package/dist/chunk-CRQ6KCRD.js +1 -0
- package/dist/chunk-CRQ6KCRD.js.map +1 -1
- package/dist/{chunk-ZYVXV4WC.js → chunk-EKBWWA6P.js} +53 -6
- package/dist/chunk-EKBWWA6P.js.map +1 -0
- package/dist/chunk-HP7WUZPK.js +1 -0
- package/dist/chunk-HP7WUZPK.js.map +1 -1
- package/dist/{chunk-MYIJNVTK.js → chunk-IXR4UEF4.js} +5 -4
- package/dist/chunk-IXR4UEF4.js.map +1 -0
- package/dist/chunk-M2QRNBDQ.js +1 -0
- package/dist/chunk-M2QRNBDQ.js.map +1 -1
- package/dist/chunk-MD2EFMES.js +1 -0
- package/dist/chunk-MD2EFMES.js.map +1 -1
- package/dist/chunk-NRHIYS5W.js +1 -0
- package/dist/chunk-NRHIYS5W.js.map +1 -1
- package/dist/chunk-OTCEJN64.js +1 -0
- package/dist/chunk-OTCEJN64.js.map +1 -1
- package/dist/chunk-OYNUU346.js +78 -0
- package/dist/chunk-OYNUU346.js.map +1 -0
- package/dist/{chunk-EX64MN2U.js → chunk-PO65I3MQ.js} +4 -3
- package/dist/chunk-PO65I3MQ.js.map +1 -0
- package/dist/chunk-QM4SJKWV.js +1 -0
- package/dist/chunk-QM4SJKWV.js.map +1 -1
- package/dist/{chunk-KWLNEH53.js → chunk-R5NFCEZ3.js} +10 -7
- package/dist/chunk-R5NFCEZ3.js.map +1 -0
- package/dist/chunk-SFY2KMHG.js +1 -0
- package/dist/chunk-SFY2KMHG.js.map +1 -1
- package/dist/{chunk-HXVXJUGV.js → chunk-TJEV7YAY.js} +38 -10
- package/dist/chunk-TJEV7YAY.js.map +1 -0
- package/dist/chunk-WH2FUFAC.js +1 -0
- package/dist/chunk-WH2FUFAC.js.map +1 -1
- package/dist/chunk-XVB55M3N.js +1 -0
- package/dist/chunk-XVB55M3N.js.map +1 -1
- package/dist/chunk-ZI3OQDET.js +1 -0
- package/dist/chunk-ZI3OQDET.js.map +1 -1
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +5 -3
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.js +2 -1
- package/dist/editor-mentions.js.map +1 -1
- package/dist/editor.js +3 -2
- package/dist/editor.js.map +1 -1
- package/dist/{feather-VFWLAILO.js → feather-FNBQ74RR.js} +10 -17
- package/dist/feather-FNBQ74RR.js.map +1 -0
- package/dist/{heroicons-H3Z7DFCF.js → heroicons-DODCSYWD.js} +9 -8
- package/dist/heroicons-DODCSYWD.js.map +1 -0
- package/dist/icons.d.ts +31 -4
- package/dist/icons.js +2 -1
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +418 -65
- package/dist/index.js +1893 -838
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +3 -2
- package/dist/kanban.js.map +1 -1
- package/dist/{lucide-MR32KM4G.js → lucide-ZWE3EPGP.js} +9 -8
- package/dist/lucide-ZWE3EPGP.js.map +1 -0
- package/dist/{phosphor-ABQQL5N5.js → phosphor-DIHPA4AJ.js} +9 -8
- package/dist/phosphor-DIHPA4AJ.js.map +1 -0
- package/dist/resizable.js +7 -5
- package/dist/resizable.js.map +1 -1
- package/dist/roots.css +25 -7
- package/dist/{tabler-ANUSY4D2.js → tabler-D3VYTSGI.js} +9 -8
- package/dist/tabler-D3VYTSGI.js.map +1 -0
- package/dist/tokens.css +11 -8
- package/dist/{use-pagination-BnKOnBdz.d.ts → use-pagination-BxcRlNQG.d.ts} +6 -0
- package/dist/utils.d.ts +275 -1
- package/dist/utils.js +875 -1
- package/dist/utils.js.map +1 -1
- package/dist/virtualized.d.ts +1 -1
- package/dist/virtualized.js +5 -3
- package/dist/virtualized.js.map +1 -1
- package/dist-static/tokens.css +11 -8
- package/package.json +5 -3
- package/dist/chunk-CYN5O567.js.map +0 -1
- package/dist/chunk-EX64MN2U.js.map +0 -1
- package/dist/chunk-HXVXJUGV.js.map +0 -1
- package/dist/chunk-KWLNEH53.js.map +0 -1
- package/dist/chunk-MYIJNVTK.js.map +0 -1
- package/dist/chunk-RWKCAKN3.js.map +0 -1
- package/dist/chunk-X2HEV7FB.js.map +0 -1
- package/dist/chunk-ZYVXV4WC.js.map +0 -1
- package/dist/feather-VFWLAILO.js.map +0 -1
- package/dist/heroicons-H3Z7DFCF.js.map +0 -1
- package/dist/lucide-MR32KM4G.js.map +0 -1
- package/dist/phosphor-ABQQL5N5.js.map +0 -1
- package/dist/tabler-ANUSY4D2.js.map +0 -1
package/dist/kanban.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { useFillHeight, FillContext, useKeyboardScroll, FOCUS_INSET } from './chunk-SFY2KMHG.js';
|
|
3
|
+
import { Badge } from './chunk-PO65I3MQ.js';
|
|
2
4
|
import { useFramesItself } from './chunk-QM4SJKWV.js';
|
|
3
5
|
import './chunk-ZI3OQDET.js';
|
|
4
|
-
import { Badge } from './chunk-EX64MN2U.js';
|
|
5
6
|
import { useTextOverflow, Tooltip } from './chunk-MD2EFMES.js';
|
|
6
7
|
import './chunk-7Q46JXSK.js';
|
|
7
|
-
import { Icon } from './chunk-
|
|
8
|
+
import { Icon } from './chunk-TJEV7YAY.js';
|
|
8
9
|
import './chunk-HP7WUZPK.js';
|
|
9
10
|
import './chunk-WH2FUFAC.js';
|
|
10
11
|
import { cn } from './chunk-M2QRNBDQ.js';
|
package/dist/kanban.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/components/KanbanBoard.tsx"],"names":[],"mappings":"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","file":"kanban.js","sourcesContent":["import { useCallback, useContext, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport {\n DndContext,\n closestCorners,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type Announcements,\n type DragCancelEvent,\n type DragEndEvent,\n type DragOverEvent,\n DragOverlay,\n type DragStartEvent,\n type KeyboardCoordinateGetter,\n useDroppable,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n arrayMove,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n useSortable,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\nimport { Tooltip } from \"./Tooltip\";\nimport { useTextOverflow } from \"../lib/use-text-overflow\";\nimport { Badge } from \"./Badge\";\nimport { useFramesItself } from \"../lib/surface-context\";\nimport { FillContext, useFillHeight } from \"../lib/use-fill-height\";\nimport { FOCUS_INSET, useKeyboardScroll } from \"../lib/use-keyboard-scroll\";\n\nexport interface KanbanCard {\n id: string;\n title: string;\n description?: string;\n tags?: string[];\n avatar?: string;\n}\n\nexport interface KanbanColumn {\n id: string;\n title: string;\n cards: KanbanCard[];\n color?: string;\n}\n\nexport interface KanbanBoardProps {\n /**\n * The board's cards by column. Authoritative: the board shows what it is given, with one exception — a card just\n * dropped stays where it was dropped until `columns` shows the move, the save fails, or `columns` changes some other\n * way (see onCardMove). A re-render that passes the same cards again, or an array rebuilt with the same cards,\n * never puts a dropped card back.\n */\n columns: KanbanColumn[];\n /**\n * The columns after a move, once on drop (Sprint 25.7, C2: it used to fire on every hover step). Its return value\n * counts as onCardMove's does.\n */\n onColumnsChange?: (columns: KanbanColumn[]) => unknown;\n /**\n * A card was dropped at a new place: its column and its index there, once on drop — a move between columns, into an\n * empty one, or a reorder within one. Save the move here (or in onColumnsChange); a board with neither saves nothing.\n * The index counts the cards the board shows: when `columns` is filtered, it is the place among the cards passed.\n *\n * Return the save's promise (an async function, or a mutation's mutateAsync) and the card stays where it was dropped\n * while it saves, and while an earlier move of the same card still saves, whatever `columns` arrive meanwhile; when\n * it rejects, the card goes back to where `columns` has it, a screen reader hears so, and the app says why (a toast\n * inside the app shell). The save must settle (give a request a timeout): one that never does holds the card. A\n * handler that throws refuses a move the same way (a column that is full). An app that updates `columns` at once,\n * then saves, puts the card back itself when its save fails; the board still says the move was not saved.\n */\n onCardMove?: (card: KanbanCard, toColumnId: string, index: number) => unknown;\n /** A board to look at, not rearrange: no dragging and no grab cursor; cards still open with onCardClick. */\n readOnly?: boolean;\n renderCard?: (card: KanbanCard) => ReactNode;\n /**\n * Opens a card (a detail drawer, a route). The board's own card surface is the control: click, or Enter with the\n * card focused, opens it; Space picks the card up for a keyboard drag. Never wire a clickable element inside\n * renderCard — a role=\"button\" div fights the drag listeners and the judge cites it (Sprint 25.4 K-1).\n */\n onCardClick?: (card: KanbanCard) => void;\n className?: string;\n}\n\nfunction SortableCard({\n card,\n renderCard,\n onCardClick,\n readOnly,\n}: {\n card: KanbanCard;\n renderCard?: (card: KanbanCard) => ReactNode;\n onCardClick?: (card: KanbanCard) => void;\n readOnly?: boolean;\n}) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: card.id, disabled: readOnly });\n\n if (readOnly) {\n // nothing to pick up: a card that opens is a button (Enter and Space), one that does not is a plain surface\n const open = onCardClick ? () => onCardClick(card) : undefined;\n return (\n <div\n ref={setNodeRef}\n {...(open ? { role: \"button\", tabIndex: 0 } : {})}\n onClick={open}\n onKeyDown={open ? (e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); open(); } } : undefined}\n data-kanban-card={card.id}\n className={cn(\n \"rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"bg-[var(--ds-bg-surface)] p-ds-3 shadow-[var(--ds-shadow-button)]\",\n open ? \"cursor-pointer\" : \"cursor-default\",\n \"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]\",\n )}\n >\n {renderCard ? renderCard(card) : <DefaultCard card={card} />}\n </div>\n );\n }\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n };\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n {...attributes}\n {...listeners}\n // the surface is the control (K-1): a click opens (the pointer sensor needs 5 px of movement to start a drag),\n // Enter opens, Space stays the keyboard drag's pick-up\n onClick={onCardClick ? () => onCardClick(card) : undefined}\n onKeyDown={(e) => {\n if (onCardClick && e.key === \"Enter\") { e.preventDefault(); onCardClick(card); return; }\n listeners?.onKeyDown?.(e);\n }}\n data-kanban-card={card.id}\n className={cn(\n \"rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"bg-[var(--ds-bg-surface)] p-ds-3 active:cursor-grabbing\",\n onCardClick ? \"cursor-pointer\" : \"cursor-grab\",\n \"shadow-[var(--ds-shadow-button)]\",\n \"transition-shadow duration-[var(--ds-transition-speed)]\",\n \"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]\",\n // no scale on the card left behind: the drag overlay takes its size from it, and 2% wider made the cards\n // below count as \"to the right\" of it, so a keyboard drag's arrow keys landed on them (Sprint 25.7, C2)\n isDragging && \"opacity-30\",\n )}\n >\n {renderCard ? (\n renderCard(card)\n ) : (\n <DefaultCard card={card} />\n )}\n </div>\n );\n}\n\nfunction ClampedDescription({ children }: { children: string }) {\n const { ref, isTruncated } = useTextOverflow({ lines: 2 });\n const el = <p ref={ref} className=\"text-xs text-[var(--ds-text-secondary)] line-clamp-2\">{children}</p>;\n if (!isTruncated) return el;\n return <Tooltip content={children}>{el}</Tooltip>;\n}\n\nfunction TruncTitle({ children }: { children: string }) {\n const { ref, isTruncated } = useTextOverflow({ lines: 1 });\n const el = <p ref={ref} className=\"text-sm font-medium text-[var(--ds-text-primary)] truncate\">{children}</p>;\n if (!isTruncated) return el;\n return <Tooltip content={children}>{el}</Tooltip>;\n}\n\nfunction DefaultCard({ card }: { card: KanbanCard }) {\n return (\n <div className=\"space-y-ds-2\">\n <TruncTitle>{card.title}</TruncTitle>\n {card.description && (\n <ClampedDescription>{card.description}</ClampedDescription>\n )}\n {card.tags && card.tags.length > 0 && (\n <div className=\"flex flex-wrap gap-ds-1\">\n {card.tags.map((tag) => (\n <Badge key={tag} variant=\"subtle\" size=\"sm\">{tag}</Badge>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction OverlayCard({\n card,\n renderCard,\n}: {\n card: KanbanCard;\n renderCard?: (card: KanbanCard) => ReactNode;\n}) {\n return (\n <div\n className={cn(\n \"rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"bg-[var(--ds-bg-surface)] p-ds-3 shadow-[var(--ds-shadow-card)]\",\n )}\n >\n {renderCard ? renderCard(card) : <DefaultCard card={card} />}\n </div>\n );\n}\n\n/** A column's drop area has its own id, so it never collides with a card id. */\nconst DROP_PREFIX = \"kanban-column:\";\nconst columnDropId = (id: string) => `${DROP_PREFIX}${id}`;\nconst droppedColumnId = (id: string) => (id.startsWith(DROP_PREFIX) ? id.slice(DROP_PREFIX.length) : null);\n\n/**\n * Sprint 25.7, C2: a keyboard drag goes column to column. Left and Right move the card to the top of the next column's\n * list — an empty column included — and Up and Down reorder within the column (dnd-kit's own handler). dnd-kit's\n * handler alone picks the nearest drop area to the right of the card's edge, which is often a card in the same column\n * or the card's own new place, so every other arrow key did nothing.\n */\nconst boardCoordinates: KeyboardCoordinateGetter = (event, args) => {\n if (event.code !== \"ArrowLeft\" && event.code !== \"ArrowRight\") return sortableKeyboardCoordinates(event, args);\n event.preventDefault();\n const { collisionRect, droppableRects, droppableContainers } = args.context;\n if (!collisionRect) return undefined;\n const columns = droppableContainers.getEnabled()\n .filter((c) => String(c.id).startsWith(DROP_PREFIX))\n .map((c) => droppableRects.get(c.id))\n .filter((r): r is NonNullable<typeof r> => r != null)\n .sort((a, b) => a.left - b.left);\n const centre = collisionRect.left + collisionRect.width / 2;\n const current = columns.findIndex((r) => centre >= r.left && centre <= r.left + r.width);\n const next = current < 0 ? undefined : columns[current + (event.code === \"ArrowRight\" ? 1 : -1)];\n if (!next) return undefined;\n return { x: next.left + (next.width - collisionRect.width) / 2, y: next.top };\n};\n\n/** Where a card is: its column's id and its index there. */\nfunction locate(cols: KanbanColumn[], cardId: string): { col: KanbanColumn; index: number } | null {\n for (const col of cols) {\n const index = col.cards.findIndex((c) => c.id === cardId);\n if (index >= 0) return { col, index };\n }\n return null;\n}\n\n/** The columns after a drop on `overId`: within the column the preview put the card in, a drop on another card reorders it. */\nfunction landing(cols: KanbanColumn[], cardId: string, overId: string): KanbanColumn[] {\n const at = locate(cols, cardId);\n const overAt = locate(cols, overId);\n if (!at || !overAt || overAt.col.id !== at.col.id || overAt.index === at.index) return cols;\n return cols.map((col) => (col.id === at.col.id ? { ...col, cards: arrayMove(col.cards, at.index, overAt.index) } : col));\n}\n\n/** A card's place, to re-apply to other columns: its column, the card after it (null when last) and its index. */\ninterface Placement {\n cardId: string;\n toColumnId: string;\n beforeId: string | null;\n index: number;\n}\n\nfunction placementIn(cols: KanbanColumn[], cardId: string): Placement | null {\n const at = locate(cols, cardId);\n return at ? { cardId, toColumnId: at.col.id, beforeId: at.col.cards[at.index + 1]?.id ?? null, index: at.index } : null;\n}\n\n/** The columns with a card put at a placement: into its column, before the same card (else at its index). */\nfunction place(cols: KanbanColumn[], p: Placement): KanbanColumn[] {\n const from = locate(cols, p.cardId);\n if (!from || !cols.some((col) => col.id === p.toColumnId)) return cols;\n const card = from.col.cards[from.index];\n return cols.map((col) => {\n if (col.id !== p.toColumnId && col.id !== from.col.id) return col;\n const cards = col.cards.filter((c) => c.id !== p.cardId);\n if (col.id === p.toColumnId) {\n const i = p.beforeId == null ? cards.length : cards.findIndex((c) => c.id === p.beforeId);\n cards.splice(i >= 0 ? i : Math.min(p.index, cards.length), 0, card);\n }\n return { ...col, cards };\n });\n}\n\n/**\n * A drag's move so far, re-applied to new columns: the card goes into the same column, before the same card, so a\n * change that arrives while a card is held shows at once and the drop keeps it.\n */\nfunction rebase(next: KanbanColumn[], shown: KanbanColumn[], cardId: string): KanbanColumn[] {\n const p = placementIn(shown, cardId);\n return p ? place(next, p) : next;\n}\n\n/**\n * A dropped card the board holds where it was dropped (Sprint 25.7, the owner's call of 26 September 2026: a card must\n * not jump back while its move saves). The pattern Atlassian's drag-and-drop guidance sets for Trello and Jira: the move\n * shows at once, before it is saved; data that arrives meanwhile has it replayed over it; a failed save lets the data\n * win, so the card goes back. One hold per card: a later move of the card replaces its place and adds its save to the\n * ones in flight.\n */\ninterface HeldMove extends Placement {\n /** The latest drop's key: only its save's failure puts the card back. */\n key: number;\n /** Saves for this card not yet settled, a replaced move's included: while one is out, nothing the columns show ends the hold. */\n inFlight: number;\n /** Where `columns` had the card before the first drop of this run of moves. */\n origin: Placement;\n /** The places of the moves this one replaced: columns showing one of them are behind, not a decision. */\n earlier: Placement[];\n /** The cards and their order in `columns` at the drop, or when its last save settled: with the card at its origin, a change ends the hold. */\n layout: string;\n}\n\n/** Which cards each column holds, in order: what a hold compares. A card's own fields changing is not a move. */\nconst layoutOf = (cols: KanbanColumn[]) => cols.map((col) => `${col.id}:${col.cards.map((c) => c.id).join(\",\")}`).join(\"|\");\n\n/** The columns show the card at a placement: in its column, before the same card (null: last). */\nfunction isAt(cols: KanbanColumn[], p: Placement): boolean {\n const at = locate(cols, p.cardId);\n return at != null && at.col.id === p.toColumnId && (at.col.cards[at.index + 1]?.id ?? null) === p.beforeId;\n}\n\n/**\n * The holds new columns keep. While a save for the card is out, every one (stale data, a card a filter hides, a card\n * that happens to sit where it was dropped). Once none is: a hold ends when its card or column is gone; with the card\n * at its origin, when the columns change some other way (the app's data has moved on — or, for a card moved back, has\n * caught up); when the columns show the card where it was dropped; or somewhere that is none of its own places (the\n * app's data decided). Columns showing one of its earlier places are behind, and the hold stays.\n */\nfunction keptHolds(holds: HeldMove[], cols: KanbanColumn[]): HeldMove[] {\n const layout = layoutOf(cols);\n const kept = holds.filter((h) => {\n if (h.inFlight > 0) return true;\n if (!locate(cols, h.cardId) || !cols.some((col) => col.id === h.toColumnId)) return false;\n // first, as a card moved back sits at its origin in data that has not caught up yet as well as in data that has\n if (isAt(cols, h.origin)) return layout === h.layout;\n if (isAt(cols, h)) return false;\n return h.earlier.some((p) => isAt(cols, p));\n });\n return kept.length === holds.length ? holds : kept;\n}\n\nconst replayHolds = (cols: KanbanColumn[], holds: HeldMove[]) => holds.reduce(place, cols);\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n value != null && typeof (value as { then?: unknown }).then === \"function\";\n\n/** A card's place, for the live region: \"To do, position 2 of 3\". */\nconst placeWords = (at: { col: KanbanColumn; index: number }) => `${at.col.title}, position ${at.index + 1} of ${at.col.cards.length}`;\n\n/** Read to a screen reader on every card that can be dragged (dnd-kit's aria-describedby). */\nconst MOVE_INSTRUCTIONS = \"Press Space to pick up the card. Use the Left and Right arrow keys to move it between columns, \"\n + \"and the Up and Down arrow keys to move it within a column. Press Space again to drop it, or Escape to cancel.\";\n\nfunction BoardColumn({\n col,\n readOnly,\n filled,\n children,\n}: {\n col: KanbanColumn;\n readOnly?: boolean;\n /** The board has a height of its own (the page's, or its pane's): the column takes it and scrolls its cards. */\n filled?: boolean;\n children: ReactNode;\n}) {\n // Sprint 25.7, C2: the column is a drop area as well as a sortable list, so an empty column takes a card\n const { setNodeRef, isOver } = useDroppable({ id: columnDropId(col.id), disabled: readOnly });\n // Sprint 25.16 A42: a column that scrolls its cards, with no card to Tab to (a read-only board), is a Tab stop itself\n const [cards, setCardsEl] = useState<HTMLDivElement | null>(null);\n const setCards = useCallback((node: HTMLDivElement | null) => { setNodeRef(node); setCardsEl(node); }, [setNodeRef]);\n useKeyboardScroll(cards, col.title, !!filled);\n return (\n <div\n className={cn(\n \"flex flex-col shrink-0 w-[calc(100vw-4rem)] sm:w-[280px] snap-center\",\n filled && \"min-h-0\",\n \"bg-[var(--ds-bg-muted)] rounded-[var(--ds-radius-lg)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n )}\n >\n <div className=\"flex items-center justify-between px-ds-3 py-ds-2.5\">\n <div className=\"flex items-center gap-ds-2\">\n {col.color && (\n <span\n className=\"w-2.5 h-2.5 rounded-[var(--ds-radius-full)] shrink-0\"\n style={{ backgroundColor: col.color }}\n />\n )}\n <span className=\"text-sm font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]\">\n {col.title}\n </span>\n <span className=\"text-xs text-[var(--ds-text-muted)] tabular-nums\">\n {col.cards.length}\n </span>\n </div>\n <Icon name=\"plus\" size={14} className=\"text-[var(--ds-text-muted)]\" />\n </div>\n\n <SortableContext\n items={col.cards.map((c) => c.id)}\n strategy={verticalListSortingStrategy}\n id={col.id}\n >\n <div\n ref={setCards}\n data-kanban-column={col.id}\n className={cn(\n \"flex flex-col gap-ds-2.5 px-ds-3 pb-ds-3 min-h-[60px] rounded-b-[var(--ds-radius-lg)] transition-colors\",\n // scrolling, it keeps room above the first card for its focus ring (drawn where the header's padding was) and\n // brings a card focused by keyboard in with room around it\n filled && cn(\"flex-1 min-h-0 overflow-y-auto -mt-ds-1 pt-ds-1 scroll-py-ds-2\", FOCUS_INSET),\n isOver && col.cards.length === 0 && \"bg-[var(--ds-bg-surface)]/60\",\n )}\n >\n {children}\n </div>\n </SortableContext>\n </div>\n );\n}\n\nexport function KanbanBoard({\n columns: columnsProp,\n onColumnsChange,\n onCardMove,\n readOnly,\n renderCard,\n onCardClick,\n className,\n}: KanbanBoardProps) {\n // Sprint 25.14 A44: a board frames itself, so a SplitView's list pane draws nothing behind it\n useFramesItself();\n // Sprint 25.7, C2: `columns` is authoritative — a new array replaces what the board shows. A move is previewed while\n // the card is dragged and held once dropped (HeldMove) until `columns` shows it; a cancelled drag (Escape) leaves the\n // board as it was.\n const [seenProp, setSeenProp] = useState(columnsProp);\n const [holds, setHoldsState] = useState<HeldMove[]>([]);\n // the preview lives in a ref as well, so a drop in the same tick as the last hover still reads it\n const [preview, setPreviewState] = useState<KanbanColumn[] | null>(null);\n const previewRef = useRef<KanbanColumn[] | null>(null);\n const setPreview = (next: KanbanColumn[] | null) => { previewRef.current = next; setPreviewState(next); };\n const [activeCard, setActiveCard] = useState<KanbanCard | null>(null);\n // the holds, the columns and the card being dragged, for a save that settles after this render\n const holdsRef = useRef<HeldMove[]>([]);\n const columnsRef = useRef(columnsProp);\n const activeRef = useRef<string | null>(null);\n const setHolds = (next: HeldMove[]) => { holdsRef.current = next; setHoldsState(next); };\n if (columnsProp !== seenProp) {\n setSeenProp(columnsProp);\n // new columns (a save landing, a refetch, another user's move): the holds they settle end, the rest replay over them\n const kept = keptHolds(holds, columnsProp);\n if (kept !== holds) setHoldsState(kept);\n // new columns while a card is held: the preview is rebuilt from them\n if (preview && activeCard) setPreviewState(rebase(replayHolds(columnsProp, kept), preview, activeCard.id));\n }\n // a preview or holds updated while rendering reach their refs before any drag event or settled save reads them\n useLayoutEffect(() => { previewRef.current = preview; }, [preview]);\n useLayoutEffect(() => { holdsRef.current = holds; }, [holds]);\n useLayoutEffect(() => { columnsRef.current = columnsProp; }, [columnsProp]);\n const committed = useMemo(() => replayHolds(columnsProp, holds), [columnsProp, holds]);\n const columns = preview ?? committed;\n\n // The live region speaks card and column titles, never ids. Each handler words its news in `said`, and dnd-kit\n // announces it straight after calling the handler. A move is said when the card's landing place changes.\n const said = useRef<string | undefined>(undefined);\n const lastPlace = useRef<string | null>(null);\n const announcements = useMemo<Announcements>(() => {\n const take = () => { const text = said.current; said.current = undefined; return text; };\n return { onDragStart: take, onDragOver: take, onDragEnd: take, onDragCancel: take };\n }, []);\n const instructions = { draggable: onCardClick ? `Press Enter to open the card. ${MOVE_INSTRUCTIONS}` : MOVE_INSTRUCTIONS };\n // A save that fails after the drag is over has no dnd-kit event to speak in: the board's own status line says it,\n // every failure since the last pick-up together, so two that land at once are both heard.\n const [notice, setNotice] = useState(\"\");\n const noticeParts = useRef<string[]>([]);\n const say = (text: string) => { noticeParts.current = [...noticeParts.current, text]; setNotice(noticeParts.current.join(\" \")); };\n // The card to focus once a failed save has put it back: its element is rendered anew in the column it returns to.\n const rootRef = useRef<HTMLDivElement>(null);\n // Sprint 25.16 A42 (P31): a board that is its page's last content takes the height under the header, and one in a\n // SplitView's pane takes the pane's; each column then scrolls its own cards, and the page or the pane doesn't\n const fill = useFillHeight(rootRef);\n const inPane = useContext(FillContext);\n const filled = fill != null || inPane;\n const refocus = useRef<string | null>(null);\n useLayoutEffect(() => {\n const id = refocus.current;\n if (id == null) return;\n refocus.current = null;\n const cards = rootRef.current?.querySelectorAll<HTMLElement>(\"[data-kanban-card]\") ?? [];\n [...cards].find((el) => el.getAttribute(\"data-kanban-card\") === id)?.focus();\n });\n const holdKey = useRef(0);\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n useSensor(KeyboardSensor, {\n coordinateGetter: boardCoordinates,\n // Space picks up and drops; Enter is the card's open key (onCardClick)\n keyboardCodes: { start: [\"Space\"], cancel: [\"Escape\"], end: [\"Space\"] },\n }),\n );\n // read-only: no sensors at all (an absent list would give dnd-kit's defaults)\n const noSensors = useSensors();\n\n const handleDragStart = (event: DragStartEvent) => {\n const at = locate(committed, String(event.active.id));\n if (!at) return;\n noticeParts.current = [];\n setNotice(\"\");\n activeRef.current = at.col.cards[at.index].id;\n setActiveCard(at.col.cards[at.index]);\n setPreview(committed);\n lastPlace.current = placeWords(at);\n said.current = `Picked up ${at.col.cards[at.index].title} in ${lastPlace.current}.`;\n };\n\n // Across columns, the preview moves the card as it is dragged; the parent hears nothing until the drop.\n const handleDragOver = (event: DragOverEvent) => {\n const { active, over } = event;\n const activeId = String(active.id);\n const overId = over ? String(over.id) : null;\n const cols = previewRef.current ?? committed;\n const from = locate(cols, activeId);\n const toColumnId = overId == null || overId === activeId ? null : droppedColumnId(overId) ?? locate(cols, overId)?.col.id;\n if (from && toColumnId && from.col.id !== toColumnId) {\n const card = from.col.cards[from.index];\n setPreview(cols.map((col) => {\n if (col.id === from.col.id) return { ...col, cards: col.cards.filter((c) => c.id !== activeId) };\n if (col.id !== toColumnId) return col;\n const overIndex = col.cards.findIndex((c) => c.id === overId);\n const cards = [...col.cards];\n cards.splice(overIndex >= 0 ? overIndex : cards.length, 0, card);\n return { ...col, cards };\n }));\n }\n // where a drop now would put the card\n const now = overId == null ? null : locate(landing(previewRef.current ?? committed, activeId, overId), activeId);\n const where = now ? placeWords(now) : null;\n if (where === lastPlace.current) return;\n lastPlace.current = where;\n const title = now ? now.col.cards[now.index].title : activeCard?.title;\n said.current = now ? `${title} is over ${where}.` : `${title} is not over a column.`;\n };\n\n /** A card's move failed: the hold ends and the card shows where `columns` has it, said on the status line. */\n const putBack = (hold: HeldMove) => {\n const rest = holdsRef.current.filter((h) => h.cardId !== hold.cardId);\n const shown = replayHolds(columnsRef.current, rest);\n const back = locate(shown, hold.cardId);\n const card = back?.col.cards[back.index];\n // focus follows the card only from this board (two boards over the same data each render it)\n const focused = document.activeElement;\n if (focused && rootRef.current?.contains(focused) && focused.closest?.(\"[data-kanban-card]\")?.getAttribute(\"data-kanban-card\") === hold.cardId) {\n refocus.current = hold.cardId;\n }\n setHolds(rest);\n // a card held mid-drag: the preview is rebuilt without the failed move, so the drop cannot carry it\n if (previewRef.current && activeRef.current) setPreview(rebase(shown, previewRef.current, activeRef.current));\n if (!back || !card) return;\n const to = columnsRef.current.find((col) => col.id === hold.toColumnId)?.title;\n say(isAt(columnsRef.current, hold.origin) || !to\n ? `Move not saved. ${card.title} is back in ${placeWords(back)}.`\n : `Move not saved. ${card.title} could not move to ${to}.`);\n };\n\n /** A save for a card has settled. The latest move's failure puts the card back; otherwise, once none is out, the hold is judged against the columns. */\n const settle = (cardId: string, key: number, ok: boolean) => {\n const hold = holdsRef.current.find((h) => h.cardId === cardId);\n if (!hold) return;\n if (!ok && hold.key === key) return putBack(hold);\n const inFlight = hold.inFlight - 1;\n const next = holdsRef.current.map((h) => (h === hold ? { ...h, inFlight, layout: inFlight > 0 ? h.layout : layoutOf(columnsRef.current) } : h));\n // the columns may already show the card elsewhere (a refetch that landed before the save resolved)\n setHolds(inFlight > 0 ? next : keptHolds(next, columnsRef.current));\n };\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n const activeId = String(active.id);\n const cols = previewRef.current ?? committed;\n activeRef.current = null;\n setActiveCard(null);\n setPreview(null);\n const final = over ? landing(cols, activeId, String(over.id)) : committed;\n const before = locate(committed, activeId);\n const after = locate(final, activeId);\n if (!before || !after || (before.col.id === after.col.id && before.index === after.index)) {\n if (before) said.current = `Dropped ${before.col.cards[before.index].title} back in ${placeWords(before)}.`;\n return;\n }\n said.current = `Dropped ${after.col.cards[after.index].title} in ${placeWords(after)}.`;\n const key = ++holdKey.current;\n // a new move of a card replaces its hold's place; the replaced move's save stays in flight\n const prev = holdsRef.current.find((h) => h.cardId === activeId);\n const hold: HeldMove = {\n ...placementIn(final, activeId)!,\n key,\n inFlight: prev?.inFlight ?? 0,\n origin: prev?.origin ?? placementIn(columnsProp, activeId) ?? placementIn(committed, activeId)!,\n earlier: prev ? [...prev.earlier, { cardId: prev.cardId, toColumnId: prev.toColumnId, beforeId: prev.beforeId, index: prev.index }] : [],\n layout: layoutOf(columnsProp),\n };\n setHolds([...holdsRef.current.filter((h) => h.cardId !== activeId), hold]);\n const saves: PromiseLike<unknown>[] = [];\n try {\n for (const result of [onColumnsChange?.(final), onCardMove?.(after.col.cards[after.index], after.col.id, after.index)]) {\n if (isThenable(result)) saves.push(result);\n }\n } catch (error) {\n // a handler that throws refuses the move, as a rejected save does; the error still reaches the console\n console.error(\"KanbanBoard: a move handler threw, so the move is refused.\", error);\n return putBack(hold);\n }\n if (!saves.length) return;\n setHolds(holdsRef.current.map((h) => (h.key === key ? { ...h, inFlight: h.inFlight + 1 } : h)));\n // every save settles before the move counts as saved; any failure refuses it\n Promise.allSettled(saves).then((results) => settle(activeId, key, results.every((r) => r.status === \"fulfilled\")));\n };\n\n const handleDragCancel = (event: DragCancelEvent) => {\n activeRef.current = null;\n setActiveCard(null);\n setPreview(null);\n const at = locate(committed, String(event.active.id));\n if (at) said.current = `Move cancelled. ${at.col.cards[at.index].title} is back in ${placeWords(at)}.`;\n };\n\n return (\n <DndContext\n sensors={readOnly ? noSensors : sensors}\n accessibility={{ announcements, screenReaderInstructions: instructions }}\n collisionDetection={closestCorners}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n >\n <div ref={rootRef} data-fill={fill != null ? \"\" : undefined} className={cn(\"relative flex gap-ds-4 overflow-x-auto pb-ds-2 snap-x snap-mandatory sm:snap-none\", inPane && \"h-full min-h-0\", className)} style={fill != null ? { height: fill } : undefined}>\n {columns.map((col) => (\n <BoardColumn key={col.id} col={col} readOnly={readOnly} filled={filled}>\n {col.cards.map((card) => (\n <SortableCard\n key={card.id}\n card={card}\n renderCard={renderCard}\n onCardClick={onCardClick}\n readOnly={readOnly}\n />\n ))}\n </BoardColumn>\n ))}\n {/* inside the board's root, so a board in a spaced stack stays one element */}\n <div role=\"status\" className=\"sr-only\">{notice}</div>\n </div>\n\n <DragOverlay>\n {activeCard && <OverlayCard card={activeCard} renderCard={renderCard} />}\n </DragOverlay>\n </DndContext>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/components/KanbanBoard.tsx"],"names":[],"mappings":"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","file":"kanban.js","sourcesContent":["import { useCallback, useContext, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport {\n DndContext,\n closestCorners,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type Announcements,\n type DragCancelEvent,\n type DragEndEvent,\n type DragOverEvent,\n DragOverlay,\n type DragStartEvent,\n type KeyboardCoordinateGetter,\n useDroppable,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n arrayMove,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n useSortable,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\nimport { Tooltip } from \"./Tooltip\";\nimport { useTextOverflow } from \"../lib/use-text-overflow\";\nimport { Badge } from \"./Badge\";\nimport { useFramesItself } from \"../lib/surface-context\";\nimport { FillContext, useFillHeight } from \"../lib/use-fill-height\";\nimport { FOCUS_INSET, useKeyboardScroll } from \"../lib/use-keyboard-scroll\";\n\nexport interface KanbanCard {\n id: string;\n title: string;\n description?: string;\n tags?: string[];\n avatar?: string;\n}\n\nexport interface KanbanColumn {\n id: string;\n title: string;\n cards: KanbanCard[];\n color?: string;\n}\n\nexport interface KanbanBoardProps {\n /**\n * The board's cards by column. Authoritative: the board shows what it is given, with one exception — a card just\n * dropped stays where it was dropped until `columns` shows the move, the save fails, or `columns` changes some other\n * way (see onCardMove). A re-render that passes the same cards again, or an array rebuilt with the same cards,\n * never puts a dropped card back.\n */\n columns: KanbanColumn[];\n /**\n * The columns after a move, once on drop (Sprint 25.7, C2: it used to fire on every hover step). Its return value\n * counts as onCardMove's does.\n */\n onColumnsChange?: (columns: KanbanColumn[]) => unknown;\n /**\n * A card was dropped at a new place: its column and its index there, once on drop — a move between columns, into an\n * empty one, or a reorder within one. Save the move here (or in onColumnsChange); a board with neither saves nothing.\n * The index counts the cards the board shows: when `columns` is filtered, it is the place among the cards passed.\n *\n * Return the save's promise (an async function, or a mutation's mutateAsync) and the card stays where it was dropped\n * while it saves, and while an earlier move of the same card still saves, whatever `columns` arrive meanwhile; when\n * it rejects, the card goes back to where `columns` has it, a screen reader hears so, and the app says why (a toast\n * inside the app shell). The save must settle (give a request a timeout): one that never does holds the card. A\n * handler that throws refuses a move the same way (a column that is full). An app that updates `columns` at once,\n * then saves, puts the card back itself when its save fails; the board still says the move was not saved.\n */\n onCardMove?: (card: KanbanCard, toColumnId: string, index: number) => unknown;\n /** A board to look at, not rearrange: no dragging and no grab cursor; cards still open with onCardClick. */\n readOnly?: boolean;\n renderCard?: (card: KanbanCard) => ReactNode;\n /**\n * Opens a card (a detail drawer, a route). The board's own card surface is the control: click, or Enter with the\n * card focused, opens it; Space picks the card up for a keyboard drag. Never wire a clickable element inside\n * renderCard — a role=\"button\" div fights the drag listeners and the judge cites it (Sprint 25.4 K-1).\n */\n onCardClick?: (card: KanbanCard) => void;\n className?: string;\n}\n\nfunction SortableCard({\n card,\n renderCard,\n onCardClick,\n readOnly,\n}: {\n card: KanbanCard;\n renderCard?: (card: KanbanCard) => ReactNode;\n onCardClick?: (card: KanbanCard) => void;\n readOnly?: boolean;\n}) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: card.id, disabled: readOnly });\n\n if (readOnly) {\n // nothing to pick up: a card that opens is a button (Enter and Space), one that does not is a plain surface\n const open = onCardClick ? () => onCardClick(card) : undefined;\n return (\n <div\n ref={setNodeRef}\n {...(open ? { role: \"button\", tabIndex: 0 } : {})}\n onClick={open}\n onKeyDown={open ? (e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); open(); } } : undefined}\n data-kanban-card={card.id}\n className={cn(\n \"rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"bg-[var(--ds-bg-surface)] p-ds-3 shadow-[var(--ds-shadow-button)]\",\n open ? \"cursor-pointer\" : \"cursor-default\",\n \"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]\",\n )}\n >\n {renderCard ? renderCard(card) : <DefaultCard card={card} />}\n </div>\n );\n }\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n };\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n {...attributes}\n {...listeners}\n // the surface is the control (K-1): a click opens (the pointer sensor needs 5 px of movement to start a drag),\n // Enter opens, Space stays the keyboard drag's pick-up\n onClick={onCardClick ? () => onCardClick(card) : undefined}\n onKeyDown={(e) => {\n if (onCardClick && e.key === \"Enter\") { e.preventDefault(); onCardClick(card); return; }\n listeners?.onKeyDown?.(e);\n }}\n data-kanban-card={card.id}\n className={cn(\n \"rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"bg-[var(--ds-bg-surface)] p-ds-3 active:cursor-grabbing\",\n onCardClick ? \"cursor-pointer\" : \"cursor-grab\",\n \"shadow-[var(--ds-shadow-button)]\",\n \"transition-shadow duration-[var(--ds-transition-speed)]\",\n \"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]\",\n // no scale on the card left behind: the drag overlay takes its size from it, and 2% wider made the cards\n // below count as \"to the right\" of it, so a keyboard drag's arrow keys landed on them (Sprint 25.7, C2)\n isDragging && \"opacity-30\",\n )}\n >\n {renderCard ? (\n renderCard(card)\n ) : (\n <DefaultCard card={card} />\n )}\n </div>\n );\n}\n\nfunction ClampedDescription({ children }: { children: string }) {\n const { ref, isTruncated } = useTextOverflow({ lines: 2 });\n const el = <p ref={ref} className=\"text-xs text-[var(--ds-text-secondary)] line-clamp-2\">{children}</p>;\n if (!isTruncated) return el;\n return <Tooltip content={children}>{el}</Tooltip>;\n}\n\nfunction TruncTitle({ children }: { children: string }) {\n const { ref, isTruncated } = useTextOverflow({ lines: 1 });\n const el = <p ref={ref} className=\"text-sm font-medium text-[var(--ds-text-primary)] truncate\">{children}</p>;\n if (!isTruncated) return el;\n return <Tooltip content={children}>{el}</Tooltip>;\n}\n\nfunction DefaultCard({ card }: { card: KanbanCard }) {\n return (\n <div className=\"space-y-ds-2\">\n <TruncTitle>{card.title}</TruncTitle>\n {card.description && (\n <ClampedDescription>{card.description}</ClampedDescription>\n )}\n {card.tags && card.tags.length > 0 && (\n <div className=\"flex flex-wrap gap-ds-1\">\n {card.tags.map((tag) => (\n <Badge key={tag} variant=\"subtle\" size=\"sm\">{tag}</Badge>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction OverlayCard({\n card,\n renderCard,\n}: {\n card: KanbanCard;\n renderCard?: (card: KanbanCard) => ReactNode;\n}) {\n return (\n <div\n className={cn(\n \"rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"bg-[var(--ds-bg-surface)] p-ds-3 shadow-[var(--ds-shadow-card)]\",\n )}\n >\n {renderCard ? renderCard(card) : <DefaultCard card={card} />}\n </div>\n );\n}\n\n/** A column's drop area has its own id, so it never collides with a card id. */\nconst DROP_PREFIX = \"kanban-column:\";\nconst columnDropId = (id: string) => `${DROP_PREFIX}${id}`;\nconst droppedColumnId = (id: string) => (id.startsWith(DROP_PREFIX) ? id.slice(DROP_PREFIX.length) : null);\n\n/**\n * Sprint 25.7, C2: a keyboard drag goes column to column. Left and Right move the card to the top of the next column's\n * list — an empty column included — and Up and Down reorder within the column (dnd-kit's own handler). dnd-kit's\n * handler alone picks the nearest drop area to the right of the card's edge, which is often a card in the same column\n * or the card's own new place, so every other arrow key did nothing.\n */\nconst boardCoordinates: KeyboardCoordinateGetter = (event, args) => {\n if (event.code !== \"ArrowLeft\" && event.code !== \"ArrowRight\") return sortableKeyboardCoordinates(event, args);\n event.preventDefault();\n const { collisionRect, droppableRects, droppableContainers } = args.context;\n if (!collisionRect) return undefined;\n const columns = droppableContainers.getEnabled()\n .filter((c) => String(c.id).startsWith(DROP_PREFIX))\n .map((c) => droppableRects.get(c.id))\n .filter((r): r is NonNullable<typeof r> => r != null)\n .sort((a, b) => a.left - b.left);\n const centre = collisionRect.left + collisionRect.width / 2;\n const current = columns.findIndex((r) => centre >= r.left && centre <= r.left + r.width);\n const next = current < 0 ? undefined : columns[current + (event.code === \"ArrowRight\" ? 1 : -1)];\n if (!next) return undefined;\n return { x: next.left + (next.width - collisionRect.width) / 2, y: next.top };\n};\n\n/** Where a card is: its column's id and its index there. */\nfunction locate(cols: KanbanColumn[], cardId: string): { col: KanbanColumn; index: number } | null {\n for (const col of cols) {\n const index = col.cards.findIndex((c) => c.id === cardId);\n if (index >= 0) return { col, index };\n }\n return null;\n}\n\n/** The columns after a drop on `overId`: within the column the preview put the card in, a drop on another card reorders it. */\nfunction landing(cols: KanbanColumn[], cardId: string, overId: string): KanbanColumn[] {\n const at = locate(cols, cardId);\n const overAt = locate(cols, overId);\n if (!at || !overAt || overAt.col.id !== at.col.id || overAt.index === at.index) return cols;\n return cols.map((col) => (col.id === at.col.id ? { ...col, cards: arrayMove(col.cards, at.index, overAt.index) } : col));\n}\n\n/** A card's place, to re-apply to other columns: its column, the card after it (null when last) and its index. */\ninterface Placement {\n cardId: string;\n toColumnId: string;\n beforeId: string | null;\n index: number;\n}\n\nfunction placementIn(cols: KanbanColumn[], cardId: string): Placement | null {\n const at = locate(cols, cardId);\n return at ? { cardId, toColumnId: at.col.id, beforeId: at.col.cards[at.index + 1]?.id ?? null, index: at.index } : null;\n}\n\n/** The columns with a card put at a placement: into its column, before the same card (else at its index). */\nfunction place(cols: KanbanColumn[], p: Placement): KanbanColumn[] {\n const from = locate(cols, p.cardId);\n if (!from || !cols.some((col) => col.id === p.toColumnId)) return cols;\n const card = from.col.cards[from.index];\n return cols.map((col) => {\n if (col.id !== p.toColumnId && col.id !== from.col.id) return col;\n const cards = col.cards.filter((c) => c.id !== p.cardId);\n if (col.id === p.toColumnId) {\n const i = p.beforeId == null ? cards.length : cards.findIndex((c) => c.id === p.beforeId);\n cards.splice(i >= 0 ? i : Math.min(p.index, cards.length), 0, card);\n }\n return { ...col, cards };\n });\n}\n\n/**\n * A drag's move so far, re-applied to new columns: the card goes into the same column, before the same card, so a\n * change that arrives while a card is held shows at once and the drop keeps it.\n */\nfunction rebase(next: KanbanColumn[], shown: KanbanColumn[], cardId: string): KanbanColumn[] {\n const p = placementIn(shown, cardId);\n return p ? place(next, p) : next;\n}\n\n/**\n * A dropped card the board holds where it was dropped (Sprint 25.7, the owner's call of 26 September 2026: a card must\n * not jump back while its move saves). The pattern Atlassian's drag-and-drop guidance sets for Trello and Jira: the move\n * shows at once, before it is saved; data that arrives meanwhile has it replayed over it; a failed save lets the data\n * win, so the card goes back. One hold per card: a later move of the card replaces its place and adds its save to the\n * ones in flight.\n */\ninterface HeldMove extends Placement {\n /** The latest drop's key: only its save's failure puts the card back. */\n key: number;\n /** Saves for this card not yet settled, a replaced move's included: while one is out, nothing the columns show ends the hold. */\n inFlight: number;\n /** Where `columns` had the card before the first drop of this run of moves. */\n origin: Placement;\n /** The places of the moves this one replaced: columns showing one of them are behind, not a decision. */\n earlier: Placement[];\n /** The cards and their order in `columns` at the drop, or when its last save settled: with the card at its origin, a change ends the hold. */\n layout: string;\n}\n\n/** Which cards each column holds, in order: what a hold compares. A card's own fields changing is not a move. */\nconst layoutOf = (cols: KanbanColumn[]) => cols.map((col) => `${col.id}:${col.cards.map((c) => c.id).join(\",\")}`).join(\"|\");\n\n/** The columns show the card at a placement: in its column, before the same card (null: last). */\nfunction isAt(cols: KanbanColumn[], p: Placement): boolean {\n const at = locate(cols, p.cardId);\n return at != null && at.col.id === p.toColumnId && (at.col.cards[at.index + 1]?.id ?? null) === p.beforeId;\n}\n\n/**\n * The holds new columns keep. While a save for the card is out, every one (stale data, a card a filter hides, a card\n * that happens to sit where it was dropped). Once none is: a hold ends when its card or column is gone; with the card\n * at its origin, when the columns change some other way (the app's data has moved on — or, for a card moved back, has\n * caught up); when the columns show the card where it was dropped; or somewhere that is none of its own places (the\n * app's data decided). Columns showing one of its earlier places are behind, and the hold stays.\n */\nfunction keptHolds(holds: HeldMove[], cols: KanbanColumn[]): HeldMove[] {\n const layout = layoutOf(cols);\n const kept = holds.filter((h) => {\n if (h.inFlight > 0) return true;\n if (!locate(cols, h.cardId) || !cols.some((col) => col.id === h.toColumnId)) return false;\n // first, as a card moved back sits at its origin in data that has not caught up yet as well as in data that has\n if (isAt(cols, h.origin)) return layout === h.layout;\n if (isAt(cols, h)) return false;\n return h.earlier.some((p) => isAt(cols, p));\n });\n return kept.length === holds.length ? holds : kept;\n}\n\nconst replayHolds = (cols: KanbanColumn[], holds: HeldMove[]) => holds.reduce(place, cols);\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n value != null && typeof (value as { then?: unknown }).then === \"function\";\n\n/** A card's place, for the live region: \"To do, position 2 of 3\". */\nconst placeWords = (at: { col: KanbanColumn; index: number }) => `${at.col.title}, position ${at.index + 1} of ${at.col.cards.length}`;\n\n/** Read to a screen reader on every card that can be dragged (dnd-kit's aria-describedby). */\nconst MOVE_INSTRUCTIONS = \"Press Space to pick up the card. Use the Left and Right arrow keys to move it between columns, \"\n + \"and the Up and Down arrow keys to move it within a column. Press Space again to drop it, or Escape to cancel.\";\n\nfunction BoardColumn({\n col,\n readOnly,\n filled,\n children,\n}: {\n col: KanbanColumn;\n readOnly?: boolean;\n /** The board has a height of its own (the page's, or its pane's): the column takes it and scrolls its cards. */\n filled?: boolean;\n children: ReactNode;\n}) {\n // Sprint 25.7, C2: the column is a drop area as well as a sortable list, so an empty column takes a card\n const { setNodeRef, isOver } = useDroppable({ id: columnDropId(col.id), disabled: readOnly });\n // Sprint 25.16 A42: a column that scrolls its cards, with no card to Tab to (a read-only board), is a Tab stop itself\n const [cards, setCardsEl] = useState<HTMLDivElement | null>(null);\n const setCards = useCallback((node: HTMLDivElement | null) => { setNodeRef(node); setCardsEl(node); }, [setNodeRef]);\n useKeyboardScroll(cards, col.title, !!filled);\n return (\n <div\n className={cn(\n \"flex flex-col shrink-0 w-[calc(100vw-4rem)] sm:w-[280px] snap-center\",\n filled && \"min-h-0\",\n \"bg-[var(--ds-bg-muted)] rounded-[var(--ds-radius-lg)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n )}\n >\n <div className=\"flex items-center justify-between px-ds-3 py-ds-2.5\">\n <div className=\"flex items-center gap-ds-2\">\n {col.color && (\n <span\n className=\"w-2.5 h-2.5 rounded-[var(--ds-radius-full)] shrink-0\"\n style={{ backgroundColor: col.color }}\n />\n )}\n <span className=\"text-sm font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]\">\n {col.title}\n </span>\n <span className=\"text-xs text-[var(--ds-text-muted)] tabular-nums\">\n {col.cards.length}\n </span>\n </div>\n <Icon name=\"plus\" size={14} className=\"text-[var(--ds-text-muted)]\" />\n </div>\n\n <SortableContext\n items={col.cards.map((c) => c.id)}\n strategy={verticalListSortingStrategy}\n id={col.id}\n >\n <div\n ref={setCards}\n data-kanban-column={col.id}\n className={cn(\n \"flex flex-col gap-ds-2.5 px-ds-3 pb-ds-3 min-h-[60px] rounded-b-[var(--ds-radius-lg)] transition-colors\",\n // scrolling, it keeps room above the first card for its focus ring (drawn where the header's padding was) and\n // brings a card focused by keyboard in with room around it\n filled && cn(\"flex-1 min-h-0 overflow-y-auto -mt-ds-1 pt-ds-1 scroll-py-ds-2\", FOCUS_INSET),\n isOver && col.cards.length === 0 && \"bg-[var(--ds-bg-surface)]/60\",\n )}\n >\n {children}\n </div>\n </SortableContext>\n </div>\n );\n}\n\nexport function KanbanBoard({\n columns: columnsProp,\n onColumnsChange,\n onCardMove,\n readOnly,\n renderCard,\n onCardClick,\n className,\n}: KanbanBoardProps) {\n // Sprint 25.14 A44: a board frames itself, so a SplitView's list pane draws nothing behind it\n useFramesItself();\n // Sprint 25.7, C2: `columns` is authoritative — a new array replaces what the board shows. A move is previewed while\n // the card is dragged and held once dropped (HeldMove) until `columns` shows it; a cancelled drag (Escape) leaves the\n // board as it was.\n const [seenProp, setSeenProp] = useState(columnsProp);\n const [holds, setHoldsState] = useState<HeldMove[]>([]);\n // the preview lives in a ref as well, so a drop in the same tick as the last hover still reads it\n const [preview, setPreviewState] = useState<KanbanColumn[] | null>(null);\n const previewRef = useRef<KanbanColumn[] | null>(null);\n const setPreview = (next: KanbanColumn[] | null) => { previewRef.current = next; setPreviewState(next); };\n const [activeCard, setActiveCard] = useState<KanbanCard | null>(null);\n // the holds, the columns and the card being dragged, for a save that settles after this render\n const holdsRef = useRef<HeldMove[]>([]);\n const columnsRef = useRef(columnsProp);\n const activeRef = useRef<string | null>(null);\n const setHolds = (next: HeldMove[]) => { holdsRef.current = next; setHoldsState(next); };\n if (columnsProp !== seenProp) {\n setSeenProp(columnsProp);\n // new columns (a save landing, a refetch, another user's move): the holds they settle end, the rest replay over them\n const kept = keptHolds(holds, columnsProp);\n if (kept !== holds) setHoldsState(kept);\n // new columns while a card is held: the preview is rebuilt from them\n if (preview && activeCard) setPreviewState(rebase(replayHolds(columnsProp, kept), preview, activeCard.id));\n }\n // a preview or holds updated while rendering reach their refs before any drag event or settled save reads them\n useLayoutEffect(() => { previewRef.current = preview; }, [preview]);\n useLayoutEffect(() => { holdsRef.current = holds; }, [holds]);\n useLayoutEffect(() => { columnsRef.current = columnsProp; }, [columnsProp]);\n const committed = useMemo(() => replayHolds(columnsProp, holds), [columnsProp, holds]);\n const columns = preview ?? committed;\n\n // The live region speaks card and column titles, never ids. Each handler words its news in `said`, and dnd-kit\n // announces it straight after calling the handler. A move is said when the card's landing place changes.\n const said = useRef<string | undefined>(undefined);\n const lastPlace = useRef<string | null>(null);\n const announcements = useMemo<Announcements>(() => {\n const take = () => { const text = said.current; said.current = undefined; return text; };\n return { onDragStart: take, onDragOver: take, onDragEnd: take, onDragCancel: take };\n }, []);\n const instructions = { draggable: onCardClick ? `Press Enter to open the card. ${MOVE_INSTRUCTIONS}` : MOVE_INSTRUCTIONS };\n // A save that fails after the drag is over has no dnd-kit event to speak in: the board's own status line says it,\n // every failure since the last pick-up together, so two that land at once are both heard.\n const [notice, setNotice] = useState(\"\");\n const noticeParts = useRef<string[]>([]);\n const say = (text: string) => { noticeParts.current = [...noticeParts.current, text]; setNotice(noticeParts.current.join(\" \")); };\n // The card to focus once a failed save has put it back: its element is rendered anew in the column it returns to.\n const rootRef = useRef<HTMLDivElement>(null);\n // Sprint 25.16 A42 (P31): a board that is its page's last content takes the height under the header, and one in a\n // SplitView's pane takes the pane's; each column then scrolls its own cards, and the page or the pane doesn't\n const fill = useFillHeight(rootRef);\n const inPane = useContext(FillContext);\n const filled = fill != null || inPane;\n const refocus = useRef<string | null>(null);\n useLayoutEffect(() => {\n const id = refocus.current;\n if (id == null) return;\n refocus.current = null;\n const cards = rootRef.current?.querySelectorAll<HTMLElement>(\"[data-kanban-card]\") ?? [];\n [...cards].find((el) => el.getAttribute(\"data-kanban-card\") === id)?.focus();\n });\n const holdKey = useRef(0);\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n useSensor(KeyboardSensor, {\n coordinateGetter: boardCoordinates,\n // Space picks up and drops; Enter is the card's open key (onCardClick)\n keyboardCodes: { start: [\"Space\"], cancel: [\"Escape\"], end: [\"Space\"] },\n }),\n );\n // read-only: no sensors at all (an absent list would give dnd-kit's defaults)\n const noSensors = useSensors();\n\n const handleDragStart = (event: DragStartEvent) => {\n const at = locate(committed, String(event.active.id));\n if (!at) return;\n noticeParts.current = [];\n setNotice(\"\");\n activeRef.current = at.col.cards[at.index].id;\n setActiveCard(at.col.cards[at.index]);\n setPreview(committed);\n lastPlace.current = placeWords(at);\n said.current = `Picked up ${at.col.cards[at.index].title} in ${lastPlace.current}.`;\n };\n\n // Across columns, the preview moves the card as it is dragged; the parent hears nothing until the drop.\n const handleDragOver = (event: DragOverEvent) => {\n const { active, over } = event;\n const activeId = String(active.id);\n const overId = over ? String(over.id) : null;\n const cols = previewRef.current ?? committed;\n const from = locate(cols, activeId);\n const toColumnId = overId == null || overId === activeId ? null : droppedColumnId(overId) ?? locate(cols, overId)?.col.id;\n if (from && toColumnId && from.col.id !== toColumnId) {\n const card = from.col.cards[from.index];\n setPreview(cols.map((col) => {\n if (col.id === from.col.id) return { ...col, cards: col.cards.filter((c) => c.id !== activeId) };\n if (col.id !== toColumnId) return col;\n const overIndex = col.cards.findIndex((c) => c.id === overId);\n const cards = [...col.cards];\n cards.splice(overIndex >= 0 ? overIndex : cards.length, 0, card);\n return { ...col, cards };\n }));\n }\n // where a drop now would put the card\n const now = overId == null ? null : locate(landing(previewRef.current ?? committed, activeId, overId), activeId);\n const where = now ? placeWords(now) : null;\n if (where === lastPlace.current) return;\n lastPlace.current = where;\n const title = now ? now.col.cards[now.index].title : activeCard?.title;\n said.current = now ? `${title} is over ${where}.` : `${title} is not over a column.`;\n };\n\n /** A card's move failed: the hold ends and the card shows where `columns` has it, said on the status line. */\n const putBack = (hold: HeldMove) => {\n const rest = holdsRef.current.filter((h) => h.cardId !== hold.cardId);\n const shown = replayHolds(columnsRef.current, rest);\n const back = locate(shown, hold.cardId);\n const card = back?.col.cards[back.index];\n // focus follows the card only from this board (two boards over the same data each render it)\n const focused = document.activeElement;\n if (focused && rootRef.current?.contains(focused) && focused.closest?.(\"[data-kanban-card]\")?.getAttribute(\"data-kanban-card\") === hold.cardId) {\n refocus.current = hold.cardId;\n }\n setHolds(rest);\n // a card held mid-drag: the preview is rebuilt without the failed move, so the drop cannot carry it\n if (previewRef.current && activeRef.current) setPreview(rebase(shown, previewRef.current, activeRef.current));\n if (!back || !card) return;\n const to = columnsRef.current.find((col) => col.id === hold.toColumnId)?.title;\n say(isAt(columnsRef.current, hold.origin) || !to\n ? `Move not saved. ${card.title} is back in ${placeWords(back)}.`\n : `Move not saved. ${card.title} could not move to ${to}.`);\n };\n\n /** A save for a card has settled. The latest move's failure puts the card back; otherwise, once none is out, the hold is judged against the columns. */\n const settle = (cardId: string, key: number, ok: boolean) => {\n const hold = holdsRef.current.find((h) => h.cardId === cardId);\n if (!hold) return;\n if (!ok && hold.key === key) return putBack(hold);\n const inFlight = hold.inFlight - 1;\n const next = holdsRef.current.map((h) => (h === hold ? { ...h, inFlight, layout: inFlight > 0 ? h.layout : layoutOf(columnsRef.current) } : h));\n // the columns may already show the card elsewhere (a refetch that landed before the save resolved)\n setHolds(inFlight > 0 ? next : keptHolds(next, columnsRef.current));\n };\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n const activeId = String(active.id);\n const cols = previewRef.current ?? committed;\n activeRef.current = null;\n setActiveCard(null);\n setPreview(null);\n const final = over ? landing(cols, activeId, String(over.id)) : committed;\n const before = locate(committed, activeId);\n const after = locate(final, activeId);\n if (!before || !after || (before.col.id === after.col.id && before.index === after.index)) {\n if (before) said.current = `Dropped ${before.col.cards[before.index].title} back in ${placeWords(before)}.`;\n return;\n }\n said.current = `Dropped ${after.col.cards[after.index].title} in ${placeWords(after)}.`;\n const key = ++holdKey.current;\n // a new move of a card replaces its hold's place; the replaced move's save stays in flight\n const prev = holdsRef.current.find((h) => h.cardId === activeId);\n const hold: HeldMove = {\n ...placementIn(final, activeId)!,\n key,\n inFlight: prev?.inFlight ?? 0,\n origin: prev?.origin ?? placementIn(columnsProp, activeId) ?? placementIn(committed, activeId)!,\n earlier: prev ? [...prev.earlier, { cardId: prev.cardId, toColumnId: prev.toColumnId, beforeId: prev.beforeId, index: prev.index }] : [],\n layout: layoutOf(columnsProp),\n };\n setHolds([...holdsRef.current.filter((h) => h.cardId !== activeId), hold]);\n const saves: PromiseLike<unknown>[] = [];\n try {\n for (const result of [onColumnsChange?.(final), onCardMove?.(after.col.cards[after.index], after.col.id, after.index)]) {\n if (isThenable(result)) saves.push(result);\n }\n } catch (error) {\n // a handler that throws refuses the move, as a rejected save does; the error still reaches the console\n console.error(\"KanbanBoard: a move handler threw, so the move is refused.\", error);\n return putBack(hold);\n }\n if (!saves.length) return;\n setHolds(holdsRef.current.map((h) => (h.key === key ? { ...h, inFlight: h.inFlight + 1 } : h)));\n // every save settles before the move counts as saved; any failure refuses it\n Promise.allSettled(saves).then((results) => settle(activeId, key, results.every((r) => r.status === \"fulfilled\")));\n };\n\n const handleDragCancel = (event: DragCancelEvent) => {\n activeRef.current = null;\n setActiveCard(null);\n setPreview(null);\n const at = locate(committed, String(event.active.id));\n if (at) said.current = `Move cancelled. ${at.col.cards[at.index].title} is back in ${placeWords(at)}.`;\n };\n\n return (\n <DndContext\n sensors={readOnly ? noSensors : sensors}\n accessibility={{ announcements, screenReaderInstructions: instructions }}\n collisionDetection={closestCorners}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n >\n <div ref={rootRef} data-fill={fill != null ? \"\" : undefined} className={cn(\"relative flex gap-ds-4 overflow-x-auto pb-ds-2 snap-x snap-mandatory sm:snap-none\", inPane && \"h-full min-h-0\", className)} style={fill != null ? { height: fill } : undefined}>\n {columns.map((col) => (\n <BoardColumn key={col.id} col={col} readOnly={readOnly} filled={filled}>\n {col.cards.map((card) => (\n <SortableCard\n key={card.id}\n card={card}\n renderCard={renderCard}\n onCardClick={onCardClick}\n readOnly={readOnly}\n />\n ))}\n </BoardColumn>\n ))}\n {/* inside the board's root, so a board in a spaced stack stays one element */}\n <div role=\"status\" className=\"sr-only\">{notice}</div>\n </div>\n\n <DragOverlay>\n {activeCard && <OverlayCard card={activeCard} renderCard={renderCard} />}\n </DragOverlay>\n </DndContext>\n );\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { pickCurated, buildExtendedMap } from './chunk-NRHIYS5W.js';
|
|
2
3
|
|
|
3
4
|
// ../../showcase/src/lib/icon-packs/lucide.ts
|
|
@@ -68,19 +69,19 @@ var CURATED = {
|
|
|
68
69
|
"lock": "Lock",
|
|
69
70
|
"map-pin": "MapPin"
|
|
70
71
|
};
|
|
71
|
-
async function peer() {
|
|
72
|
-
return await
|
|
72
|
+
async function peer(load) {
|
|
73
|
+
return await load();
|
|
73
74
|
}
|
|
74
|
-
async function loadCurated() {
|
|
75
|
-
return pickCurated(await peer(), CURATED);
|
|
75
|
+
async function loadCurated(load) {
|
|
76
|
+
return pickCurated(await peer(load), CURATED);
|
|
76
77
|
}
|
|
77
|
-
async function loadExtended() {
|
|
78
|
-
const mod = await peer();
|
|
78
|
+
async function loadExtended(load) {
|
|
79
|
+
const mod = await peer(load);
|
|
79
80
|
const extended = buildExtendedMap(mod, {});
|
|
80
81
|
Object.assign(extended, pickCurated(mod, CURATED));
|
|
81
82
|
return extended;
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
export { loadCurated, loadExtended };
|
|
85
|
-
//# sourceMappingURL=lucide-
|
|
86
|
-
//# sourceMappingURL=lucide-
|
|
86
|
+
//# sourceMappingURL=lucide-ZWE3EPGP.js.map
|
|
87
|
+
//# sourceMappingURL=lucide-ZWE3EPGP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/icon-packs/lucide.ts"],"names":[],"mappings":"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","file":"lucide-ZWE3EPGP.js","sourcesContent":["import type { IconMap, PackLoad } from './types'\nimport { buildExtendedMap, pickCurated } from './utils'\n\n/**\n * Lucide icons.\n *\n * The library's own pack: every app installs it, as the fallback, so icons.tsx\n * hands this file its import itself (the other packs come through the import\n * the app registers, Sprint 25.21 P1). Never a static named import: a static\n * import of an optional peer makes a consumer's production build fail on Vite 8\n * when the peer is not installed (Sprint 22 bench finding 1, 13 Sep 2026;\n * showcase/src/test/vite8-optional-peers-build.test.ts guards it). The curated\n * names are strings for the same reason; icon-completeness.test.tsx proves\n * every one resolves in the installed pack. If the import fails, loadPack in\n * icons.tsx reports which package to install.\n */\nconst CURATED: Record<string, string> = {\n \"home\": \"Home\",\n \"folder\": \"FolderKanban\",\n \"chart\": \"BarChart3\",\n \"settings\": \"Settings\",\n \"chevron-right\": \"ChevronRight\",\n \"close\": \"X\",\n \"plus\": \"Plus\",\n \"search\": \"Search\",\n \"bell\": \"Bell\",\n \"user\": \"User\",\n \"check\": \"Check\",\n \"warning\": \"AlertTriangle\",\n \"info\": \"Info\",\n \"error\": \"AlertCircle\",\n \"clock\": \"Clock\",\n \"calendar\": \"CalendarDays\",\n \"bold\": \"Bold\",\n \"italic\": \"Italic\",\n \"underline\": \"Underline\",\n \"strikethrough\": \"Strikethrough\",\n \"align-left\": \"AlignLeft\",\n \"align-center\": \"AlignCenter\",\n \"align-right\": \"AlignRight\",\n \"list\": \"List\",\n \"list-ordered\": \"ListOrdered\",\n \"list-checks\": \"ListChecks\",\n \"link\": \"Link\",\n \"image\": \"Image\",\n \"table\": \"Table\",\n \"code\": \"Code\",\n \"quote\": \"Quote\",\n \"minus\": \"Minus\",\n \"superscript\": \"Superscript\",\n \"subscript\": \"Subscript\",\n \"highlight\": \"Highlighter\",\n \"type\": \"Type\",\n \"chevron-up\": \"ChevronUp\",\n \"chevron-down\": \"ChevronDown\",\n \"chevron-left\": \"ChevronLeft\",\n \"trash\": \"Trash2\",\n \"undo\": \"Undo2\",\n \"redo\": \"Redo2\",\n \"arrow-left\": \"ArrowLeft\",\n \"grip-vertical\": \"GripVertical\",\n \"mic\": \"Mic\",\n \"paperclip\": \"Paperclip\",\n \"send\": \"Send\",\n \"log-out\": \"LogOut\",\n \"edit\": \"Pencil\",\n \"menu\": \"Menu\",\n \"more-horizontal\": \"MoreHorizontal\",\n \"star\": \"Star\",\n \"bookmark\": \"Bookmark\",\n \"download\": \"Download\",\n \"upload\": \"Upload\",\n \"sparkles\": \"Sparkles\",\n \"file\": \"File\",\n \"file-text\": \"FileText\",\n \"eye\": \"Eye\",\n \"eye-off\": \"EyeOff\",\n \"copy\": \"Copy\",\n \"external-link\": \"ExternalLink\",\n \"filter\": \"Funnel\",\n \"lock\": \"Lock\",\n \"map-pin\": \"MapPin\",\n}\n\n/** The pack's module, through the import handed to it (Sprint 25.21 P1). */\nasync function peer(load: PackLoad): Promise<Record<string, unknown>> {\n return (await load()) as Record<string, unknown>\n}\n\nexport async function loadCurated(load: PackLoad): Promise<IconMap> {\n return pickCurated(await peer(load), CURATED)\n}\n\nexport async function loadExtended(load: PackLoad): Promise<IconMap> {\n const mod = await peer(load)\n const extended = buildExtendedMap(mod, {})\n Object.assign(extended, pickCurated(mod, CURATED))\n return extended\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { pickCurated, buildExtendedMap } from './chunk-NRHIYS5W.js';
|
|
2
3
|
|
|
3
4
|
// ../../showcase/src/lib/icon-packs/phosphor.ts
|
|
@@ -68,19 +69,19 @@ var CURATED = {
|
|
|
68
69
|
"lock": "Lock",
|
|
69
70
|
"map-pin": "MapPin"
|
|
70
71
|
};
|
|
71
|
-
async function peer() {
|
|
72
|
-
return await
|
|
72
|
+
async function peer(load) {
|
|
73
|
+
return await load();
|
|
73
74
|
}
|
|
74
|
-
async function loadCurated() {
|
|
75
|
-
return pickCurated(await peer(), CURATED);
|
|
75
|
+
async function loadCurated(load) {
|
|
76
|
+
return pickCurated(await peer(load), CURATED);
|
|
76
77
|
}
|
|
77
|
-
async function loadExtended() {
|
|
78
|
-
const mod = await peer();
|
|
78
|
+
async function loadExtended(load) {
|
|
79
|
+
const mod = await peer(load);
|
|
79
80
|
const extended = buildExtendedMap(mod, {});
|
|
80
81
|
Object.assign(extended, pickCurated(mod, CURATED));
|
|
81
82
|
return extended;
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
export { loadCurated, loadExtended };
|
|
85
|
-
//# sourceMappingURL=phosphor-
|
|
86
|
-
//# sourceMappingURL=phosphor-
|
|
86
|
+
//# sourceMappingURL=phosphor-DIHPA4AJ.js.map
|
|
87
|
+
//# sourceMappingURL=phosphor-DIHPA4AJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/icon-packs/phosphor.ts"],"names":[],"mappings":"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","file":"phosphor-DIHPA4AJ.js","sourcesContent":["import type { IconMap, PackLoad } from './types'\nimport { buildExtendedMap, pickCurated } from './utils'\n\n/**\n * Phosphor icons.\n *\n * The pack is reached only through the import the app registers for it\n * (registerIconPack, Sprint 25.21 P1): no file the library publishes names the\n * package, so a bundler never looks for a pack the app didn't install\n * (Next.js's webpack resolved every such import, and failed the build). Never a\n * static named import either: a static import of an optional peer makes a\n * consumer's production build fail on Vite 8 when the peer is not installed\n * (Sprint 22 bench finding 1, 13 Sep 2026; showcase/src/test/\n * vite8-optional-peers-build.test.ts guards it). The curated names are strings\n * for the same reason; icon-completeness.test.tsx proves every one resolves in\n * the installed pack. If the import fails, loadPack in icons.tsx reports which\n * package to install.\n */\nconst CURATED: Record<string, string> = {\n \"home\": \"House\",\n \"folder\": \"FolderSimple\",\n \"chart\": \"ChartBar\",\n \"settings\": \"Gear\",\n \"chevron-right\": \"CaretRight\",\n \"close\": \"X\",\n \"plus\": \"Plus\",\n \"search\": \"MagnifyingGlass\",\n \"bell\": \"Bell\",\n \"user\": \"User\",\n \"check\": \"Check\",\n \"warning\": \"Warning\",\n \"info\": \"Info\",\n \"error\": \"WarningCircle\",\n \"clock\": \"Clock\",\n \"calendar\": \"CalendarBlank\",\n \"bold\": \"TextB\",\n \"italic\": \"TextItalic\",\n \"underline\": \"TextUnderline\",\n \"strikethrough\": \"TextStrikethrough\",\n \"align-left\": \"TextAlignLeft\",\n \"align-center\": \"TextAlignCenter\",\n \"align-right\": \"TextAlignRight\",\n \"list\": \"ListBullets\",\n \"list-ordered\": \"ListNumbers\",\n \"list-checks\": \"ListChecks\",\n \"link\": \"Link\",\n \"image\": \"Image\",\n \"table\": \"Table\",\n \"code\": \"Code\",\n \"quote\": \"Quotes\",\n \"minus\": \"Minus\",\n \"superscript\": \"TextSuperscript\",\n \"subscript\": \"TextSubscript\",\n \"highlight\": \"Highlighter\",\n \"type\": \"TextT\",\n \"chevron-up\": \"CaretUp\",\n \"chevron-down\": \"CaretDown\",\n \"chevron-left\": \"CaretLeft\",\n \"trash\": \"Trash\",\n \"undo\": \"ArrowCounterClockwise\",\n \"redo\": \"ArrowClockwise\",\n \"arrow-left\": \"ArrowLeft\",\n \"grip-vertical\": \"DotsSixVertical\",\n \"mic\": \"Microphone\",\n \"paperclip\": \"Paperclip\",\n \"send\": \"PaperPlaneTilt\",\n \"log-out\": \"SignOut\",\n \"edit\": \"PencilSimple\",\n \"menu\": \"List\",\n \"more-horizontal\": \"DotsThree\",\n \"star\": \"Star\",\n \"bookmark\": \"BookmarkSimple\",\n \"download\": \"DownloadSimple\",\n \"upload\": \"UploadSimple\",\n \"sparkles\": \"Sparkle\",\n \"file\": \"File\",\n \"file-text\": \"FileText\",\n \"eye\": \"Eye\",\n \"eye-off\": \"EyeSlash\",\n \"copy\": \"Copy\",\n \"external-link\": \"ArrowSquareOut\",\n \"filter\": \"Funnel\",\n \"lock\": \"Lock\",\n \"map-pin\": \"MapPin\",\n}\n\n/** The pack's module, through the import handed to it (Sprint 25.21 P1). */\nasync function peer(load: PackLoad): Promise<Record<string, unknown>> {\n return (await load()) as Record<string, unknown>\n}\n\nexport async function loadCurated(load: PackLoad): Promise<IconMap> {\n return pickCurated(await peer(load), CURATED)\n}\n\nexport async function loadExtended(load: PackLoad): Promise<IconMap> {\n const mod = await peer(load)\n const extended = buildExtendedMap(mod, {})\n Object.assign(extended, pickCurated(mod, CURATED))\n return extended\n}\n"]}
|
package/dist/resizable.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCompact, useElementWidth, useBelow, crumbGoes, useAppShell, Breadcrumbs, Drawer } from './chunk-R5NFCEZ3.js';
|
|
3
|
+
import { useFillHeight, useKeyboardScroll, FillContext, FOCUS_INSET } from './chunk-SFY2KMHG.js';
|
|
4
|
+
import { Button } from './chunk-EKBWWA6P.js';
|
|
5
|
+
import './chunk-OYNUU346.js';
|
|
3
6
|
import { useBreakpoint } from './chunk-CRQ6KCRD.js';
|
|
4
7
|
import './chunk-XVB55M3N.js';
|
|
5
|
-
import { useFillHeight, useKeyboardScroll, FillContext, FOCUS_INSET } from './chunk-SFY2KMHG.js';
|
|
6
8
|
import { SurfaceBoundary } from './chunk-QM4SJKWV.js';
|
|
7
9
|
import { isTabStop, tabStops, rememberFocus } from './chunk-ZI3OQDET.js';
|
|
8
10
|
import './chunk-MD2EFMES.js';
|
|
9
11
|
import './chunk-7Q46JXSK.js';
|
|
10
|
-
import { Icon } from './chunk-
|
|
12
|
+
import { Icon } from './chunk-TJEV7YAY.js';
|
|
11
13
|
import './chunk-HP7WUZPK.js';
|
|
12
14
|
import './chunk-WH2FUFAC.js';
|
|
13
15
|
import { cn } from './chunk-M2QRNBDQ.js';
|
|
@@ -253,7 +255,7 @@ function SplitView({
|
|
|
253
255
|
return /* @__PURE__ */ jsx(FillContext, { value: true, children: /* @__PURE__ */ jsxs("div", { ref: rootRef, "data-split-view": showDetail2 ? "detail" : "list", "data-frame": frame, "data-fill": pageFill != null ? "" : void 0, ...region, className: cn(surface, "flex flex-col"), style: fillStyle, children: [
|
|
254
256
|
showDetail2 && /* @__PURE__ */ jsxs("div", { className: cn("flex-1 min-h-0 flex flex-col", itemSurface), children: [
|
|
255
257
|
/* @__PURE__ */ jsxs("div", { className: cn("shrink-0 flex items-center justify-between gap-ds-2 py-ds-2 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]", path ? "px-[var(--ds-page-gutter)]" : "px-ds-3"), children: [
|
|
256
|
-
path ? /* @__PURE__ */ jsx(Breadcrumbs, { items: path, maxItems: 3, "aria-label": "Path", className: "min-w-0" }) : /* @__PURE__ */ jsx(Button, { type: "button", variant: "
|
|
258
|
+
path ? /* @__PURE__ */ jsx(Breadcrumbs, { items: path, maxItems: 3, "aria-label": "Path", className: "min-w-0" }) : /* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "arrow-left", size: 14 }), onClick: onDetailClose, children: backLabel }),
|
|
257
259
|
phoneAside && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "info", size: 14 }), onClick: () => setAsideWantsOpen(true), "aria-expanded": asideWantsOpen, children: asideTitle })
|
|
258
260
|
] }),
|
|
259
261
|
/* @__PURE__ */ jsx("div", { ref: setStackedDetailScroll, className: cn("flex-1 min-h-0 overflow-y-auto", FOCUS_INSET), children: detailContent })
|