@draftline/react 0.1.15 → 0.2.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/README.md +11 -0
- package/dist/index.d.ts +46 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +123 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -19,9 +19,12 @@ npm install @draftline/client @draftline/react
|
|
|
19
19
|
import { createDraftlineClient } from '@draftline/client';
|
|
20
20
|
import {
|
|
21
21
|
DraftlineHistoryGraph,
|
|
22
|
+
DraftlineWorkspaceGraph,
|
|
22
23
|
DraftlineProvider,
|
|
23
24
|
createDraftlineHistoryGraph,
|
|
25
|
+
createDraftlineWorkspaceGraphModel,
|
|
24
26
|
} from '@draftline/react';
|
|
27
|
+
import '@xyflow/react/dist/style.css';
|
|
25
28
|
|
|
26
29
|
const client = createDraftlineClient();
|
|
27
30
|
|
|
@@ -40,12 +43,20 @@ export function App() {
|
|
|
40
43
|
}
|
|
41
44
|
```
|
|
42
45
|
|
|
46
|
+
For Git/DAG history, pass Draftline's `WorkspaceGraph` DTO directly into
|
|
47
|
+
`createDraftlineWorkspaceGraphModel`. Use `view: 'first-parent'` for a compact
|
|
48
|
+
main-line milestone view and `view: 'expanded'` to show every saved side commit
|
|
49
|
+
and merge parent. Hosts can supply `renderNode` to use product-specific labels,
|
|
50
|
+
badges, and theme tokens while Draftline keeps the graph semantics.
|
|
51
|
+
|
|
43
52
|
## Design notes
|
|
44
53
|
|
|
45
54
|
- `DraftlineGraphNode` is an exported discriminated union for version, dirty, and
|
|
46
55
|
remote-tip nodes.
|
|
47
56
|
- `DraftlineHistoryGraph` is non-interactive unless the host supplies
|
|
48
57
|
`onSelectNode`.
|
|
58
|
+
- `DraftlineWorkspaceGraph` consumes `WorkspaceGraph`, supports first-parent and
|
|
59
|
+
expanded views, and uses React Flow + Dagre for rendering/layout only.
|
|
49
60
|
- Selection callbacks receive full context: `{ node, graph, selectable,
|
|
50
61
|
nativeEvent }`.
|
|
51
62
|
- Host apps own labels, editor reloads, dirty-navigation prompts, and remote UX.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type ChangedFile, type DraftlineClient, type JsonValue, type SupportRef, type SupportRefScope, type Variation, type Version, type WorkspaceDiagnostics } from '@draftline/client';
|
|
1
|
+
import { type ChangedFile, type DraftlineClient, type JsonValue, type SupportRef, type SupportRefScope, type Variation, type Version, type WorkspaceGraph, type WorkspaceGraphNode, type WorkspaceDiagnostics } from '@draftline/client';
|
|
2
|
+
import { type Edge as ReactFlowEdge, type Node as ReactFlowNode } from '@xyflow/react';
|
|
2
3
|
import { type CSSProperties, type KeyboardEvent as ReactKeyboardEvent, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react';
|
|
3
4
|
export type CommandResult = {
|
|
4
5
|
name: string;
|
|
@@ -99,6 +100,48 @@ export interface DraftlineHistoryGraphProps {
|
|
|
99
100
|
renderNode?: (node: DraftlineGraphNode, context: DraftlineGraphNodeContext) => ReactNode;
|
|
100
101
|
style?: CSSProperties;
|
|
101
102
|
}
|
|
103
|
+
export type DraftlineWorkspaceGraphView = 'expanded' | 'first-parent';
|
|
104
|
+
export type DraftlineWorkspaceGraphDirection = 'TB' | 'BT' | 'LR' | 'RL';
|
|
105
|
+
export interface DraftlineWorkspaceGraphModelOptions {
|
|
106
|
+
direction?: DraftlineWorkspaceGraphDirection;
|
|
107
|
+
nodeHeight?: number;
|
|
108
|
+
nodeWidth?: number;
|
|
109
|
+
rootVersionId?: string | null;
|
|
110
|
+
view?: DraftlineWorkspaceGraphView;
|
|
111
|
+
}
|
|
112
|
+
export interface DraftlineWorkspaceGraphNodeData {
|
|
113
|
+
[key: string]: unknown;
|
|
114
|
+
graphNode: WorkspaceGraphNode;
|
|
115
|
+
hiddenParentCount: number;
|
|
116
|
+
isFirstParentProjection: boolean;
|
|
117
|
+
label: string;
|
|
118
|
+
refs: string[];
|
|
119
|
+
}
|
|
120
|
+
export interface DraftlineWorkspaceGraphEdgeData {
|
|
121
|
+
[key: string]: unknown;
|
|
122
|
+
isFirstParent: boolean;
|
|
123
|
+
parentIndex: number;
|
|
124
|
+
}
|
|
125
|
+
export type DraftlineWorkspaceGraphNode = ReactFlowNode<DraftlineWorkspaceGraphNodeData, 'draftlineCommit'>;
|
|
126
|
+
export type DraftlineWorkspaceGraphEdge = ReactFlowEdge<DraftlineWorkspaceGraphEdgeData>;
|
|
127
|
+
export interface DraftlineWorkspaceGraphModel {
|
|
128
|
+
edges: DraftlineWorkspaceGraphEdge[];
|
|
129
|
+
graph: WorkspaceGraph;
|
|
130
|
+
hiddenNodeCount: number;
|
|
131
|
+
nodes: DraftlineWorkspaceGraphNode[];
|
|
132
|
+
view: DraftlineWorkspaceGraphView;
|
|
133
|
+
}
|
|
134
|
+
export interface DraftlineWorkspaceGraphRenderContext {
|
|
135
|
+
model: DraftlineWorkspaceGraphModel;
|
|
136
|
+
}
|
|
137
|
+
export interface DraftlineWorkspaceGraphProps {
|
|
138
|
+
className?: string;
|
|
139
|
+
fitView?: boolean;
|
|
140
|
+
model: DraftlineWorkspaceGraphModel;
|
|
141
|
+
onSelectNode?: (node: DraftlineWorkspaceGraphNode, context: DraftlineWorkspaceGraphRenderContext) => Promise<void> | void;
|
|
142
|
+
renderNode?: (node: DraftlineWorkspaceGraphNode, context: DraftlineWorkspaceGraphRenderContext) => ReactNode;
|
|
143
|
+
style?: CSSProperties;
|
|
144
|
+
}
|
|
102
145
|
export interface VariationOptionRenderState {
|
|
103
146
|
isActive: boolean;
|
|
104
147
|
label: string;
|
|
@@ -197,8 +240,10 @@ export declare function ChangedFilesList({ files }: {
|
|
|
197
240
|
export declare function VariationList(): import("react").JSX.Element;
|
|
198
241
|
export declare function VersionLane(): import("react").JSX.Element;
|
|
199
242
|
export declare function createDraftlineHistoryGraph({ activeVariationId, dirtyFiles, dirtyMode, includeRemoteTips, laneOrder, orientation, remoteTips, variations, versions, }: DraftlineHistoryGraphInput): DraftlineHistoryGraphModel;
|
|
243
|
+
export declare function createDraftlineWorkspaceGraphModel(graph: WorkspaceGraph, { direction, nodeHeight, nodeWidth, rootVersionId, view, }?: DraftlineWorkspaceGraphModelOptions): DraftlineWorkspaceGraphModel;
|
|
200
244
|
export declare function createDraftlineVariationListModel({ activeVariationId, getLabel, variations, }: DraftlineVariationListInput): DraftlineVariationListModel;
|
|
201
245
|
export declare function DraftlineHistoryGraph({ ariaLabel, className, getNodeKey, graph, onSelectNode, orientation, renderBadge, renderNode, style, }: DraftlineHistoryGraphProps): import("react").JSX.Element;
|
|
246
|
+
export declare function DraftlineWorkspaceGraph({ className, fitView, model, onSelectNode, renderNode, style, }: DraftlineWorkspaceGraphProps): import("react").JSX.Element;
|
|
202
247
|
export declare function DraftlineVariationSelect({ activeVariationId, className, getLabel, onSwitch, renderOption, style, variations, }: DraftlineVariationSelectProps): import("react").JSX.Element;
|
|
203
248
|
export declare function RawInspectorPanel(): import("react").JSX.Element;
|
|
204
249
|
export declare function ContentPolicyDiagnosticsPanel(): import("react").JSX.Element;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,SAAS,EAEd,KAAK,OAAO,EACZ,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createDraftlineClient, } from '@draftline/client';
|
|
3
|
+
import dagre from '@dagrejs/dagre';
|
|
4
|
+
import { Background, Controls, MarkerType, Position, ReactFlow, } from '@xyflow/react';
|
|
3
5
|
import { createContext, useCallback, useContext, useEffect, useMemo, useState, } from 'react';
|
|
4
6
|
const DraftlineContext = createContext(null);
|
|
5
7
|
function normalizeWorkspacePath(path) {
|
|
@@ -396,6 +398,88 @@ export function createDraftlineHistoryGraph({ activeVariationId, dirtyFiles = []
|
|
|
396
398
|
orientation,
|
|
397
399
|
};
|
|
398
400
|
}
|
|
401
|
+
export function createDraftlineWorkspaceGraphModel(graph, { direction = 'TB', nodeHeight = 72, nodeWidth = 220, rootVersionId, view = 'expanded', } = {}) {
|
|
402
|
+
const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
403
|
+
const nodesByVersion = new Map(graph.nodes.map((node) => [node.version.id, node]));
|
|
404
|
+
const rootNode = (rootVersionId ? nodesByVersion.get(rootVersionId) : undefined) ??
|
|
405
|
+
(graph.current_version ? nodesByVersion.get(graph.current_version) : undefined) ??
|
|
406
|
+
graph.nodes.find((node) => node.is_current) ??
|
|
407
|
+
graph.nodes.find((node) => node.is_head) ??
|
|
408
|
+
graph.nodes[0];
|
|
409
|
+
const visibleIds = view === 'first-parent' && rootNode
|
|
410
|
+
? collectFirstParentChain(rootNode, nodesById)
|
|
411
|
+
: new Set(graph.nodes.map((node) => node.id));
|
|
412
|
+
const refsByTarget = new Map();
|
|
413
|
+
for (const ref of graph.refs) {
|
|
414
|
+
refsByTarget.set(ref.target, [...(refsByTarget.get(ref.target) ?? []), ref.display_label]);
|
|
415
|
+
}
|
|
416
|
+
const layoutGraph = new dagre.graphlib.Graph();
|
|
417
|
+
layoutGraph.setDefaultEdgeLabel(() => ({}));
|
|
418
|
+
layoutGraph.setGraph({
|
|
419
|
+
marginx: 24,
|
|
420
|
+
marginy: 24,
|
|
421
|
+
nodesep: 44,
|
|
422
|
+
rankdir: direction,
|
|
423
|
+
ranksep: 72,
|
|
424
|
+
});
|
|
425
|
+
const visibleGraphNodes = graph.nodes
|
|
426
|
+
.filter((node) => visibleIds.has(node.id))
|
|
427
|
+
.sort((left, right) => left.topo_index - right.topo_index);
|
|
428
|
+
for (const node of visibleGraphNodes) {
|
|
429
|
+
layoutGraph.setNode(node.id, { height: nodeHeight, width: nodeWidth });
|
|
430
|
+
}
|
|
431
|
+
const edges = [];
|
|
432
|
+
for (const node of visibleGraphNodes) {
|
|
433
|
+
node.parent_ids.forEach((parentId, parentIndex) => {
|
|
434
|
+
if (!visibleIds.has(parentId)) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (view === 'first-parent' && parentIndex > 0) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const edge = {
|
|
441
|
+
id: `${parentId}->${node.id}:${parentIndex}`,
|
|
442
|
+
data: { isFirstParent: parentIndex === 0, parentIndex },
|
|
443
|
+
markerEnd: { type: MarkerType.ArrowClosed },
|
|
444
|
+
source: parentId,
|
|
445
|
+
style: parentIndex === 0 ? undefined : { strokeDasharray: '6 4' },
|
|
446
|
+
target: node.id,
|
|
447
|
+
type: 'smoothstep',
|
|
448
|
+
};
|
|
449
|
+
edges.push(edge);
|
|
450
|
+
layoutGraph.setEdge(parentId, node.id);
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
dagre.layout(layoutGraph);
|
|
454
|
+
const nodes = visibleGraphNodes.map((node) => {
|
|
455
|
+
const layout = layoutGraph.node(node.id);
|
|
456
|
+
const hiddenParentCount = node.parent_ids.filter((parentId) => !visibleIds.has(parentId)).length;
|
|
457
|
+
return {
|
|
458
|
+
data: {
|
|
459
|
+
graphNode: node,
|
|
460
|
+
hiddenParentCount,
|
|
461
|
+
isFirstParentProjection: view === 'first-parent',
|
|
462
|
+
label: node.layout.display_label || node.version.label || node.version.id.slice(0, 7),
|
|
463
|
+
refs: refsByTarget.get(node.id) ?? [],
|
|
464
|
+
},
|
|
465
|
+
id: node.id,
|
|
466
|
+
position: {
|
|
467
|
+
x: (layout?.x ?? node.layout.lane * (nodeWidth + 44)) - nodeWidth / 2,
|
|
468
|
+
y: (layout?.y ?? node.layout.row * (nodeHeight + 72)) - nodeHeight / 2,
|
|
469
|
+
},
|
|
470
|
+
sourcePosition: direction === 'LR' ? Position.Right : Position.Bottom,
|
|
471
|
+
targetPosition: direction === 'LR' ? Position.Left : Position.Top,
|
|
472
|
+
type: 'draftlineCommit',
|
|
473
|
+
};
|
|
474
|
+
});
|
|
475
|
+
return {
|
|
476
|
+
edges,
|
|
477
|
+
graph,
|
|
478
|
+
hiddenNodeCount: graph.nodes.length - nodes.length,
|
|
479
|
+
nodes,
|
|
480
|
+
view,
|
|
481
|
+
};
|
|
482
|
+
}
|
|
399
483
|
export function createDraftlineVariationListModel({ activeVariationId, getLabel = defaultVariationLabel, variations, }) {
|
|
400
484
|
return {
|
|
401
485
|
activeVariationId,
|
|
@@ -410,6 +494,13 @@ export function createDraftlineVariationListModel({ activeVariationId, getLabel
|
|
|
410
494
|
export function DraftlineHistoryGraph({ ariaLabel = 'Draftline history graph', className, getNodeKey = (node) => node.id, graph, onSelectNode, orientation = graph.orientation, renderBadge, renderNode, style, }) {
|
|
411
495
|
return (_jsx("ol", { "aria-label": ariaLabel, className: ['version-lane', className].filter(Boolean).join(' '), "data-orientation": orientation, "data-testid": "draftline-history-graph", id: "draftline-history-graph", style: style, children: [...graph.nodes].sort(compareGraphNodes).map((node) => (_jsx(DraftlineHistoryGraphRow, { getNodeKey: getNodeKey, graph: graph, node: node, onSelectNode: onSelectNode, renderBadge: renderBadge, renderNode: renderNode }, getNodeKey(node)))) }));
|
|
412
496
|
}
|
|
497
|
+
export function DraftlineWorkspaceGraph({ className, fitView = true, model, onSelectNode, renderNode, style, }) {
|
|
498
|
+
const context = useMemo(() => ({ model }), [model]);
|
|
499
|
+
const nodeTypes = useMemo(() => ({
|
|
500
|
+
draftlineCommit: (props) => (_jsx(DraftlineWorkspaceGraphNodeView, { context: context, node: props, onSelectNode: onSelectNode, renderNode: renderNode })),
|
|
501
|
+
}), [context, onSelectNode, renderNode]);
|
|
502
|
+
return (_jsx("div", { className: ['draftline-workspace-graph', className].filter(Boolean).join(' '), "data-view": model.view, style: style, children: _jsxs(ReactFlow, { edges: model.edges, fitView: fitView, nodes: model.nodes, nodeTypes: nodeTypes, nodesDraggable: false, nodesFocusable: Boolean(onSelectNode), proOptions: { hideAttribution: true }, children: [_jsx(Background, {}), _jsx(Controls, { showInteractive: false })] }) }));
|
|
503
|
+
}
|
|
413
504
|
function DraftlineHistoryGraphRow({ getNodeKey, graph, node, onSelectNode, renderBadge, renderNode, }) {
|
|
414
505
|
const selectable = Boolean(onSelectNode);
|
|
415
506
|
const context = { graph, selectable };
|
|
@@ -437,6 +528,24 @@ function DraftlineHistoryGraphRow({ getNodeKey, graph, node, onSelectNode, rende
|
|
|
437
528
|
? 'graph-node head-node'
|
|
438
529
|
: 'graph-node' }) }), onSelectNode ? (_jsx("button", { "aria-current": node.isActiveHead ? 'step' : undefined, className: "graph-node-button", onClick: (event) => notifyNodeSelected(event), onKeyDown: handleKeyDown, type: "button", children: renderNode ? renderNode(node, context) : _jsx(DefaultGraphNode, { node: node }) })) : (_jsx("div", { className: "graph-node-content", children: renderNode ? renderNode(node, context) : _jsx(DefaultGraphNode, { node: node }) })), _jsxs("span", { className: "badge-row", children: [renderBadge?.(node, context), node.isActiveHead ? _jsx(StatusPill, { tone: "ok", children: "HEAD" }) : null, node.kind === 'remoteTip' ? _jsx(StatusPill, { tone: "neutral", children: node.remote }) : null] })] }, getNodeKey(node)));
|
|
439
530
|
}
|
|
531
|
+
function DraftlineWorkspaceGraphNodeView({ context, node, onSelectNode, renderNode, }) {
|
|
532
|
+
const graphNode = context.model.nodes.find((candidate) => candidate.id === node.id);
|
|
533
|
+
if (!graphNode) {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
const content = renderNode ? (renderNode(graphNode, context)) : (_jsx(DefaultWorkspaceGraphNode, { node: graphNode }));
|
|
537
|
+
const onClick = () => {
|
|
538
|
+
const result = onSelectNode?.(graphNode, context);
|
|
539
|
+
if (result) {
|
|
540
|
+
void Promise.resolve(result).catch((error) => {
|
|
541
|
+
setTimeout(() => {
|
|
542
|
+
throw error;
|
|
543
|
+
}, 0);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
return onSelectNode ? (_jsx("button", { className: "workspace-graph-node", onClick: onClick, type: "button", children: content })) : (_jsx("div", { className: "workspace-graph-node", children: content }));
|
|
548
|
+
}
|
|
440
549
|
export function DraftlineVariationSelect({ activeVariationId, className, getLabel = defaultVariationLabel, onSwitch, renderOption, style, variations, }) {
|
|
441
550
|
const model = createDraftlineVariationListModel({ activeVariationId, getLabel, variations });
|
|
442
551
|
return (_jsx("ul", { className: ['item-list', className].filter(Boolean).join(' '), "data-testid": "draftline-variation-select", id: "draftline-variation-select", style: style, children: model.items.map(({ isActive, label, variation }) => {
|
|
@@ -488,6 +597,16 @@ function useDraftlineMutation(name, command) {
|
|
|
488
597
|
function RailItem({ label, tone, value, }) {
|
|
489
598
|
return (_jsxs("div", { className: "rail-item", children: [_jsx("span", { children: label }), _jsx(StatusPill, { tone: tone, children: value })] }));
|
|
490
599
|
}
|
|
600
|
+
function collectFirstParentChain(rootNode, nodesById) {
|
|
601
|
+
const keep = new Set();
|
|
602
|
+
let current = rootNode;
|
|
603
|
+
while (current && !keep.has(current.id)) {
|
|
604
|
+
keep.add(current.id);
|
|
605
|
+
const firstParentId = current.parent_ids[0];
|
|
606
|
+
current = firstParentId ? nodesById.get(firstParentId) : undefined;
|
|
607
|
+
}
|
|
608
|
+
return keep;
|
|
609
|
+
}
|
|
491
610
|
function DefaultGraphNode({ node }) {
|
|
492
611
|
if (node.kind === 'dirty') {
|
|
493
612
|
return (_jsxs("span", { children: [_jsx("strong", { children: "Unsaved changes" }), _jsxs("small", { children: [node.changedCount ?? 0, " tracked file(s) need save, shelf, or discard."] })] }));
|
|
@@ -497,6 +616,10 @@ function DefaultGraphNode({ node }) {
|
|
|
497
616
|
}
|
|
498
617
|
return (_jsxs("span", { children: [_jsx("strong", { children: node.label }), _jsxs("small", { children: [node.version?.author.name ?? 'Unknown', " -", ' ', node.version ? new Date(node.version.time_seconds * 1000).toLocaleString() : 'unsaved'] })] }));
|
|
499
618
|
}
|
|
619
|
+
function DefaultWorkspaceGraphNode({ node }) {
|
|
620
|
+
const graphNode = node.data.graphNode;
|
|
621
|
+
return (_jsxs("div", { className: "workspace-graph-node-card", "data-merge": graphNode.is_merge || undefined, children: [_jsx("strong", { children: node.data.label }), _jsx("small", { children: graphNode.version.id.slice(0, 7) }), node.data.refs.length > 0 ? (_jsx("span", { className: "workspace-graph-node-refs", children: node.data.refs.join(', ') })) : null, node.data.hiddenParentCount > 0 ? (_jsxs("span", { className: "workspace-graph-node-hidden", children: ["+", node.data.hiddenParentCount, " collapsed parent", node.data.hiddenParentCount === 1 ? '' : 's'] })) : null] }));
|
|
622
|
+
}
|
|
500
623
|
function defaultVariationLabel(variation) {
|
|
501
624
|
return variation.metadata.label ?? variation.name;
|
|
502
625
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@draftline/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "React hooks and primitives for Draftline-enabled Tauri applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,9 @@
|
|
|
30
30
|
"test": "vitest run --environment jsdom"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@
|
|
33
|
+
"@dagrejs/dagre": "^3.1.1",
|
|
34
|
+
"@draftline/client": "0.2.0",
|
|
35
|
+
"@xyflow/react": "^12.12.0"
|
|
34
36
|
},
|
|
35
37
|
"peerDependencies": {
|
|
36
38
|
"react": "^19.0.0"
|