@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 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;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
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.1.15",
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
- "@draftline/client": "0.1.14"
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"