@ceebee/ui 1.6.0 → 1.8.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/THIRD_PARTY_NOTICES.md +8 -0
- package/dist/client.d.ts +92 -1
- package/dist/client.js +315 -4
- package/dist/index.js +2 -2
- package/dist/skins/moodboard.css +21 -0
- package/dist/styles.css +729 -3
- package/package.json +2 -1
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -20,6 +20,14 @@ Copyright © 2015-present Ant UED
|
|
|
20
20
|
Icon components come from `@ant-design/icons` 6.x, a peer dependency. It is licensed under the MIT
|
|
21
21
|
License.
|
|
22
22
|
|
|
23
|
+
## React Flow (@xyflow/react)
|
|
24
|
+
|
|
25
|
+
Copyright © 2019-present webkid GmbH
|
|
26
|
+
|
|
27
|
+
`Diagram` and `DiagramEditor` in `@ceebee/ui/client` are built on the `@xyflow/react` 12.11.6 runtime,
|
|
28
|
+
a dependency. Its base stylesheet is included in `styles.css`, and its appearance is set by Ceebee's
|
|
29
|
+
Tokens. React Flow is licensed under the MIT License, and its copyright notice is retained here.
|
|
30
|
+
|
|
23
31
|
## dayjs
|
|
24
32
|
|
|
25
33
|
Copyright © 2018-present iamkun
|
package/dist/client.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { default as enUSDatePickerLocale } from 'antd/lib/date-picker/locale/en_
|
|
|
11
11
|
export { default as idIDLocale } from 'antd/locale/id_ID.js';
|
|
12
12
|
export { default as zhCNLocale } from 'antd/locale/zh_CN.js';
|
|
13
13
|
import * as _base_ui_react from '@base-ui/react';
|
|
14
|
+
import { ReactFlowProps } from '@xyflow/react';
|
|
14
15
|
|
|
15
16
|
interface ModalProps extends ModalProps$1 {
|
|
16
17
|
/** Separate explanatory copy announced after the dialog title. */
|
|
@@ -376,4 +377,94 @@ declare const PanZoomCanvas: typeof PanZoomCanvasRoot & {
|
|
|
376
377
|
Skeleton: typeof PanZoomCanvasSkeleton;
|
|
377
378
|
};
|
|
378
379
|
|
|
379
|
-
|
|
380
|
+
interface DiagramSkeletonProps {
|
|
381
|
+
label?: string;
|
|
382
|
+
}
|
|
383
|
+
declare function DiagramSkeleton({ label }: DiagramSkeletonProps): react.JSX.Element;
|
|
384
|
+
|
|
385
|
+
interface DiagramPosition {
|
|
386
|
+
x: number;
|
|
387
|
+
y: number;
|
|
388
|
+
}
|
|
389
|
+
type DiagramShape = 'rect' | 'pill' | 'diamond';
|
|
390
|
+
interface DiagramNode {
|
|
391
|
+
id: string;
|
|
392
|
+
label: string;
|
|
393
|
+
/** Grid cells from the diagram's origin. The caller owns and stores positions. */
|
|
394
|
+
position: DiagramPosition;
|
|
395
|
+
shape?: DiagramShape;
|
|
396
|
+
tone?: Tone;
|
|
397
|
+
/** Static supplementary content under the label. It must not be interactive. */
|
|
398
|
+
content?: ReactNode;
|
|
399
|
+
}
|
|
400
|
+
interface DiagramEdge {
|
|
401
|
+
id: string;
|
|
402
|
+
from: string;
|
|
403
|
+
to: string;
|
|
404
|
+
label?: string;
|
|
405
|
+
tone?: Tone;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
interface DiagramProps {
|
|
409
|
+
/** Accessible name for the diagram viewport. */
|
|
410
|
+
label: string;
|
|
411
|
+
nodes: readonly DiagramNode[];
|
|
412
|
+
edges: readonly DiagramEdge[];
|
|
413
|
+
hint?: string;
|
|
414
|
+
/** Accessible name for the list a screen reader walks instead of the drawing. */
|
|
415
|
+
outlineLabel?: string;
|
|
416
|
+
/** Localised names for the substrate's own controls and descriptions. */
|
|
417
|
+
ariaLabels?: ReactFlowProps['ariaLabelConfig'];
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* A read-only drawing of nodes joined by arrows, on the React Flow runtime. Pan and zoom are the
|
|
421
|
+
* viewport's; nothing in the drawing is focusable, draggable or selectable. The diagram is also given as an
|
|
422
|
+
* outline list, which the viewport is described by.
|
|
423
|
+
*/
|
|
424
|
+
declare function DiagramRoot({ label, nodes, edges, hint, outlineLabel, ariaLabels }: DiagramProps): react.JSX.Element;
|
|
425
|
+
declare const Diagram: typeof DiagramRoot & {
|
|
426
|
+
Skeleton: typeof DiagramSkeleton;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
interface DiagramRemoval {
|
|
430
|
+
nodeIds: string[];
|
|
431
|
+
edgeIds: string[];
|
|
432
|
+
}
|
|
433
|
+
interface DiagramRenameTarget {
|
|
434
|
+
kind: 'node' | 'edge';
|
|
435
|
+
id: string;
|
|
436
|
+
}
|
|
437
|
+
interface DiagramEditorProps {
|
|
438
|
+
label: string;
|
|
439
|
+
nodes: readonly DiagramNode[];
|
|
440
|
+
edges: readonly DiagramEdge[];
|
|
441
|
+
hint?: string;
|
|
442
|
+
selectedId?: string | null;
|
|
443
|
+
onSelectionChange?: (id: string) => void;
|
|
444
|
+
/** A request, in whole cells: the caller moves the node by updating `nodes`, or does not. */
|
|
445
|
+
onMoveNode?: (id: string, position: DiagramPosition) => void;
|
|
446
|
+
onConnect?: (from: string, to: string) => void;
|
|
447
|
+
/** A request: removing a node names the edges touching it too. Nothing is removed until `nodes`/`edges` change. */
|
|
448
|
+
onRemove?: (removal: DiagramRemoval) => void;
|
|
449
|
+
/** The caller renders the rename input; the editor only says what is to be renamed. */
|
|
450
|
+
onRename?: (target: DiagramRenameTarget) => void;
|
|
451
|
+
connectingStatus?: (nodeLabel: string) => string;
|
|
452
|
+
outlineLabel?: string;
|
|
453
|
+
/** Localised names for the substrate's own controls and keyboard descriptions. */
|
|
454
|
+
ariaLabels?: ReactFlowProps['ariaLabelConfig'];
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Draws and edits a diagram on the React Flow runtime. React Flow owns dragging, panning, zooming,
|
|
458
|
+
* selection, focus and its keyboard model; this component keeps the caller in charge of the data by turning
|
|
459
|
+
* every change into a request, and adds keyboard connecting, which the runtime does not offer.
|
|
460
|
+
*
|
|
461
|
+
* Every value handed to the runtime keeps its identity between renders. The runtime pushes any prop whose
|
|
462
|
+
* identity changed into its store after each render, and some of those — the selection callback among them —
|
|
463
|
+
* fire again when they change, so a fresh function or array per render is enough to loop.
|
|
464
|
+
*/
|
|
465
|
+
declare function DiagramEditorRoot(props: DiagramEditorProps): react.JSX.Element;
|
|
466
|
+
declare const DiagramEditor: typeof DiagramEditorRoot & {
|
|
467
|
+
Skeleton: typeof DiagramSkeleton;
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
export { type CeebeeAntStyleCache, CeebeeAntStyleProvider, type CeebeeAntStyleProviderProps, Checklist, type ChecklistProps, type ChecklistTask, type Command, CommandPalette, type CommandPaletteProps, DEFAULT_LABELS, Diagram, type DiagramEdge, DiagramEditor, type DiagramEditorProps, type DiagramNode, type DiagramPosition, type DiagramProps, type DiagramRemoval, type DiagramRenameTarget, type DiagramShape, type DiagramSkeletonProps, type DurationToken, type Labels, LabelsProvider, type LabelsProviderProps, Modal, type ModalProps, type MotionHelpers, MotionProvider, type MotionProviderProps, type MotionSettings, type NavItem, type NavSection, type PaletteCommand, PanZoomCanvas, type PanZoomCanvasProps, type PanZoomCanvasSkeletonProps, type RankedCommand, Reveal, type RevealProps, Sidebar, type SidebarProps, type SpringPreset, Stagger, type StaggerProps, StickerGroup, type StickerGroupProps, type StickerGroupSkeletonProps, type StickerItem, ThemeBridge, type ThemeBridgeProps, type ThemeChoice, ThemeProvider, type ThemeProviderProps, type ToastOptions, type ToastPosition, ToastProvider, type ToastProviderProps, TopBar, type TopBarProps, createCeebeeAntStyleCache, extractCeebeeAntStyles, filterCommands, groupCommands, rankCommand, useLabels, useMotionSettings, useTheme, useToast };
|
package/dist/client.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Modal as Modal$1, Button, theme, ConfigProvider, Progress } from 'antd';
|
|
3
3
|
export * from 'antd';
|
|
4
|
-
import { createContext, useId, useRef, useCallback, useInsertionEffect, useLayoutEffect, useState, useEffect,
|
|
4
|
+
import { createContext, useId, useRef, useCallback, useInsertionEffect, useLayoutEffect, useState, useEffect, useMemo, useContext, Children } from 'react';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import { StyleProvider, createCache, extractStyle } from '@ant-design/cssinjs';
|
|
7
7
|
export { default as enUSLocale } from 'antd/locale/en_US.js';
|
|
@@ -13,6 +13,7 @@ import { X, Minus, Plus, RotateCcw, Minimize2, Maximize2, Search, Check, Chevron
|
|
|
13
13
|
import { Toast } from '@base-ui/react/toast';
|
|
14
14
|
import { Popover } from '@base-ui/react/popover';
|
|
15
15
|
import { AnimatePresence, motion } from 'motion/react';
|
|
16
|
+
import { ReactFlow, ConnectionMode, Background, Controls, applyNodeChanges, MarkerType, Handle, Position } from '@xyflow/react';
|
|
16
17
|
|
|
17
18
|
// src/lib/cn.ts
|
|
18
19
|
function cn(...parts) {
|
|
@@ -662,7 +663,7 @@ var generatedCeebeeAntSeeds = {
|
|
|
662
663
|
"colorBgContainer": "rgba(255, 253, 248, 1)",
|
|
663
664
|
"colorBgElevated": "rgba(255, 255, 255, 1)",
|
|
664
665
|
"colorBorder": "rgba(83, 84, 97, 1)",
|
|
665
|
-
"colorBorderSecondary": "rgba(
|
|
666
|
+
"colorBorderSecondary": "rgba(126, 115, 107, 1)",
|
|
666
667
|
"fontSize": 14,
|
|
667
668
|
"fontSizeSM": 12,
|
|
668
669
|
"fontSizeLG": 16,
|
|
@@ -742,7 +743,7 @@ var generatedCeebeeAntSeeds = {
|
|
|
742
743
|
"colorBgContainer": "rgba(40, 40, 50, 1)",
|
|
743
744
|
"colorBgElevated": "rgba(51, 45, 41, 1)",
|
|
744
745
|
"colorBorder": "rgba(160, 163, 184, 1)",
|
|
745
|
-
"colorBorderSecondary": "rgba(
|
|
746
|
+
"colorBorderSecondary": "rgba(156, 150, 166, 1)",
|
|
746
747
|
"fontSize": 14,
|
|
747
748
|
"fontSizeSM": 12,
|
|
748
749
|
"fontSizeLG": 16,
|
|
@@ -815,10 +816,14 @@ function ThemeBridge({
|
|
|
815
816
|
if (event.target instanceof HTMLElement && event.target.id === SKIN_LINK_ID) refresh();
|
|
816
817
|
};
|
|
817
818
|
document.addEventListener("load", onSkinLoad, true);
|
|
819
|
+
const coarsePointer = window.matchMedia("(pointer: coarse)");
|
|
820
|
+
const onPointerChange = () => refresh();
|
|
821
|
+
coarsePointer.addEventListener("change", onPointerChange);
|
|
818
822
|
return () => {
|
|
819
823
|
rootObserver.disconnect();
|
|
820
824
|
headObserver.disconnect();
|
|
821
825
|
document.removeEventListener("load", onSkinLoad, true);
|
|
826
|
+
coarsePointer.removeEventListener("change", onPointerChange);
|
|
822
827
|
};
|
|
823
828
|
}, [refresh]);
|
|
824
829
|
const mergedTheme = useMemo(() => ({
|
|
@@ -1668,5 +1673,311 @@ function PanZoomCanvasRoot({
|
|
|
1668
1673
|
] });
|
|
1669
1674
|
}
|
|
1670
1675
|
var PanZoomCanvas = Object.assign(PanZoomCanvasRoot, { Skeleton: PanZoomCanvasSkeleton });
|
|
1676
|
+
function DiagramNodeView({ data, selected }) {
|
|
1677
|
+
return /* @__PURE__ */ jsxs(
|
|
1678
|
+
"div",
|
|
1679
|
+
{
|
|
1680
|
+
className: "cb-diagram__node",
|
|
1681
|
+
"data-shape": data.shape,
|
|
1682
|
+
"data-tone": data.tone,
|
|
1683
|
+
"data-selected": String(Boolean(selected)),
|
|
1684
|
+
"data-connecting": String(data.connecting),
|
|
1685
|
+
children: [
|
|
1686
|
+
/* @__PURE__ */ jsx(Handle, { id: "left", type: "target", position: Position.Left, className: "cb-diagram__handle", isConnectable: data.connectable }),
|
|
1687
|
+
/* @__PURE__ */ jsx(Handle, { id: "top", type: "target", position: Position.Top, className: "cb-diagram__handle", isConnectable: data.connectable }),
|
|
1688
|
+
/* @__PURE__ */ jsx("span", { className: "cb-diagram__label", children: data.label }),
|
|
1689
|
+
data.content,
|
|
1690
|
+
/* @__PURE__ */ jsx(Handle, { id: "right", type: "source", position: Position.Right, className: "cb-diagram__handle", isConnectable: data.connectable }),
|
|
1691
|
+
/* @__PURE__ */ jsx(Handle, { id: "bottom", type: "source", position: Position.Bottom, className: "cb-diagram__handle", isConnectable: data.connectable })
|
|
1692
|
+
]
|
|
1693
|
+
}
|
|
1694
|
+
);
|
|
1695
|
+
}
|
|
1696
|
+
var FLOW_NODE_TYPE = "cb-diagram";
|
|
1697
|
+
var FALLBACK_CELL = 20;
|
|
1698
|
+
function cellSize(measured) {
|
|
1699
|
+
return measured !== void 0 && measured > 0 ? measured : FALLBACK_CELL;
|
|
1700
|
+
}
|
|
1701
|
+
function toCells(position, cell) {
|
|
1702
|
+
return { x: Math.round(position.x / cell), y: Math.round(position.y / cell) };
|
|
1703
|
+
}
|
|
1704
|
+
function toFlowNodes(nodes, cell, state) {
|
|
1705
|
+
return nodes.map((node) => ({
|
|
1706
|
+
id: node.id,
|
|
1707
|
+
type: FLOW_NODE_TYPE,
|
|
1708
|
+
position: { x: node.position.x * cell, y: node.position.y * cell },
|
|
1709
|
+
selected: state.selectedId === node.id,
|
|
1710
|
+
data: {
|
|
1711
|
+
label: node.label,
|
|
1712
|
+
content: node.content,
|
|
1713
|
+
shape: node.shape ?? "rect",
|
|
1714
|
+
tone: node.tone,
|
|
1715
|
+
connecting: state.connectingFrom === node.id,
|
|
1716
|
+
connectable: state.connectable
|
|
1717
|
+
}
|
|
1718
|
+
}));
|
|
1719
|
+
}
|
|
1720
|
+
function centreOf(node) {
|
|
1721
|
+
const [columns, rows] = node.shape === "diamond" ? [4, 4] : [8, 3];
|
|
1722
|
+
return { x: node.position.x + columns / 2, y: node.position.y + rows / 2 };
|
|
1723
|
+
}
|
|
1724
|
+
function edgeHandles(from, to) {
|
|
1725
|
+
const a = centreOf(from);
|
|
1726
|
+
const b = centreOf(to);
|
|
1727
|
+
const dx = b.x - a.x;
|
|
1728
|
+
const dy = b.y - a.y;
|
|
1729
|
+
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
1730
|
+
return dx >= 0 ? { sourceHandle: "right", targetHandle: "left" } : { sourceHandle: "left", targetHandle: "right" };
|
|
1731
|
+
}
|
|
1732
|
+
return dy >= 0 ? { sourceHandle: "bottom", targetHandle: "top" } : { sourceHandle: "top", targetHandle: "bottom" };
|
|
1733
|
+
}
|
|
1734
|
+
function toFlowEdges(edges, nodes) {
|
|
1735
|
+
const byId = new Map(nodes.map((node) => [node.id, node]));
|
|
1736
|
+
return edges.flatMap((edge) => {
|
|
1737
|
+
const from = byId.get(edge.from);
|
|
1738
|
+
const to = byId.get(edge.to);
|
|
1739
|
+
if (!from || !to) return [];
|
|
1740
|
+
return [
|
|
1741
|
+
{
|
|
1742
|
+
id: edge.id,
|
|
1743
|
+
source: edge.from,
|
|
1744
|
+
target: edge.to,
|
|
1745
|
+
...edgeHandles(from, to),
|
|
1746
|
+
label: edge.label,
|
|
1747
|
+
className: edge.tone ? `cb-diagram__edge cb-diagram__edge--${edge.tone}` : "cb-diagram__edge",
|
|
1748
|
+
markerEnd: { type: MarkerType.ArrowClosed }
|
|
1749
|
+
}
|
|
1750
|
+
];
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1753
|
+
function settledMoves(changes, cell) {
|
|
1754
|
+
return changes.flatMap(
|
|
1755
|
+
(change) => change.type === "position" && change.position && change.dragging !== true ? [{ id: change.id, position: toCells(change.position, cell) }] : []
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1758
|
+
function changedMoves(moves, nodes) {
|
|
1759
|
+
return moves.filter((move) => {
|
|
1760
|
+
const current = nodes.find((node) => node.id === move.id)?.position;
|
|
1761
|
+
return !current || current.x !== move.position.x || current.y !== move.position.y;
|
|
1762
|
+
});
|
|
1763
|
+
}
|
|
1764
|
+
function mergeFlowNodes(current, next) {
|
|
1765
|
+
const byId = new Map(current.map((node) => [node.id, node]));
|
|
1766
|
+
let changed = current.length !== next.length;
|
|
1767
|
+
const merged = next.map((node, index) => {
|
|
1768
|
+
const previous = byId.get(node.id);
|
|
1769
|
+
if (!previous) {
|
|
1770
|
+
changed = true;
|
|
1771
|
+
return node;
|
|
1772
|
+
}
|
|
1773
|
+
const same = current[index] === previous && previous.position.x === node.position.x && previous.position.y === node.position.y && previous.data.label === node.data.label && previous.data.content === node.data.content && previous.data.shape === node.data.shape && previous.data.tone === node.data.tone && previous.data.connecting === node.data.connecting && previous.data.connectable === node.data.connectable;
|
|
1774
|
+
if (same) return previous;
|
|
1775
|
+
changed = true;
|
|
1776
|
+
return { ...node, selected: previous.selected, measured: previous.measured };
|
|
1777
|
+
});
|
|
1778
|
+
return changed ? merged : current;
|
|
1779
|
+
}
|
|
1780
|
+
function keepIfUnchanged(current, next) {
|
|
1781
|
+
return next.length === current.length && next.every((item, index) => item === current[index]) ? current : next;
|
|
1782
|
+
}
|
|
1783
|
+
function applySelection(current, selectedId) {
|
|
1784
|
+
let changed = false;
|
|
1785
|
+
const next = current.map((node) => {
|
|
1786
|
+
const selected = node.id === selectedId;
|
|
1787
|
+
if (Boolean(node.selected) === selected) return node;
|
|
1788
|
+
changed = true;
|
|
1789
|
+
return { ...node, selected };
|
|
1790
|
+
});
|
|
1791
|
+
return changed ? next : current;
|
|
1792
|
+
}
|
|
1793
|
+
function connectStep(state, event) {
|
|
1794
|
+
if (event.type === "cancel") return { state: { mode: "idle" } };
|
|
1795
|
+
if (event.type === "start" || state.mode === "idle") return { state: { mode: "connecting", from: event.nodeId } };
|
|
1796
|
+
if (event.nodeId === state.from) return { state: { mode: "idle" } };
|
|
1797
|
+
return { state: { mode: "idle" }, connect: { from: state.from, to: event.nodeId } };
|
|
1798
|
+
}
|
|
1799
|
+
var NODE_TYPES = { [FLOW_NODE_TYPE]: DiagramNodeView };
|
|
1800
|
+
function useCellSize(ref) {
|
|
1801
|
+
const [cell, setCell] = useState(FALLBACK_CELL);
|
|
1802
|
+
useEffect(() => {
|
|
1803
|
+
setCell(cellSize(ref.current?.getBoundingClientRect().width));
|
|
1804
|
+
}, [ref]);
|
|
1805
|
+
return cell;
|
|
1806
|
+
}
|
|
1807
|
+
function DiagramOutline({
|
|
1808
|
+
id,
|
|
1809
|
+
nodes,
|
|
1810
|
+
edges,
|
|
1811
|
+
label
|
|
1812
|
+
}) {
|
|
1813
|
+
const byId = new Map(nodes.map((n) => [n.id, n]));
|
|
1814
|
+
return /* @__PURE__ */ jsx("ul", { id, className: "cb-diagram__outline", "aria-label": label, children: nodes.map((node) => {
|
|
1815
|
+
const leaving = edges.filter((e) => e.from === node.id && byId.has(e.to));
|
|
1816
|
+
return /* @__PURE__ */ jsxs("li", { children: [
|
|
1817
|
+
node.label,
|
|
1818
|
+
leaving.length > 0 ? /* @__PURE__ */ jsx("ul", { children: leaving.map((edge) => /* @__PURE__ */ jsx("li", { children: `\u2192 ${byId.get(edge.to)?.label ?? ""}${edge.label ? `: ${edge.label}` : ""}` }, edge.id)) }) : null
|
|
1819
|
+
] }, node.id);
|
|
1820
|
+
}) });
|
|
1821
|
+
}
|
|
1822
|
+
function safeId(id) {
|
|
1823
|
+
return id.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
1824
|
+
}
|
|
1825
|
+
function DiagramSkeleton({ label = "Loading diagram" }) {
|
|
1826
|
+
return /* @__PURE__ */ jsx(PanZoomCanvasSkeleton, { label });
|
|
1827
|
+
}
|
|
1828
|
+
function DiagramRoot({ label, nodes, edges, hint, outlineLabel = "Diagram outline", ariaLabels }) {
|
|
1829
|
+
const base = safeId(useId());
|
|
1830
|
+
const cellRef = useRef(null);
|
|
1831
|
+
const cell = useCellSize(cellRef);
|
|
1832
|
+
const flowNodes = useMemo(() => toFlowNodes(nodes, cell, { connectable: false }), [nodes, cell]);
|
|
1833
|
+
const flowEdges = useMemo(() => toFlowEdges(edges, nodes), [edges, nodes]);
|
|
1834
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-diagram", children: [
|
|
1835
|
+
/* @__PURE__ */ jsx("span", { ref: cellRef, className: "cb-diagram__cell", "aria-hidden": "true" }),
|
|
1836
|
+
hint ? /* @__PURE__ */ jsx("p", { className: "cb-diagram__hint", children: hint }) : null,
|
|
1837
|
+
/* @__PURE__ */ jsx("div", { className: "cb-diagram__viewport", role: "region", "aria-label": label, "aria-describedby": `${base}-outline`, children: /* @__PURE__ */ jsxs(
|
|
1838
|
+
ReactFlow,
|
|
1839
|
+
{
|
|
1840
|
+
nodes: flowNodes,
|
|
1841
|
+
edges: flowEdges,
|
|
1842
|
+
nodeTypes: NODE_TYPES,
|
|
1843
|
+
connectionMode: ConnectionMode.Loose,
|
|
1844
|
+
nodesDraggable: false,
|
|
1845
|
+
nodesConnectable: false,
|
|
1846
|
+
elementsSelectable: false,
|
|
1847
|
+
nodesFocusable: false,
|
|
1848
|
+
edgesFocusable: false,
|
|
1849
|
+
fitView: true,
|
|
1850
|
+
minZoom: 0.5,
|
|
1851
|
+
maxZoom: 2,
|
|
1852
|
+
ariaLabelConfig: ariaLabels,
|
|
1853
|
+
children: [
|
|
1854
|
+
/* @__PURE__ */ jsx(Background, { gap: cell }),
|
|
1855
|
+
/* @__PURE__ */ jsx(Controls, { showInteractive: false })
|
|
1856
|
+
]
|
|
1857
|
+
}
|
|
1858
|
+
) }),
|
|
1859
|
+
/* @__PURE__ */ jsx(DiagramOutline, { id: `${base}-outline`, nodes, edges, label: outlineLabel })
|
|
1860
|
+
] });
|
|
1861
|
+
}
|
|
1862
|
+
var Diagram = Object.assign(DiagramRoot, { Skeleton: DiagramSkeleton });
|
|
1863
|
+
var CONNECT_KEY = "c";
|
|
1864
|
+
var DELETE_KEYS = ["Delete", "Backspace"];
|
|
1865
|
+
var defaultConnectingStatus = (node) => `Connecting from ${node}. Focus another node and press C, or press Escape to cancel.`;
|
|
1866
|
+
function elementAt(target) {
|
|
1867
|
+
if (!(target instanceof Element)) return null;
|
|
1868
|
+
const node = target.closest(".react-flow__node")?.getAttribute("data-id");
|
|
1869
|
+
if (node) return { kind: "node", id: node };
|
|
1870
|
+
const edge = target.closest(".react-flow__edge")?.getAttribute("data-id");
|
|
1871
|
+
return edge ? { kind: "edge", id: edge } : null;
|
|
1872
|
+
}
|
|
1873
|
+
function DiagramEditorRoot(props) {
|
|
1874
|
+
const { label, nodes, edges, hint, selectedId, connectingStatus = defaultConnectingStatus, outlineLabel = "Diagram outline", ariaLabels } = props;
|
|
1875
|
+
const base = safeId(useId());
|
|
1876
|
+
const cellRef = useRef(null);
|
|
1877
|
+
const cell = useCellSize(cellRef);
|
|
1878
|
+
const [connect, setConnect] = useState({ mode: "idle" });
|
|
1879
|
+
const connectingFrom = connect.mode === "connecting" ? connect.from : null;
|
|
1880
|
+
const latest = useRef({ props, cell, connect });
|
|
1881
|
+
latest.current = { props, cell, connect };
|
|
1882
|
+
const reportedSelection = useRef(selectedId ?? null);
|
|
1883
|
+
const [resync, setResync] = useState(0);
|
|
1884
|
+
const [flowNodes, setFlowNodes] = useState(() => toFlowNodes(nodes, cell, { selectedId, connectable: true }));
|
|
1885
|
+
useEffect(() => {
|
|
1886
|
+
setFlowNodes((current) => mergeFlowNodes(current, toFlowNodes(nodes, cell, { connectingFrom, connectable: true })));
|
|
1887
|
+
}, [nodes, cell, connectingFrom, resync]);
|
|
1888
|
+
useEffect(() => {
|
|
1889
|
+
if (selectedId === void 0) return;
|
|
1890
|
+
reportedSelection.current = selectedId;
|
|
1891
|
+
setFlowNodes((current) => applySelection(current, selectedId));
|
|
1892
|
+
}, [selectedId]);
|
|
1893
|
+
const flowEdges = useMemo(() => toFlowEdges(edges, nodes), [edges, nodes]);
|
|
1894
|
+
const snapGrid = useMemo(() => [cell, cell], [cell]);
|
|
1895
|
+
const step = useCallback((event) => {
|
|
1896
|
+
const { connect: state, props: current } = latest.current;
|
|
1897
|
+
const next = connectStep(state, event);
|
|
1898
|
+
setConnect(next.state);
|
|
1899
|
+
if (next.connect) current.onConnect?.(next.connect.from, next.connect.to);
|
|
1900
|
+
}, []);
|
|
1901
|
+
const onNodesChange = useCallback((changes) => {
|
|
1902
|
+
const { props: current, cell: size } = latest.current;
|
|
1903
|
+
setFlowNodes((mirror) => keepIfUnchanged(mirror, applyNodeChanges(changes.filter((change) => change.type !== "remove"), mirror)));
|
|
1904
|
+
const moves = changedMoves(settledMoves(changes, size), current.nodes);
|
|
1905
|
+
for (const move of moves) current.onMoveNode?.(move.id, move.position);
|
|
1906
|
+
if (moves.length > 0) setResync((n) => n + 1);
|
|
1907
|
+
}, []);
|
|
1908
|
+
const onConnectEdge = useCallback((connection) => {
|
|
1909
|
+
if (connection.source !== connection.target) latest.current.props.onConnect?.(connection.source, connection.target);
|
|
1910
|
+
}, []);
|
|
1911
|
+
const onBeforeDelete = useCallback(async ({ nodes: gone, edges: goneEdges }) => {
|
|
1912
|
+
latest.current.props.onRemove?.({ nodeIds: gone.map((n) => n.id), edgeIds: goneEdges.map((e) => e.id) });
|
|
1913
|
+
return false;
|
|
1914
|
+
}, []);
|
|
1915
|
+
const onSelectionChange = useCallback(({ nodes: chosen }) => {
|
|
1916
|
+
const id = chosen[0]?.id;
|
|
1917
|
+
if (!id || id === reportedSelection.current) return;
|
|
1918
|
+
reportedSelection.current = id;
|
|
1919
|
+
latest.current.props.onSelectionChange?.(id);
|
|
1920
|
+
}, []);
|
|
1921
|
+
const onNodeClick = useCallback(
|
|
1922
|
+
(_, node) => {
|
|
1923
|
+
if (latest.current.connect.mode === "connecting") step({ type: "choose", nodeId: node.id });
|
|
1924
|
+
},
|
|
1925
|
+
[step]
|
|
1926
|
+
);
|
|
1927
|
+
const onPaneClick = useCallback(() => {
|
|
1928
|
+
if (latest.current.connect.mode === "connecting") step({ type: "cancel" });
|
|
1929
|
+
}, [step]);
|
|
1930
|
+
const onKeyDown = useCallback(
|
|
1931
|
+
(event) => {
|
|
1932
|
+
const target = elementAt(event.target);
|
|
1933
|
+
if (event.key.toLowerCase() === CONNECT_KEY && target?.kind === "node" && !event.metaKey && !event.ctrlKey && !event.altKey) {
|
|
1934
|
+
event.preventDefault();
|
|
1935
|
+
step({ type: "choose", nodeId: target.id });
|
|
1936
|
+
} else if (event.key === "Escape" && latest.current.connect.mode === "connecting") {
|
|
1937
|
+
step({ type: "cancel" });
|
|
1938
|
+
} else if (event.key === "F2" && target) {
|
|
1939
|
+
event.preventDefault();
|
|
1940
|
+
latest.current.props.onRename?.(target);
|
|
1941
|
+
}
|
|
1942
|
+
},
|
|
1943
|
+
[step]
|
|
1944
|
+
);
|
|
1945
|
+
const labelOf = (id) => nodes.find((n) => n.id === id)?.label ?? "";
|
|
1946
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-diagram cb-diagram--editor", children: [
|
|
1947
|
+
/* @__PURE__ */ jsx("span", { ref: cellRef, className: "cb-diagram__cell", "aria-hidden": "true" }),
|
|
1948
|
+
hint ? /* @__PURE__ */ jsx("p", { className: "cb-diagram__hint", children: hint }) : null,
|
|
1949
|
+
/* @__PURE__ */ jsx("div", { className: "cb-diagram__viewport", role: "region", "aria-label": label, "aria-describedby": `${base}-outline`, children: /* @__PURE__ */ jsxs(
|
|
1950
|
+
ReactFlow,
|
|
1951
|
+
{
|
|
1952
|
+
nodes: flowNodes,
|
|
1953
|
+
edges: flowEdges,
|
|
1954
|
+
nodeTypes: NODE_TYPES,
|
|
1955
|
+
onNodesChange,
|
|
1956
|
+
onConnect: onConnectEdge,
|
|
1957
|
+
onBeforeDelete,
|
|
1958
|
+
onSelectionChange,
|
|
1959
|
+
onNodeClick,
|
|
1960
|
+
onPaneClick,
|
|
1961
|
+
onKeyDown,
|
|
1962
|
+
connectionMode: ConnectionMode.Loose,
|
|
1963
|
+
connectOnClick: true,
|
|
1964
|
+
snapToGrid: true,
|
|
1965
|
+
snapGrid,
|
|
1966
|
+
deleteKeyCode: DELETE_KEYS,
|
|
1967
|
+
fitView: true,
|
|
1968
|
+
minZoom: 0.5,
|
|
1969
|
+
maxZoom: 2,
|
|
1970
|
+
ariaLabelConfig: ariaLabels,
|
|
1971
|
+
children: [
|
|
1972
|
+
/* @__PURE__ */ jsx(Background, { gap: cell }),
|
|
1973
|
+
/* @__PURE__ */ jsx(Controls, { showInteractive: false })
|
|
1974
|
+
]
|
|
1975
|
+
}
|
|
1976
|
+
) }),
|
|
1977
|
+
/* @__PURE__ */ jsx("p", { className: "cb-diagram__status", role: "status", children: connectingFrom ? connectingStatus(labelOf(connectingFrom)) : "" }),
|
|
1978
|
+
/* @__PURE__ */ jsx(DiagramOutline, { id: `${base}-outline`, nodes, edges, label: outlineLabel })
|
|
1979
|
+
] });
|
|
1980
|
+
}
|
|
1981
|
+
var DiagramEditor = Object.assign(DiagramEditorRoot, { Skeleton: DiagramSkeleton });
|
|
1671
1982
|
|
|
1672
|
-
export { CeebeeAntStyleProvider, Checklist, CommandPalette, DEFAULT_LABELS, LabelsProvider, Modal, MotionProvider, PanZoomCanvas, Reveal, Sidebar, Stagger, StickerGroup, ThemeBridge, ThemeProvider, ToastProvider, TopBar, createCeebeeAntStyleCache, extractCeebeeAntStyles, filterCommands, groupCommands, rankCommand, useLabels, useMotionSettings, useTheme, useToast };
|
|
1983
|
+
export { CeebeeAntStyleProvider, Checklist, CommandPalette, DEFAULT_LABELS, Diagram, DiagramEditor, LabelsProvider, Modal, MotionProvider, PanZoomCanvas, Reveal, Sidebar, Stagger, StickerGroup, ThemeBridge, ThemeProvider, ToastProvider, TopBar, createCeebeeAntStyleCache, extractCeebeeAntStyles, filterCommands, groupCommands, rankCommand, useLabels, useMotionSettings, useTheme, useToast };
|
package/dist/index.js
CHANGED
|
@@ -550,7 +550,7 @@ var generatedCeebeeAntSeeds = {
|
|
|
550
550
|
"colorBgContainer": "rgba(255, 253, 248, 1)",
|
|
551
551
|
"colorBgElevated": "rgba(255, 255, 255, 1)",
|
|
552
552
|
"colorBorder": "rgba(83, 84, 97, 1)",
|
|
553
|
-
"colorBorderSecondary": "rgba(
|
|
553
|
+
"colorBorderSecondary": "rgba(126, 115, 107, 1)",
|
|
554
554
|
"fontSize": 14,
|
|
555
555
|
"fontSizeSM": 12,
|
|
556
556
|
"fontSizeLG": 16,
|
|
@@ -630,7 +630,7 @@ var generatedCeebeeAntSeeds = {
|
|
|
630
630
|
"colorBgContainer": "rgba(40, 40, 50, 1)",
|
|
631
631
|
"colorBgElevated": "rgba(51, 45, 41, 1)",
|
|
632
632
|
"colorBorder": "rgba(160, 163, 184, 1)",
|
|
633
|
-
"colorBorderSecondary": "rgba(
|
|
633
|
+
"colorBorderSecondary": "rgba(156, 150, 166, 1)",
|
|
634
634
|
"fontSize": 14,
|
|
635
635
|
"fontSizeSM": 12,
|
|
636
636
|
"fontSizeLG": 16,
|
package/dist/skins/moodboard.css
CHANGED
|
@@ -90,3 +90,24 @@
|
|
|
90
90
|
--cb-sticker-shadow: 0 var(--cb-space-1) var(--cb-space-2) oklch(0 0 0 / 0.42);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
+
|
|
94
|
+
/* Someone on this Skin who asks for more contrast should get an edge in this
|
|
95
|
+
Skin's own warmth, not the neutral one the base falls back to. These values
|
|
96
|
+
are the ones CeeBee List's Flutter client had tuned locally and shipped —
|
|
97
|
+
what already worked, abstracted so every product on this Skin gets it.
|
|
98
|
+
|
|
99
|
+
`html:root` matches the base's own specificity and comes later, which is how
|
|
100
|
+
this wins. The base claims that weight so a Skin cannot weaken an
|
|
101
|
+
accessibility edge; both of these are stronger than what they replace —
|
|
102
|
+
0.5632 against the base's 0.70 in light, 0.6834 against 0.58 in dark — so the
|
|
103
|
+
rule is honoured rather than worked around. */
|
|
104
|
+
@media (prefers-contrast: more) {
|
|
105
|
+
html:root {
|
|
106
|
+
--cb-border: oklch(0.5632 0.0183 58.4);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
html:root[data-theme="dark"],
|
|
110
|
+
html:root:not([data-theme="light"]) {
|
|
111
|
+
--cb-border: oklch(0.6834 0.0241 302.8);
|
|
112
|
+
}
|
|
113
|
+
}
|
package/dist/styles.css
CHANGED
|
@@ -38,9 +38,23 @@
|
|
|
38
38
|
--cb-weight-medium: 500;
|
|
39
39
|
--cb-weight-semibold: 600;
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
/* The height a control must not go below for the pointer in use. A mouse points and can hit a
|
|
42
|
+
32px target; a finger cannot, so a coarse pointer needs 44px — WCAG 2.5.5, Apple HIG, and
|
|
43
|
+
Material all land there. */
|
|
44
|
+
--cb-control-floor-fine: 2rem;
|
|
45
|
+
--cb-control-floor-coarse: 2.75rem;
|
|
46
|
+
--cb-control-floor: var(--cb-control-floor-fine);
|
|
47
|
+
|
|
48
|
+
/* The ladder's preferred heights. A density scale retunes these; the resolved heights below are
|
|
49
|
+
`max()` of the preferred step and the active floor, so no scale can shrink a control under the
|
|
50
|
+
target its pointer can hit. */
|
|
51
|
+
--cb-control-height-base-sm: 2rem;
|
|
52
|
+
--cb-control-height-base-md: 2.5rem;
|
|
53
|
+
--cb-control-height-base-lg: 3rem;
|
|
54
|
+
|
|
55
|
+
--cb-control-height-sm: max(var(--cb-control-height-base-sm), var(--cb-control-floor));
|
|
56
|
+
--cb-control-height-md: max(var(--cb-control-height-base-md), var(--cb-control-floor));
|
|
57
|
+
--cb-control-height-lg: max(var(--cb-control-height-base-lg), var(--cb-control-floor));
|
|
44
58
|
--cb-canvas-block-size: 32rem;
|
|
45
59
|
|
|
46
60
|
--cb-sticker-enter-y: var(--cb-space-3);
|
|
@@ -73,6 +87,16 @@
|
|
|
73
87
|
--cb-z-overlay: var(--cb-z-modal-backdrop);
|
|
74
88
|
}
|
|
75
89
|
|
|
90
|
+
/* A coarse pointer switches the active floor to the touch target. The resolved heights above are
|
|
91
|
+
`max()` of the preferred step and that floor, so `sm` and `md` both reach 44px and `lg` keeps its
|
|
92
|
+
48px — nothing here restates a step, so retuning `--cb-control-height-base-*` on either pointer
|
|
93
|
+
still cannot take a control under its floor. */
|
|
94
|
+
@media (pointer: coarse) {
|
|
95
|
+
:root {
|
|
96
|
+
--cb-control-floor: var(--cb-control-floor-coarse);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
76
100
|
/* tokens/skin.css */
|
|
77
101
|
/* Skin tokens: the default Ceebee skin. A Skin file rewrites only these.
|
|
78
102
|
Light is defined on bare :root so no colour has its only definition inside a media query. */
|
|
@@ -363,6 +387,513 @@ html, body { background: var(--cb-bg); color: var(--cb-fg); }
|
|
|
363
387
|
--cb-skeleton-opacity-max: 1;
|
|
364
388
|
}
|
|
365
389
|
|
|
390
|
+
/* @xyflow/react/dist/base.css (MIT, see THIRD_PARTY_NOTICES.md) */
|
|
391
|
+
/* this will be exported as base.css and can be used for a basic styling */
|
|
392
|
+
/* these are the necessary styles for React/Svelte Flow, they get used by base.css and style.css */
|
|
393
|
+
.react-flow {
|
|
394
|
+
direction: ltr;
|
|
395
|
+
|
|
396
|
+
--xy-edge-stroke-default: #b1b1b7;
|
|
397
|
+
--xy-edge-stroke-width-default: 1;
|
|
398
|
+
--xy-edge-stroke-selected-default: #555;
|
|
399
|
+
|
|
400
|
+
--xy-connectionline-stroke-default: #b1b1b7;
|
|
401
|
+
--xy-connectionline-stroke-width-default: 1;
|
|
402
|
+
|
|
403
|
+
--xy-attribution-background-color-default: rgba(255, 255, 255, 0.5);
|
|
404
|
+
|
|
405
|
+
--xy-minimap-background-color-default: #fff;
|
|
406
|
+
--xy-minimap-mask-background-color-default: rgba(240, 240, 240, 0.6);
|
|
407
|
+
--xy-minimap-mask-stroke-color-default: transparent;
|
|
408
|
+
--xy-minimap-mask-stroke-width-default: 1;
|
|
409
|
+
--xy-minimap-node-background-color-default: #e2e2e2;
|
|
410
|
+
--xy-minimap-node-stroke-color-default: transparent;
|
|
411
|
+
--xy-minimap-node-stroke-width-default: 2;
|
|
412
|
+
|
|
413
|
+
--xy-background-color-default: transparent;
|
|
414
|
+
--xy-background-pattern-dots-color-default: #91919a;
|
|
415
|
+
--xy-background-pattern-lines-color-default: #eee;
|
|
416
|
+
--xy-background-pattern-cross-color-default: #e2e2e2;
|
|
417
|
+
background-color: var(--xy-background-color, var(--xy-background-color-default));
|
|
418
|
+
--xy-node-border-default: 1px solid #bbb;
|
|
419
|
+
--xy-node-border-selected-default: 1px solid #555;
|
|
420
|
+
|
|
421
|
+
--xy-handle-background-color-default: #333;
|
|
422
|
+
|
|
423
|
+
--xy-selection-background-color-default: rgba(150, 150, 180, 0.1);
|
|
424
|
+
--xy-selection-border-default: 1px dotted rgba(155, 155, 155, 0.8);
|
|
425
|
+
--xy-resize-background-color-default: #3367d9;
|
|
426
|
+
}
|
|
427
|
+
.react-flow.dark {
|
|
428
|
+
--xy-edge-stroke-default: #3e3e3e;
|
|
429
|
+
--xy-edge-stroke-width-default: 1;
|
|
430
|
+
--xy-edge-stroke-selected-default: #727272;
|
|
431
|
+
|
|
432
|
+
--xy-connectionline-stroke-default: #b1b1b7;
|
|
433
|
+
--xy-connectionline-stroke-width-default: 1;
|
|
434
|
+
|
|
435
|
+
--xy-attribution-background-color-default: rgba(150, 150, 150, 0.25);
|
|
436
|
+
|
|
437
|
+
--xy-minimap-background-color-default: #141414;
|
|
438
|
+
--xy-minimap-mask-background-color-default: rgba(60, 60, 60, 0.6);
|
|
439
|
+
--xy-minimap-mask-stroke-color-default: transparent;
|
|
440
|
+
--xy-minimap-mask-stroke-width-default: 1;
|
|
441
|
+
--xy-minimap-node-background-color-default: #2b2b2b;
|
|
442
|
+
--xy-minimap-node-stroke-color-default: transparent;
|
|
443
|
+
--xy-minimap-node-stroke-width-default: 2;
|
|
444
|
+
|
|
445
|
+
--xy-background-color-default: #141414;
|
|
446
|
+
--xy-background-pattern-dots-color-default: #555;
|
|
447
|
+
--xy-background-pattern-lines-color-default: #333;
|
|
448
|
+
--xy-background-pattern-cross-color-default: #333;
|
|
449
|
+
--xy-node-color-default: #f8f8f8;
|
|
450
|
+
}
|
|
451
|
+
.react-flow__background {
|
|
452
|
+
background-color: var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));
|
|
453
|
+
pointer-events: none;
|
|
454
|
+
z-index: -1;
|
|
455
|
+
}
|
|
456
|
+
.react-flow__container {
|
|
457
|
+
position: absolute;
|
|
458
|
+
width: 100%;
|
|
459
|
+
height: 100%;
|
|
460
|
+
top: 0;
|
|
461
|
+
left: 0;
|
|
462
|
+
}
|
|
463
|
+
.react-flow__pane {
|
|
464
|
+
z-index: 1;
|
|
465
|
+
touch-action: none;
|
|
466
|
+
}
|
|
467
|
+
.react-flow__pane.draggable {
|
|
468
|
+
cursor: grab;
|
|
469
|
+
}
|
|
470
|
+
.react-flow__pane.dragging {
|
|
471
|
+
cursor: grabbing;
|
|
472
|
+
}
|
|
473
|
+
.react-flow__pane.selection {
|
|
474
|
+
cursor: pointer;
|
|
475
|
+
}
|
|
476
|
+
.react-flow__viewport {
|
|
477
|
+
transform-origin: 0 0;
|
|
478
|
+
z-index: 2;
|
|
479
|
+
pointer-events: none;
|
|
480
|
+
}
|
|
481
|
+
.react-flow__renderer {
|
|
482
|
+
z-index: 4;
|
|
483
|
+
}
|
|
484
|
+
.react-flow__selection {
|
|
485
|
+
z-index: 6;
|
|
486
|
+
}
|
|
487
|
+
.react-flow__nodesselection-rect:focus,
|
|
488
|
+
.react-flow__nodesselection-rect:focus-visible {
|
|
489
|
+
outline: none;
|
|
490
|
+
}
|
|
491
|
+
.react-flow__edge-path {
|
|
492
|
+
stroke: var(--xy-edge-stroke, var(--xy-edge-stroke-default));
|
|
493
|
+
stroke-width: var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));
|
|
494
|
+
fill: none;
|
|
495
|
+
}
|
|
496
|
+
.react-flow__connection-path {
|
|
497
|
+
stroke: var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));
|
|
498
|
+
stroke-width: var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));
|
|
499
|
+
fill: none;
|
|
500
|
+
}
|
|
501
|
+
.react-flow .react-flow__edges {
|
|
502
|
+
position: absolute;
|
|
503
|
+
}
|
|
504
|
+
.react-flow .react-flow__edges svg {
|
|
505
|
+
overflow: visible;
|
|
506
|
+
position: absolute;
|
|
507
|
+
pointer-events: none;
|
|
508
|
+
}
|
|
509
|
+
.react-flow__edge {
|
|
510
|
+
pointer-events: visibleStroke;
|
|
511
|
+
}
|
|
512
|
+
.react-flow__edge.selectable {
|
|
513
|
+
cursor: pointer;
|
|
514
|
+
}
|
|
515
|
+
.react-flow__edge.animated path {
|
|
516
|
+
stroke-dasharray: 5;
|
|
517
|
+
animation: dashdraw 0.5s linear infinite;
|
|
518
|
+
}
|
|
519
|
+
.react-flow__edge.animated path.react-flow__edge-interaction {
|
|
520
|
+
stroke-dasharray: none;
|
|
521
|
+
animation: none;
|
|
522
|
+
}
|
|
523
|
+
.react-flow__edge.inactive {
|
|
524
|
+
pointer-events: none;
|
|
525
|
+
}
|
|
526
|
+
.react-flow__edge.selected,
|
|
527
|
+
.react-flow__edge:focus,
|
|
528
|
+
.react-flow__edge:focus-visible {
|
|
529
|
+
outline: none;
|
|
530
|
+
}
|
|
531
|
+
.react-flow__edge.selected .react-flow__edge-path,
|
|
532
|
+
.react-flow__edge.selectable:focus .react-flow__edge-path,
|
|
533
|
+
.react-flow__edge.selectable:focus-visible .react-flow__edge-path {
|
|
534
|
+
stroke: var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default));
|
|
535
|
+
}
|
|
536
|
+
.react-flow__edge-textwrapper {
|
|
537
|
+
pointer-events: all;
|
|
538
|
+
}
|
|
539
|
+
.react-flow__edge .react-flow__edge-text {
|
|
540
|
+
pointer-events: none;
|
|
541
|
+
-webkit-user-select: none;
|
|
542
|
+
-moz-user-select: none;
|
|
543
|
+
user-select: none;
|
|
544
|
+
}
|
|
545
|
+
/* Arrowhead marker styles - use CSS custom properties as default */
|
|
546
|
+
.react-flow__arrowhead polyline {
|
|
547
|
+
stroke: var(--xy-edge-stroke, var(--xy-edge-stroke-default));
|
|
548
|
+
}
|
|
549
|
+
.react-flow__arrowhead polyline.arrowclosed {
|
|
550
|
+
fill: var(--xy-edge-stroke, var(--xy-edge-stroke-default));
|
|
551
|
+
}
|
|
552
|
+
.react-flow__connection {
|
|
553
|
+
pointer-events: none;
|
|
554
|
+
}
|
|
555
|
+
.react-flow__connection .animated {
|
|
556
|
+
stroke-dasharray: 5;
|
|
557
|
+
animation: dashdraw 0.5s linear infinite;
|
|
558
|
+
}
|
|
559
|
+
svg.react-flow__connectionline {
|
|
560
|
+
z-index: 1001;
|
|
561
|
+
overflow: visible;
|
|
562
|
+
position: absolute;
|
|
563
|
+
}
|
|
564
|
+
.react-flow__nodes {
|
|
565
|
+
pointer-events: none;
|
|
566
|
+
transform-origin: 0 0;
|
|
567
|
+
}
|
|
568
|
+
.react-flow__node {
|
|
569
|
+
position: absolute;
|
|
570
|
+
-webkit-user-select: none;
|
|
571
|
+
-moz-user-select: none;
|
|
572
|
+
user-select: none;
|
|
573
|
+
pointer-events: all;
|
|
574
|
+
transform-origin: 0 0;
|
|
575
|
+
box-sizing: border-box;
|
|
576
|
+
cursor: default;
|
|
577
|
+
}
|
|
578
|
+
.react-flow__node.selectable {
|
|
579
|
+
cursor: pointer;
|
|
580
|
+
}
|
|
581
|
+
.react-flow__node.draggable {
|
|
582
|
+
cursor: grab;
|
|
583
|
+
pointer-events: all;
|
|
584
|
+
}
|
|
585
|
+
.react-flow__node.draggable.dragging {
|
|
586
|
+
cursor: grabbing;
|
|
587
|
+
}
|
|
588
|
+
.react-flow__nodesselection {
|
|
589
|
+
z-index: 3;
|
|
590
|
+
transform-origin: left top;
|
|
591
|
+
pointer-events: none;
|
|
592
|
+
}
|
|
593
|
+
.react-flow__nodesselection-rect {
|
|
594
|
+
position: absolute;
|
|
595
|
+
pointer-events: all;
|
|
596
|
+
cursor: grab;
|
|
597
|
+
}
|
|
598
|
+
.react-flow__handle {
|
|
599
|
+
position: absolute;
|
|
600
|
+
pointer-events: none;
|
|
601
|
+
min-width: 5px;
|
|
602
|
+
min-height: 5px;
|
|
603
|
+
background-color: var(--xy-handle-background-color, var(--xy-handle-background-color-default));
|
|
604
|
+
}
|
|
605
|
+
.react-flow__handle.connectingfrom {
|
|
606
|
+
pointer-events: all;
|
|
607
|
+
}
|
|
608
|
+
.react-flow__handle.connectionindicator {
|
|
609
|
+
pointer-events: all;
|
|
610
|
+
cursor: crosshair;
|
|
611
|
+
}
|
|
612
|
+
.react-flow__handle-bottom {
|
|
613
|
+
top: auto;
|
|
614
|
+
left: 50%;
|
|
615
|
+
bottom: 0;
|
|
616
|
+
transform: translate(-50%, 50%);
|
|
617
|
+
}
|
|
618
|
+
.react-flow__handle-top {
|
|
619
|
+
top: 0;
|
|
620
|
+
left: 50%;
|
|
621
|
+
transform: translate(-50%, -50%);
|
|
622
|
+
}
|
|
623
|
+
.react-flow__handle-left {
|
|
624
|
+
top: 50%;
|
|
625
|
+
left: 0;
|
|
626
|
+
transform: translate(-50%, -50%);
|
|
627
|
+
}
|
|
628
|
+
.react-flow__handle-right {
|
|
629
|
+
top: 50%;
|
|
630
|
+
right: 0;
|
|
631
|
+
transform: translate(50%, -50%);
|
|
632
|
+
}
|
|
633
|
+
.react-flow__edgeupdater {
|
|
634
|
+
cursor: move;
|
|
635
|
+
pointer-events: all;
|
|
636
|
+
}
|
|
637
|
+
.react-flow__pane.selection .react-flow__panel {
|
|
638
|
+
pointer-events: none;
|
|
639
|
+
}
|
|
640
|
+
.react-flow__panel {
|
|
641
|
+
position: absolute;
|
|
642
|
+
z-index: 5;
|
|
643
|
+
margin: 15px;
|
|
644
|
+
}
|
|
645
|
+
.react-flow__panel.top {
|
|
646
|
+
top: 0;
|
|
647
|
+
}
|
|
648
|
+
.react-flow__panel.bottom {
|
|
649
|
+
bottom: 0;
|
|
650
|
+
}
|
|
651
|
+
.react-flow__panel.top.center, .react-flow__panel.bottom.center {
|
|
652
|
+
left: 50%;
|
|
653
|
+
transform: translateX(-15px) translateX(-50%);
|
|
654
|
+
}
|
|
655
|
+
.react-flow__panel.left {
|
|
656
|
+
left: 0;
|
|
657
|
+
}
|
|
658
|
+
.react-flow__panel.right {
|
|
659
|
+
right: 0;
|
|
660
|
+
}
|
|
661
|
+
.react-flow__panel.left.center, .react-flow__panel.right.center {
|
|
662
|
+
top: 50%;
|
|
663
|
+
transform: translateY(-15px) translateY(-50%);
|
|
664
|
+
}
|
|
665
|
+
.react-flow__attribution {
|
|
666
|
+
font-size: 10px;
|
|
667
|
+
background: var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));
|
|
668
|
+
padding: 2px 3px;
|
|
669
|
+
margin: 0;
|
|
670
|
+
}
|
|
671
|
+
.react-flow__attribution a {
|
|
672
|
+
text-decoration: none;
|
|
673
|
+
color: #999;
|
|
674
|
+
}
|
|
675
|
+
@keyframes dashdraw {
|
|
676
|
+
from {
|
|
677
|
+
stroke-dashoffset: 10;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
.react-flow__edgelabel-renderer {
|
|
681
|
+
position: absolute;
|
|
682
|
+
width: 100%;
|
|
683
|
+
height: 100%;
|
|
684
|
+
pointer-events: none;
|
|
685
|
+
-webkit-user-select: none;
|
|
686
|
+
-moz-user-select: none;
|
|
687
|
+
user-select: none;
|
|
688
|
+
left: 0;
|
|
689
|
+
top: 0;
|
|
690
|
+
}
|
|
691
|
+
.react-flow__viewport-portal {
|
|
692
|
+
position: absolute;
|
|
693
|
+
width: 100%;
|
|
694
|
+
height: 100%;
|
|
695
|
+
left: 0;
|
|
696
|
+
top: 0;
|
|
697
|
+
-webkit-user-select: none;
|
|
698
|
+
-moz-user-select: none;
|
|
699
|
+
user-select: none;
|
|
700
|
+
}
|
|
701
|
+
.react-flow__minimap {
|
|
702
|
+
background: var(
|
|
703
|
+
--xy-minimap-background-color-props,
|
|
704
|
+
var(--xy-minimap-background-color, var(--xy-minimap-background-color-default))
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
.react-flow__minimap-svg {
|
|
708
|
+
display: block;
|
|
709
|
+
}
|
|
710
|
+
.react-flow__minimap-mask {
|
|
711
|
+
fill: var(
|
|
712
|
+
--xy-minimap-mask-background-color-props,
|
|
713
|
+
var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default))
|
|
714
|
+
);
|
|
715
|
+
stroke: var(
|
|
716
|
+
--xy-minimap-mask-stroke-color-props,
|
|
717
|
+
var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default))
|
|
718
|
+
);
|
|
719
|
+
stroke-width: var(
|
|
720
|
+
--xy-minimap-mask-stroke-width-props,
|
|
721
|
+
var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default))
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
.react-flow__minimap-node {
|
|
725
|
+
fill: var(
|
|
726
|
+
--xy-minimap-node-background-color-props,
|
|
727
|
+
var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default))
|
|
728
|
+
);
|
|
729
|
+
stroke: var(
|
|
730
|
+
--xy-minimap-node-stroke-color-props,
|
|
731
|
+
var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default))
|
|
732
|
+
);
|
|
733
|
+
stroke-width: var(
|
|
734
|
+
--xy-minimap-node-stroke-width-props,
|
|
735
|
+
var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default))
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
.react-flow__background-pattern.dots {
|
|
739
|
+
fill: var(
|
|
740
|
+
--xy-background-pattern-color-props,
|
|
741
|
+
var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default))
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
.react-flow__background-pattern.lines {
|
|
745
|
+
stroke: var(
|
|
746
|
+
--xy-background-pattern-color-props,
|
|
747
|
+
var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default))
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
.react-flow__background-pattern.cross {
|
|
751
|
+
stroke: var(
|
|
752
|
+
--xy-background-pattern-color-props,
|
|
753
|
+
var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default))
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
.react-flow__controls {
|
|
757
|
+
display: flex;
|
|
758
|
+
flex-direction: column;
|
|
759
|
+
}
|
|
760
|
+
.react-flow__controls.horizontal {
|
|
761
|
+
flex-direction: row;
|
|
762
|
+
}
|
|
763
|
+
.react-flow__controls-button {
|
|
764
|
+
display: flex;
|
|
765
|
+
justify-content: center;
|
|
766
|
+
align-items: center;
|
|
767
|
+
height: 26px;
|
|
768
|
+
width: 26px;
|
|
769
|
+
padding: 4px;
|
|
770
|
+
}
|
|
771
|
+
.react-flow__controls-button svg {
|
|
772
|
+
width: 100%;
|
|
773
|
+
max-width: 12px;
|
|
774
|
+
max-height: 12px;
|
|
775
|
+
fill: currentColor;
|
|
776
|
+
}
|
|
777
|
+
.react-flow__node-input,
|
|
778
|
+
.react-flow__node-default,
|
|
779
|
+
.react-flow__node-output,
|
|
780
|
+
.react-flow__node-group {
|
|
781
|
+
border: var(--xy-node-border, var(--xy-node-border-default));
|
|
782
|
+
color: var(--xy-node-color, var(--xy-node-color-default));
|
|
783
|
+
}
|
|
784
|
+
.react-flow__node-input.selected,
|
|
785
|
+
.react-flow__node-input:focus,
|
|
786
|
+
.react-flow__node-input:focus-visible,
|
|
787
|
+
.react-flow__node-default.selected,
|
|
788
|
+
.react-flow__node-default:focus,
|
|
789
|
+
.react-flow__node-default:focus-visible,
|
|
790
|
+
.react-flow__node-output.selected,
|
|
791
|
+
.react-flow__node-output:focus,
|
|
792
|
+
.react-flow__node-output:focus-visible,
|
|
793
|
+
.react-flow__node-group.selected,
|
|
794
|
+
.react-flow__node-group:focus,
|
|
795
|
+
.react-flow__node-group:focus-visible {
|
|
796
|
+
outline: none;
|
|
797
|
+
border: var(--xy-node-border-selected, var(--xy-node-border-selected-default));
|
|
798
|
+
}
|
|
799
|
+
.react-flow__nodesselection-rect,
|
|
800
|
+
.react-flow__selection {
|
|
801
|
+
background: var(--xy-selection-background-color, var(--xy-selection-background-color-default));
|
|
802
|
+
border: var(--xy-selection-border, var(--xy-selection-border-default));
|
|
803
|
+
}
|
|
804
|
+
.react-flow__resize-control {
|
|
805
|
+
position: absolute;
|
|
806
|
+
}
|
|
807
|
+
.react-flow__resize-control.left,
|
|
808
|
+
.react-flow__resize-control.right {
|
|
809
|
+
cursor: ew-resize;
|
|
810
|
+
}
|
|
811
|
+
.react-flow__resize-control.top,
|
|
812
|
+
.react-flow__resize-control.bottom {
|
|
813
|
+
cursor: ns-resize;
|
|
814
|
+
}
|
|
815
|
+
.react-flow__resize-control.top.left,
|
|
816
|
+
.react-flow__resize-control.bottom.right {
|
|
817
|
+
cursor: nwse-resize;
|
|
818
|
+
}
|
|
819
|
+
.react-flow__resize-control.bottom.left,
|
|
820
|
+
.react-flow__resize-control.top.right {
|
|
821
|
+
cursor: nesw-resize;
|
|
822
|
+
}
|
|
823
|
+
/* handle styles */
|
|
824
|
+
.react-flow__resize-control.handle {
|
|
825
|
+
width: 5px;
|
|
826
|
+
height: 5px;
|
|
827
|
+
border: 1px solid #fff;
|
|
828
|
+
border-radius: 1px;
|
|
829
|
+
background-color: var(--xy-resize-background-color, var(--xy-resize-background-color-default));
|
|
830
|
+
translate: -50% -50%;
|
|
831
|
+
}
|
|
832
|
+
.react-flow__resize-control.handle.left {
|
|
833
|
+
left: 0;
|
|
834
|
+
top: 50%;
|
|
835
|
+
}
|
|
836
|
+
.react-flow__resize-control.handle.right {
|
|
837
|
+
left: 100%;
|
|
838
|
+
top: 50%;
|
|
839
|
+
}
|
|
840
|
+
.react-flow__resize-control.handle.top {
|
|
841
|
+
left: 50%;
|
|
842
|
+
top: 0;
|
|
843
|
+
}
|
|
844
|
+
.react-flow__resize-control.handle.bottom {
|
|
845
|
+
left: 50%;
|
|
846
|
+
top: 100%;
|
|
847
|
+
}
|
|
848
|
+
.react-flow__resize-control.handle.top.left {
|
|
849
|
+
left: 0;
|
|
850
|
+
}
|
|
851
|
+
.react-flow__resize-control.handle.bottom.left {
|
|
852
|
+
left: 0;
|
|
853
|
+
}
|
|
854
|
+
.react-flow__resize-control.handle.top.right {
|
|
855
|
+
left: 100%;
|
|
856
|
+
}
|
|
857
|
+
.react-flow__resize-control.handle.bottom.right {
|
|
858
|
+
left: 100%;
|
|
859
|
+
}
|
|
860
|
+
/* line styles */
|
|
861
|
+
.react-flow__resize-control.line {
|
|
862
|
+
border-color: var(--xy-resize-background-color, var(--xy-resize-background-color-default));
|
|
863
|
+
border-width: 0;
|
|
864
|
+
border-style: solid;
|
|
865
|
+
}
|
|
866
|
+
.react-flow__resize-control.line.left,
|
|
867
|
+
.react-flow__resize-control.line.right {
|
|
868
|
+
width: 1px;
|
|
869
|
+
transform: translate(-50%, 0);
|
|
870
|
+
top: 0;
|
|
871
|
+
height: 100%;
|
|
872
|
+
}
|
|
873
|
+
.react-flow__resize-control.line.left {
|
|
874
|
+
left: 0;
|
|
875
|
+
border-left-width: 1px;
|
|
876
|
+
}
|
|
877
|
+
.react-flow__resize-control.line.right {
|
|
878
|
+
left: 100%;
|
|
879
|
+
border-right-width: 1px;
|
|
880
|
+
}
|
|
881
|
+
.react-flow__resize-control.line.top,
|
|
882
|
+
.react-flow__resize-control.line.bottom {
|
|
883
|
+
height: 1px;
|
|
884
|
+
transform: translate(0, -50%);
|
|
885
|
+
left: 0;
|
|
886
|
+
width: 100%;
|
|
887
|
+
}
|
|
888
|
+
.react-flow__resize-control.line.top {
|
|
889
|
+
top: 0;
|
|
890
|
+
border-top-width: 1px;
|
|
891
|
+
}
|
|
892
|
+
.react-flow__resize-control.line.bottom {
|
|
893
|
+
border-bottom-width: 1px;
|
|
894
|
+
top: 100%;
|
|
895
|
+
}
|
|
896
|
+
|
|
366
897
|
/* foundation/layout.css */
|
|
367
898
|
.cb-flex { display: flex; gap: var(--cb-flex-gap); }
|
|
368
899
|
.cb-flex--column { flex-direction: column; }
|
|
@@ -829,6 +1360,201 @@ html, body { background: var(--cb-bg); color: var(--cb-fg); }
|
|
|
829
1360
|
line-height: var(--cb-leading-normal);
|
|
830
1361
|
}
|
|
831
1362
|
|
|
1363
|
+
/* data/diagram/diagram.css */
|
|
1364
|
+
/* Diagram and DiagramEditor run on React Flow. Its base stylesheet (bundled before this file) owns layout and
|
|
1365
|
+
reads its colours from `--xy-*` custom properties; here those are pointed at Tokens, and the node React
|
|
1366
|
+
Flow wraps is drawn by this library. */
|
|
1367
|
+
|
|
1368
|
+
.cb-diagram {
|
|
1369
|
+
--cb-diagram-cell: var(--cb-space-5);
|
|
1370
|
+
min-inline-size: 0;
|
|
1371
|
+
position: relative;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
.cb-diagram__cell {
|
|
1375
|
+
inline-size: var(--cb-diagram-cell);
|
|
1376
|
+
pointer-events: none;
|
|
1377
|
+
position: absolute;
|
|
1378
|
+
visibility: hidden;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
.cb-diagram__hint {
|
|
1382
|
+
color: var(--cb-fg-muted);
|
|
1383
|
+
font-size: var(--cb-text-xs);
|
|
1384
|
+
margin: 0 0 var(--cb-space-2);
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
.cb-diagram__viewport {
|
|
1388
|
+
background: var(--cb-surface);
|
|
1389
|
+
block-size: var(--cb-canvas-block-size);
|
|
1390
|
+
border: var(--cb-border-width) solid var(--cb-border);
|
|
1391
|
+
border-radius: var(--cb-radius-lg);
|
|
1392
|
+
overflow: hidden;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
.cb-diagram .react-flow {
|
|
1396
|
+
--xy-background-color: var(--cb-surface);
|
|
1397
|
+
--xy-background-pattern-color: var(--cb-border);
|
|
1398
|
+
--xy-edge-stroke: var(--cb-border-strong);
|
|
1399
|
+
--xy-edge-stroke-selected: var(--cb-tone-brand);
|
|
1400
|
+
--xy-edge-stroke-width: var(--cb-border-width);
|
|
1401
|
+
--xy-connectionline-stroke: var(--cb-tone-info);
|
|
1402
|
+
--xy-connectionline-stroke-width: var(--cb-border-width);
|
|
1403
|
+
--xy-handle-background-color: var(--cb-surface);
|
|
1404
|
+
--xy-handle-border-color: var(--cb-border-strong);
|
|
1405
|
+
--xy-attribution-background-color: transparent;
|
|
1406
|
+
--xy-controls-button-background-color: var(--cb-surface);
|
|
1407
|
+
--xy-controls-button-background-color-hover: var(--cb-bg-subtle);
|
|
1408
|
+
--xy-controls-button-color: var(--cb-fg);
|
|
1409
|
+
--xy-controls-button-color-hover: var(--cb-fg);
|
|
1410
|
+
--xy-controls-button-border-color: var(--cb-border);
|
|
1411
|
+
--xy-controls-box-shadow: none;
|
|
1412
|
+
--xy-edge-label-background-color: var(--cb-surface);
|
|
1413
|
+
--xy-edge-label-color: var(--cb-fg-muted);
|
|
1414
|
+
color: var(--cb-fg);
|
|
1415
|
+
font-family: inherit;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
.cb-diagram .react-flow__edge-text {
|
|
1419
|
+
fill: var(--cb-fg-muted);
|
|
1420
|
+
font-size: var(--cb-text-xs);
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
.cb-diagram .react-flow__edge-textbg { fill: var(--cb-surface); }
|
|
1424
|
+
|
|
1425
|
+
.cb-diagram .cb-diagram__edge--neutral .react-flow__edge-path { stroke: var(--cb-tone-neutral); }
|
|
1426
|
+
.cb-diagram .cb-diagram__edge--brand .react-flow__edge-path { stroke: var(--cb-tone-brand); }
|
|
1427
|
+
.cb-diagram .cb-diagram__edge--info .react-flow__edge-path { stroke: var(--cb-tone-info); }
|
|
1428
|
+
.cb-diagram .cb-diagram__edge--success .react-flow__edge-path { stroke: var(--cb-tone-success); }
|
|
1429
|
+
.cb-diagram .cb-diagram__edge--warning .react-flow__edge-path { stroke: var(--cb-tone-warning); }
|
|
1430
|
+
.cb-diagram .cb-diagram__edge--danger .react-flow__edge-path { stroke: var(--cb-tone-danger); }
|
|
1431
|
+
|
|
1432
|
+
.cb-diagram .react-flow__node:focus-visible,
|
|
1433
|
+
.cb-diagram .react-flow__edge:focus-visible {
|
|
1434
|
+
outline: var(--cb-focus-width) solid var(--cb-focus);
|
|
1435
|
+
outline-offset: var(--cb-focus-offset);
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
.cb-diagram__node {
|
|
1439
|
+
align-items: center;
|
|
1440
|
+
background: var(--cb-surface);
|
|
1441
|
+
block-size: calc(var(--cb-diagram-cell) * 3);
|
|
1442
|
+
border: var(--cb-border-width) solid var(--cb-border-strong);
|
|
1443
|
+
border-radius: var(--cb-radius-md);
|
|
1444
|
+
box-sizing: border-box;
|
|
1445
|
+
color: var(--cb-fg);
|
|
1446
|
+
display: flex;
|
|
1447
|
+
flex-direction: column;
|
|
1448
|
+
font-size: var(--cb-text-sm);
|
|
1449
|
+
gap: var(--cb-space-1);
|
|
1450
|
+
inline-size: calc(var(--cb-diagram-cell) * 8);
|
|
1451
|
+
isolation: isolate;
|
|
1452
|
+
justify-content: center;
|
|
1453
|
+
padding: var(--cb-space-1) var(--cb-space-2);
|
|
1454
|
+
position: relative;
|
|
1455
|
+
text-align: center;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
.cb-diagram--editor .cb-diagram__node { cursor: grab; }
|
|
1459
|
+
|
|
1460
|
+
.cb-diagram__node[data-shape="pill"] { border-radius: var(--cb-radius-full); }
|
|
1461
|
+
|
|
1462
|
+
/* A diamond's box is square, so the handles React Flow places at the middle of each side sit exactly on the
|
|
1463
|
+
diamond's tips and arrows meet the drawn outline. The rotated square's diagonal equals the box's side. */
|
|
1464
|
+
.cb-diagram__node[data-shape="diamond"] {
|
|
1465
|
+
background: transparent;
|
|
1466
|
+
block-size: calc(var(--cb-diagram-cell) * 4);
|
|
1467
|
+
border-color: transparent;
|
|
1468
|
+
inline-size: calc(var(--cb-diagram-cell) * 4);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
.cb-diagram__node[data-shape="diamond"]::before {
|
|
1472
|
+
aspect-ratio: 1;
|
|
1473
|
+
background: var(--cb-surface);
|
|
1474
|
+
block-size: 70.7%;
|
|
1475
|
+
border: var(--cb-border-width) solid var(--cb-border-strong);
|
|
1476
|
+
content: "";
|
|
1477
|
+
inset: 0;
|
|
1478
|
+
margin: auto;
|
|
1479
|
+
position: absolute;
|
|
1480
|
+
rotate: 45deg;
|
|
1481
|
+
z-index: -1;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
.cb-diagram__node[data-tone="neutral"],
|
|
1485
|
+
.cb-diagram__node[data-tone="neutral"]::before { border-color: var(--cb-tone-neutral); }
|
|
1486
|
+
.cb-diagram__node[data-tone="brand"],
|
|
1487
|
+
.cb-diagram__node[data-tone="brand"]::before { border-color: var(--cb-tone-brand); }
|
|
1488
|
+
.cb-diagram__node[data-tone="info"],
|
|
1489
|
+
.cb-diagram__node[data-tone="info"]::before { border-color: var(--cb-tone-info); }
|
|
1490
|
+
.cb-diagram__node[data-tone="success"],
|
|
1491
|
+
.cb-diagram__node[data-tone="success"]::before { border-color: var(--cb-tone-success); }
|
|
1492
|
+
.cb-diagram__node[data-tone="warning"],
|
|
1493
|
+
.cb-diagram__node[data-tone="warning"]::before { border-color: var(--cb-tone-warning); }
|
|
1494
|
+
.cb-diagram__node[data-tone="danger"],
|
|
1495
|
+
.cb-diagram__node[data-tone="danger"]::before { border-color: var(--cb-tone-danger); }
|
|
1496
|
+
|
|
1497
|
+
.cb-diagram__node[data-shape="diamond"][data-tone] { border-color: transparent; }
|
|
1498
|
+
|
|
1499
|
+
.cb-diagram__node[data-selected="true"],
|
|
1500
|
+
.cb-diagram__node[data-selected="true"]::before {
|
|
1501
|
+
border-color: var(--cb-tone-brand);
|
|
1502
|
+
box-shadow: 0 0 0 var(--cb-border-width) var(--cb-tone-brand);
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
.cb-diagram__node[data-shape="diamond"][data-selected="true"] { box-shadow: none; }
|
|
1506
|
+
|
|
1507
|
+
.cb-diagram__node[data-connecting="true"],
|
|
1508
|
+
.cb-diagram__node[data-connecting="true"]::before {
|
|
1509
|
+
border-color: var(--cb-tone-info);
|
|
1510
|
+
border-style: dashed;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
.cb-diagram__label {
|
|
1514
|
+
max-inline-size: 100%;
|
|
1515
|
+
overflow: hidden;
|
|
1516
|
+
text-overflow: ellipsis;
|
|
1517
|
+
white-space: nowrap;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
.cb-diagram .cb-diagram__handle {
|
|
1521
|
+
background: var(--cb-surface);
|
|
1522
|
+
block-size: var(--cb-space-3);
|
|
1523
|
+
border: var(--cb-border-width) solid var(--cb-border-strong);
|
|
1524
|
+
inline-size: var(--cb-space-3);
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
.cb-diagram:not(.cb-diagram--editor) .cb-diagram__handle { visibility: hidden; }
|
|
1528
|
+
|
|
1529
|
+
/* Where a pointer can hover, handles appear with the node's hover or focus; on touch there is no hover, so
|
|
1530
|
+
they stay visible to tap. */
|
|
1531
|
+
@media (hover: hover) {
|
|
1532
|
+
.cb-diagram--editor .react-flow__node:not(:hover, :focus-within, .selected) .cb-diagram__handle { opacity: 0; }
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
.cb-diagram .react-flow__controls-button svg { fill: currentColor; }
|
|
1536
|
+
|
|
1537
|
+
.cb-diagram .react-flow__attribution { font-size: var(--cb-text-xs); }
|
|
1538
|
+
|
|
1539
|
+
.cb-diagram__outline,
|
|
1540
|
+
.cb-diagram__status {
|
|
1541
|
+
block-size: var(--cb-border-width);
|
|
1542
|
+
clip-path: inset(50%);
|
|
1543
|
+
inline-size: var(--cb-border-width);
|
|
1544
|
+
margin: 0;
|
|
1545
|
+
overflow: hidden;
|
|
1546
|
+
padding: 0;
|
|
1547
|
+
position: absolute;
|
|
1548
|
+
white-space: nowrap;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
@media (forced-colors: active) {
|
|
1552
|
+
.cb-diagram__node,
|
|
1553
|
+
.cb-diagram__node::before,
|
|
1554
|
+
.cb-diagram .cb-diagram__handle { border-color: CanvasText; }
|
|
1555
|
+
.cb-diagram .react-flow__edge-path { stroke: CanvasText; }
|
|
1556
|
+
}
|
|
1557
|
+
|
|
832
1558
|
/* data/donut.css */
|
|
833
1559
|
.cb-donut { position: relative; display: inline-grid; place-items: center; }
|
|
834
1560
|
.cb-donut svg { position: absolute; inset: 0; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ceebee/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Ceebee's design system: tokens, themed primitives, motion, and onboarding.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@ant-design/cssinjs": "2.1.2",
|
|
58
|
+
"@xyflow/react": "12.11.6",
|
|
58
59
|
"antd": "6.6.1",
|
|
59
60
|
"dayjs": "1.11.18"
|
|
60
61
|
},
|