@ceebee/ui 1.5.4 → 1.7.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 +95 -2
- package/dist/client.js +345 -7
- package/dist/index.js +2 -2
- package/dist/skins/moodboard.css +21 -0
- package/dist/styles.css +715 -0
- 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. */
|
|
@@ -367,11 +368,103 @@ interface PanZoomCanvasProps {
|
|
|
367
368
|
zoomOutLabel?: string;
|
|
368
369
|
resetLabel?: string;
|
|
369
370
|
zoomStatusLabel?: string;
|
|
371
|
+
fullscreenLabel?: string;
|
|
372
|
+
exitFullscreenLabel?: string;
|
|
370
373
|
motion?: boolean;
|
|
371
374
|
}
|
|
372
|
-
declare function PanZoomCanvasRoot({ label, children, hint, zoomInLabel, zoomOutLabel, resetLabel, zoomStatusLabel, motion: motionEnabled, }: PanZoomCanvasProps): react.JSX.Element;
|
|
375
|
+
declare function PanZoomCanvasRoot({ label, children, hint, zoomInLabel, zoomOutLabel, resetLabel, zoomStatusLabel, fullscreenLabel, exitFullscreenLabel, motion: motionEnabled, }: PanZoomCanvasProps): react.JSX.Element;
|
|
373
376
|
declare const PanZoomCanvas: typeof PanZoomCanvasRoot & {
|
|
374
377
|
Skeleton: typeof PanZoomCanvasSkeleton;
|
|
375
378
|
};
|
|
376
379
|
|
|
377
|
-
|
|
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,
|
|
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';
|
|
@@ -9,10 +9,11 @@ export { default as enUSDatePickerLocale } from 'antd/lib/date-picker/locale/en_
|
|
|
9
9
|
export { default as idIDLocale } from 'antd/locale/id_ID.js';
|
|
10
10
|
export { default as zhCNLocale } from 'antd/locale/zh_CN.js';
|
|
11
11
|
import { Dialog } from '@base-ui/react/dialog';
|
|
12
|
-
import { X, Minus, Plus, RotateCcw, Search, Check, ChevronRight, PanelLeftOpen, PanelLeftClose, Info, XCircle, AlertTriangle, CheckCircle2 } from 'lucide-react';
|
|
12
|
+
import { X, Minus, Plus, RotateCcw, Minimize2, Maximize2, Search, Check, ChevronRight, PanelLeftOpen, PanelLeftClose, Info, XCircle, AlertTriangle, CheckCircle2 } from 'lucide-react';
|
|
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,
|
|
@@ -1517,9 +1518,14 @@ function PanZoomCanvasRoot({
|
|
|
1517
1518
|
zoomOutLabel = "Zoom out",
|
|
1518
1519
|
resetLabel = "Reset canvas",
|
|
1519
1520
|
zoomStatusLabel = "Canvas zoom",
|
|
1521
|
+
fullscreenLabel = "Enter fullscreen",
|
|
1522
|
+
exitFullscreenLabel = "Exit fullscreen",
|
|
1520
1523
|
motion: motionEnabled = true
|
|
1521
1524
|
}) {
|
|
1522
1525
|
const motionSettings = useMotionSettings();
|
|
1526
|
+
const rootRef = useRef(null);
|
|
1527
|
+
const [fullscreenAvailable, setFullscreenAvailable] = useState(false);
|
|
1528
|
+
const [fullscreen, setFullscreen] = useState(false);
|
|
1523
1529
|
const [pan, setPan] = useState({ x: 0, y: 0 });
|
|
1524
1530
|
const [scale, setScale] = useState(1);
|
|
1525
1531
|
const pointers = useRef(/* @__PURE__ */ new Map());
|
|
@@ -1527,6 +1533,21 @@ function PanZoomCanvasRoot({
|
|
|
1527
1533
|
const pinchOrigin = useRef(null);
|
|
1528
1534
|
const stepRef = useRef(null);
|
|
1529
1535
|
const shouldAnimate = motionEnabled && motionSettings.enabled;
|
|
1536
|
+
useEffect(() => {
|
|
1537
|
+
setFullscreenAvailable(typeof document !== "undefined" && document.fullscreenEnabled === true && typeof rootRef.current?.requestFullscreen === "function");
|
|
1538
|
+
function onChange() {
|
|
1539
|
+
setFullscreen(document.fullscreenElement === rootRef.current);
|
|
1540
|
+
}
|
|
1541
|
+
document.addEventListener("fullscreenchange", onChange);
|
|
1542
|
+
return () => document.removeEventListener("fullscreenchange", onChange);
|
|
1543
|
+
}, []);
|
|
1544
|
+
function toggleFullscreen() {
|
|
1545
|
+
if (document.fullscreenElement === rootRef.current) {
|
|
1546
|
+
void document.exitFullscreen();
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
void rootRef.current?.requestFullscreen();
|
|
1550
|
+
}
|
|
1530
1551
|
function reset() {
|
|
1531
1552
|
setPan({ x: 0, y: 0 });
|
|
1532
1553
|
setScale(1);
|
|
@@ -1600,7 +1621,7 @@ function PanZoomCanvasRoot({
|
|
|
1600
1621
|
"--cb-pan-zoom-y": pan.y,
|
|
1601
1622
|
"--cb-pan-zoom-scale": scale
|
|
1602
1623
|
};
|
|
1603
|
-
return /* @__PURE__ */ jsxs("section", { className: "cb-pan-zoom-canvas", "data-motion": String(shouldAnimate), children: [
|
|
1624
|
+
return /* @__PURE__ */ jsxs("section", { ref: rootRef, className: "cb-pan-zoom-canvas", "data-motion": String(shouldAnimate), "data-fullscreen": String(fullscreen), children: [
|
|
1604
1625
|
/* @__PURE__ */ jsxs("div", { className: "cb-pan-zoom-canvas__toolbar", children: [
|
|
1605
1626
|
hint ? /* @__PURE__ */ jsx("p", { className: "cb-pan-zoom-canvas__hint", children: hint }) : /* @__PURE__ */ jsx("span", {}),
|
|
1606
1627
|
/* @__PURE__ */ jsxs("div", { className: "cb-pan-zoom-canvas__controls", children: [
|
|
@@ -1610,7 +1631,18 @@ function PanZoomCanvasRoot({
|
|
|
1610
1631
|
"%"
|
|
1611
1632
|
] }),
|
|
1612
1633
|
/* @__PURE__ */ jsx(Button, { type: "text", size: "small", icon: /* @__PURE__ */ jsx(Plus, { "aria-hidden": "true" }), "aria-label": zoomInLabel, onClick: () => zoom(SCALE_STEP), disabled: scale >= MAX_SCALE }),
|
|
1613
|
-
/* @__PURE__ */ jsx(Button, { type: "text", size: "small", icon: /* @__PURE__ */ jsx(RotateCcw, { "aria-hidden": "true" }), "aria-label": resetLabel, onClick: reset })
|
|
1634
|
+
/* @__PURE__ */ jsx(Button, { type: "text", size: "small", icon: /* @__PURE__ */ jsx(RotateCcw, { "aria-hidden": "true" }), "aria-label": resetLabel, onClick: reset }),
|
|
1635
|
+
fullscreenAvailable ? /* @__PURE__ */ jsx(
|
|
1636
|
+
Button,
|
|
1637
|
+
{
|
|
1638
|
+
type: "text",
|
|
1639
|
+
size: "small",
|
|
1640
|
+
icon: fullscreen ? /* @__PURE__ */ jsx(Minimize2, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Maximize2, { "aria-hidden": "true" }),
|
|
1641
|
+
"aria-label": fullscreen ? exitFullscreenLabel : fullscreenLabel,
|
|
1642
|
+
"aria-pressed": fullscreen,
|
|
1643
|
+
onClick: toggleFullscreen
|
|
1644
|
+
}
|
|
1645
|
+
) : null
|
|
1614
1646
|
] })
|
|
1615
1647
|
] }),
|
|
1616
1648
|
/* @__PURE__ */ jsxs(
|
|
@@ -1637,5 +1669,311 @@ function PanZoomCanvasRoot({
|
|
|
1637
1669
|
] });
|
|
1638
1670
|
}
|
|
1639
1671
|
var PanZoomCanvas = Object.assign(PanZoomCanvasRoot, { Skeleton: PanZoomCanvasSkeleton });
|
|
1672
|
+
function DiagramNodeView({ data, selected }) {
|
|
1673
|
+
return /* @__PURE__ */ jsxs(
|
|
1674
|
+
"div",
|
|
1675
|
+
{
|
|
1676
|
+
className: "cb-diagram__node",
|
|
1677
|
+
"data-shape": data.shape,
|
|
1678
|
+
"data-tone": data.tone,
|
|
1679
|
+
"data-selected": String(Boolean(selected)),
|
|
1680
|
+
"data-connecting": String(data.connecting),
|
|
1681
|
+
children: [
|
|
1682
|
+
/* @__PURE__ */ jsx(Handle, { id: "left", type: "target", position: Position.Left, className: "cb-diagram__handle", isConnectable: data.connectable }),
|
|
1683
|
+
/* @__PURE__ */ jsx(Handle, { id: "top", type: "target", position: Position.Top, className: "cb-diagram__handle", isConnectable: data.connectable }),
|
|
1684
|
+
/* @__PURE__ */ jsx("span", { className: "cb-diagram__label", children: data.label }),
|
|
1685
|
+
data.content,
|
|
1686
|
+
/* @__PURE__ */ jsx(Handle, { id: "right", type: "source", position: Position.Right, className: "cb-diagram__handle", isConnectable: data.connectable }),
|
|
1687
|
+
/* @__PURE__ */ jsx(Handle, { id: "bottom", type: "source", position: Position.Bottom, className: "cb-diagram__handle", isConnectable: data.connectable })
|
|
1688
|
+
]
|
|
1689
|
+
}
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
var FLOW_NODE_TYPE = "cb-diagram";
|
|
1693
|
+
var FALLBACK_CELL = 20;
|
|
1694
|
+
function cellSize(measured) {
|
|
1695
|
+
return measured !== void 0 && measured > 0 ? measured : FALLBACK_CELL;
|
|
1696
|
+
}
|
|
1697
|
+
function toCells(position, cell) {
|
|
1698
|
+
return { x: Math.round(position.x / cell), y: Math.round(position.y / cell) };
|
|
1699
|
+
}
|
|
1700
|
+
function toFlowNodes(nodes, cell, state) {
|
|
1701
|
+
return nodes.map((node) => ({
|
|
1702
|
+
id: node.id,
|
|
1703
|
+
type: FLOW_NODE_TYPE,
|
|
1704
|
+
position: { x: node.position.x * cell, y: node.position.y * cell },
|
|
1705
|
+
selected: state.selectedId === node.id,
|
|
1706
|
+
data: {
|
|
1707
|
+
label: node.label,
|
|
1708
|
+
content: node.content,
|
|
1709
|
+
shape: node.shape ?? "rect",
|
|
1710
|
+
tone: node.tone,
|
|
1711
|
+
connecting: state.connectingFrom === node.id,
|
|
1712
|
+
connectable: state.connectable
|
|
1713
|
+
}
|
|
1714
|
+
}));
|
|
1715
|
+
}
|
|
1716
|
+
function centreOf(node) {
|
|
1717
|
+
const [columns, rows] = node.shape === "diamond" ? [4, 4] : [8, 3];
|
|
1718
|
+
return { x: node.position.x + columns / 2, y: node.position.y + rows / 2 };
|
|
1719
|
+
}
|
|
1720
|
+
function edgeHandles(from, to) {
|
|
1721
|
+
const a = centreOf(from);
|
|
1722
|
+
const b = centreOf(to);
|
|
1723
|
+
const dx = b.x - a.x;
|
|
1724
|
+
const dy = b.y - a.y;
|
|
1725
|
+
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
1726
|
+
return dx >= 0 ? { sourceHandle: "right", targetHandle: "left" } : { sourceHandle: "left", targetHandle: "right" };
|
|
1727
|
+
}
|
|
1728
|
+
return dy >= 0 ? { sourceHandle: "bottom", targetHandle: "top" } : { sourceHandle: "top", targetHandle: "bottom" };
|
|
1729
|
+
}
|
|
1730
|
+
function toFlowEdges(edges, nodes) {
|
|
1731
|
+
const byId = new Map(nodes.map((node) => [node.id, node]));
|
|
1732
|
+
return edges.flatMap((edge) => {
|
|
1733
|
+
const from = byId.get(edge.from);
|
|
1734
|
+
const to = byId.get(edge.to);
|
|
1735
|
+
if (!from || !to) return [];
|
|
1736
|
+
return [
|
|
1737
|
+
{
|
|
1738
|
+
id: edge.id,
|
|
1739
|
+
source: edge.from,
|
|
1740
|
+
target: edge.to,
|
|
1741
|
+
...edgeHandles(from, to),
|
|
1742
|
+
label: edge.label,
|
|
1743
|
+
className: edge.tone ? `cb-diagram__edge cb-diagram__edge--${edge.tone}` : "cb-diagram__edge",
|
|
1744
|
+
markerEnd: { type: MarkerType.ArrowClosed }
|
|
1745
|
+
}
|
|
1746
|
+
];
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1749
|
+
function settledMoves(changes, cell) {
|
|
1750
|
+
return changes.flatMap(
|
|
1751
|
+
(change) => change.type === "position" && change.position && change.dragging !== true ? [{ id: change.id, position: toCells(change.position, cell) }] : []
|
|
1752
|
+
);
|
|
1753
|
+
}
|
|
1754
|
+
function changedMoves(moves, nodes) {
|
|
1755
|
+
return moves.filter((move) => {
|
|
1756
|
+
const current = nodes.find((node) => node.id === move.id)?.position;
|
|
1757
|
+
return !current || current.x !== move.position.x || current.y !== move.position.y;
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
function mergeFlowNodes(current, next) {
|
|
1761
|
+
const byId = new Map(current.map((node) => [node.id, node]));
|
|
1762
|
+
let changed = current.length !== next.length;
|
|
1763
|
+
const merged = next.map((node, index) => {
|
|
1764
|
+
const previous = byId.get(node.id);
|
|
1765
|
+
if (!previous) {
|
|
1766
|
+
changed = true;
|
|
1767
|
+
return node;
|
|
1768
|
+
}
|
|
1769
|
+
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;
|
|
1770
|
+
if (same) return previous;
|
|
1771
|
+
changed = true;
|
|
1772
|
+
return { ...node, selected: previous.selected, measured: previous.measured };
|
|
1773
|
+
});
|
|
1774
|
+
return changed ? merged : current;
|
|
1775
|
+
}
|
|
1776
|
+
function keepIfUnchanged(current, next) {
|
|
1777
|
+
return next.length === current.length && next.every((item, index) => item === current[index]) ? current : next;
|
|
1778
|
+
}
|
|
1779
|
+
function applySelection(current, selectedId) {
|
|
1780
|
+
let changed = false;
|
|
1781
|
+
const next = current.map((node) => {
|
|
1782
|
+
const selected = node.id === selectedId;
|
|
1783
|
+
if (Boolean(node.selected) === selected) return node;
|
|
1784
|
+
changed = true;
|
|
1785
|
+
return { ...node, selected };
|
|
1786
|
+
});
|
|
1787
|
+
return changed ? next : current;
|
|
1788
|
+
}
|
|
1789
|
+
function connectStep(state, event) {
|
|
1790
|
+
if (event.type === "cancel") return { state: { mode: "idle" } };
|
|
1791
|
+
if (event.type === "start" || state.mode === "idle") return { state: { mode: "connecting", from: event.nodeId } };
|
|
1792
|
+
if (event.nodeId === state.from) return { state: { mode: "idle" } };
|
|
1793
|
+
return { state: { mode: "idle" }, connect: { from: state.from, to: event.nodeId } };
|
|
1794
|
+
}
|
|
1795
|
+
var NODE_TYPES = { [FLOW_NODE_TYPE]: DiagramNodeView };
|
|
1796
|
+
function useCellSize(ref) {
|
|
1797
|
+
const [cell, setCell] = useState(FALLBACK_CELL);
|
|
1798
|
+
useEffect(() => {
|
|
1799
|
+
setCell(cellSize(ref.current?.getBoundingClientRect().width));
|
|
1800
|
+
}, [ref]);
|
|
1801
|
+
return cell;
|
|
1802
|
+
}
|
|
1803
|
+
function DiagramOutline({
|
|
1804
|
+
id,
|
|
1805
|
+
nodes,
|
|
1806
|
+
edges,
|
|
1807
|
+
label
|
|
1808
|
+
}) {
|
|
1809
|
+
const byId = new Map(nodes.map((n) => [n.id, n]));
|
|
1810
|
+
return /* @__PURE__ */ jsx("ul", { id, className: "cb-diagram__outline", "aria-label": label, children: nodes.map((node) => {
|
|
1811
|
+
const leaving = edges.filter((e) => e.from === node.id && byId.has(e.to));
|
|
1812
|
+
return /* @__PURE__ */ jsxs("li", { children: [
|
|
1813
|
+
node.label,
|
|
1814
|
+
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
|
|
1815
|
+
] }, node.id);
|
|
1816
|
+
}) });
|
|
1817
|
+
}
|
|
1818
|
+
function safeId(id) {
|
|
1819
|
+
return id.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
1820
|
+
}
|
|
1821
|
+
function DiagramSkeleton({ label = "Loading diagram" }) {
|
|
1822
|
+
return /* @__PURE__ */ jsx(PanZoomCanvasSkeleton, { label });
|
|
1823
|
+
}
|
|
1824
|
+
function DiagramRoot({ label, nodes, edges, hint, outlineLabel = "Diagram outline", ariaLabels }) {
|
|
1825
|
+
const base = safeId(useId());
|
|
1826
|
+
const cellRef = useRef(null);
|
|
1827
|
+
const cell = useCellSize(cellRef);
|
|
1828
|
+
const flowNodes = useMemo(() => toFlowNodes(nodes, cell, { connectable: false }), [nodes, cell]);
|
|
1829
|
+
const flowEdges = useMemo(() => toFlowEdges(edges, nodes), [edges, nodes]);
|
|
1830
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-diagram", children: [
|
|
1831
|
+
/* @__PURE__ */ jsx("span", { ref: cellRef, className: "cb-diagram__cell", "aria-hidden": "true" }),
|
|
1832
|
+
hint ? /* @__PURE__ */ jsx("p", { className: "cb-diagram__hint", children: hint }) : null,
|
|
1833
|
+
/* @__PURE__ */ jsx("div", { className: "cb-diagram__viewport", role: "region", "aria-label": label, "aria-describedby": `${base}-outline`, children: /* @__PURE__ */ jsxs(
|
|
1834
|
+
ReactFlow,
|
|
1835
|
+
{
|
|
1836
|
+
nodes: flowNodes,
|
|
1837
|
+
edges: flowEdges,
|
|
1838
|
+
nodeTypes: NODE_TYPES,
|
|
1839
|
+
connectionMode: ConnectionMode.Loose,
|
|
1840
|
+
nodesDraggable: false,
|
|
1841
|
+
nodesConnectable: false,
|
|
1842
|
+
elementsSelectable: false,
|
|
1843
|
+
nodesFocusable: false,
|
|
1844
|
+
edgesFocusable: false,
|
|
1845
|
+
fitView: true,
|
|
1846
|
+
minZoom: 0.5,
|
|
1847
|
+
maxZoom: 2,
|
|
1848
|
+
ariaLabelConfig: ariaLabels,
|
|
1849
|
+
children: [
|
|
1850
|
+
/* @__PURE__ */ jsx(Background, { gap: cell }),
|
|
1851
|
+
/* @__PURE__ */ jsx(Controls, { showInteractive: false })
|
|
1852
|
+
]
|
|
1853
|
+
}
|
|
1854
|
+
) }),
|
|
1855
|
+
/* @__PURE__ */ jsx(DiagramOutline, { id: `${base}-outline`, nodes, edges, label: outlineLabel })
|
|
1856
|
+
] });
|
|
1857
|
+
}
|
|
1858
|
+
var Diagram = Object.assign(DiagramRoot, { Skeleton: DiagramSkeleton });
|
|
1859
|
+
var CONNECT_KEY = "c";
|
|
1860
|
+
var DELETE_KEYS = ["Delete", "Backspace"];
|
|
1861
|
+
var defaultConnectingStatus = (node) => `Connecting from ${node}. Focus another node and press C, or press Escape to cancel.`;
|
|
1862
|
+
function elementAt(target) {
|
|
1863
|
+
if (!(target instanceof Element)) return null;
|
|
1864
|
+
const node = target.closest(".react-flow__node")?.getAttribute("data-id");
|
|
1865
|
+
if (node) return { kind: "node", id: node };
|
|
1866
|
+
const edge = target.closest(".react-flow__edge")?.getAttribute("data-id");
|
|
1867
|
+
return edge ? { kind: "edge", id: edge } : null;
|
|
1868
|
+
}
|
|
1869
|
+
function DiagramEditorRoot(props) {
|
|
1870
|
+
const { label, nodes, edges, hint, selectedId, connectingStatus = defaultConnectingStatus, outlineLabel = "Diagram outline", ariaLabels } = props;
|
|
1871
|
+
const base = safeId(useId());
|
|
1872
|
+
const cellRef = useRef(null);
|
|
1873
|
+
const cell = useCellSize(cellRef);
|
|
1874
|
+
const [connect, setConnect] = useState({ mode: "idle" });
|
|
1875
|
+
const connectingFrom = connect.mode === "connecting" ? connect.from : null;
|
|
1876
|
+
const latest = useRef({ props, cell, connect });
|
|
1877
|
+
latest.current = { props, cell, connect };
|
|
1878
|
+
const reportedSelection = useRef(selectedId ?? null);
|
|
1879
|
+
const [resync, setResync] = useState(0);
|
|
1880
|
+
const [flowNodes, setFlowNodes] = useState(() => toFlowNodes(nodes, cell, { selectedId, connectable: true }));
|
|
1881
|
+
useEffect(() => {
|
|
1882
|
+
setFlowNodes((current) => mergeFlowNodes(current, toFlowNodes(nodes, cell, { connectingFrom, connectable: true })));
|
|
1883
|
+
}, [nodes, cell, connectingFrom, resync]);
|
|
1884
|
+
useEffect(() => {
|
|
1885
|
+
if (selectedId === void 0) return;
|
|
1886
|
+
reportedSelection.current = selectedId;
|
|
1887
|
+
setFlowNodes((current) => applySelection(current, selectedId));
|
|
1888
|
+
}, [selectedId]);
|
|
1889
|
+
const flowEdges = useMemo(() => toFlowEdges(edges, nodes), [edges, nodes]);
|
|
1890
|
+
const snapGrid = useMemo(() => [cell, cell], [cell]);
|
|
1891
|
+
const step = useCallback((event) => {
|
|
1892
|
+
const { connect: state, props: current } = latest.current;
|
|
1893
|
+
const next = connectStep(state, event);
|
|
1894
|
+
setConnect(next.state);
|
|
1895
|
+
if (next.connect) current.onConnect?.(next.connect.from, next.connect.to);
|
|
1896
|
+
}, []);
|
|
1897
|
+
const onNodesChange = useCallback((changes) => {
|
|
1898
|
+
const { props: current, cell: size } = latest.current;
|
|
1899
|
+
setFlowNodes((mirror) => keepIfUnchanged(mirror, applyNodeChanges(changes.filter((change) => change.type !== "remove"), mirror)));
|
|
1900
|
+
const moves = changedMoves(settledMoves(changes, size), current.nodes);
|
|
1901
|
+
for (const move of moves) current.onMoveNode?.(move.id, move.position);
|
|
1902
|
+
if (moves.length > 0) setResync((n) => n + 1);
|
|
1903
|
+
}, []);
|
|
1904
|
+
const onConnectEdge = useCallback((connection) => {
|
|
1905
|
+
if (connection.source !== connection.target) latest.current.props.onConnect?.(connection.source, connection.target);
|
|
1906
|
+
}, []);
|
|
1907
|
+
const onBeforeDelete = useCallback(async ({ nodes: gone, edges: goneEdges }) => {
|
|
1908
|
+
latest.current.props.onRemove?.({ nodeIds: gone.map((n) => n.id), edgeIds: goneEdges.map((e) => e.id) });
|
|
1909
|
+
return false;
|
|
1910
|
+
}, []);
|
|
1911
|
+
const onSelectionChange = useCallback(({ nodes: chosen }) => {
|
|
1912
|
+
const id = chosen[0]?.id;
|
|
1913
|
+
if (!id || id === reportedSelection.current) return;
|
|
1914
|
+
reportedSelection.current = id;
|
|
1915
|
+
latest.current.props.onSelectionChange?.(id);
|
|
1916
|
+
}, []);
|
|
1917
|
+
const onNodeClick = useCallback(
|
|
1918
|
+
(_, node) => {
|
|
1919
|
+
if (latest.current.connect.mode === "connecting") step({ type: "choose", nodeId: node.id });
|
|
1920
|
+
},
|
|
1921
|
+
[step]
|
|
1922
|
+
);
|
|
1923
|
+
const onPaneClick = useCallback(() => {
|
|
1924
|
+
if (latest.current.connect.mode === "connecting") step({ type: "cancel" });
|
|
1925
|
+
}, [step]);
|
|
1926
|
+
const onKeyDown = useCallback(
|
|
1927
|
+
(event) => {
|
|
1928
|
+
const target = elementAt(event.target);
|
|
1929
|
+
if (event.key.toLowerCase() === CONNECT_KEY && target?.kind === "node" && !event.metaKey && !event.ctrlKey && !event.altKey) {
|
|
1930
|
+
event.preventDefault();
|
|
1931
|
+
step({ type: "choose", nodeId: target.id });
|
|
1932
|
+
} else if (event.key === "Escape" && latest.current.connect.mode === "connecting") {
|
|
1933
|
+
step({ type: "cancel" });
|
|
1934
|
+
} else if (event.key === "F2" && target) {
|
|
1935
|
+
event.preventDefault();
|
|
1936
|
+
latest.current.props.onRename?.(target);
|
|
1937
|
+
}
|
|
1938
|
+
},
|
|
1939
|
+
[step]
|
|
1940
|
+
);
|
|
1941
|
+
const labelOf = (id) => nodes.find((n) => n.id === id)?.label ?? "";
|
|
1942
|
+
return /* @__PURE__ */ jsxs("div", { className: "cb-diagram cb-diagram--editor", children: [
|
|
1943
|
+
/* @__PURE__ */ jsx("span", { ref: cellRef, className: "cb-diagram__cell", "aria-hidden": "true" }),
|
|
1944
|
+
hint ? /* @__PURE__ */ jsx("p", { className: "cb-diagram__hint", children: hint }) : null,
|
|
1945
|
+
/* @__PURE__ */ jsx("div", { className: "cb-diagram__viewport", role: "region", "aria-label": label, "aria-describedby": `${base}-outline`, children: /* @__PURE__ */ jsxs(
|
|
1946
|
+
ReactFlow,
|
|
1947
|
+
{
|
|
1948
|
+
nodes: flowNodes,
|
|
1949
|
+
edges: flowEdges,
|
|
1950
|
+
nodeTypes: NODE_TYPES,
|
|
1951
|
+
onNodesChange,
|
|
1952
|
+
onConnect: onConnectEdge,
|
|
1953
|
+
onBeforeDelete,
|
|
1954
|
+
onSelectionChange,
|
|
1955
|
+
onNodeClick,
|
|
1956
|
+
onPaneClick,
|
|
1957
|
+
onKeyDown,
|
|
1958
|
+
connectionMode: ConnectionMode.Loose,
|
|
1959
|
+
connectOnClick: true,
|
|
1960
|
+
snapToGrid: true,
|
|
1961
|
+
snapGrid,
|
|
1962
|
+
deleteKeyCode: DELETE_KEYS,
|
|
1963
|
+
fitView: true,
|
|
1964
|
+
minZoom: 0.5,
|
|
1965
|
+
maxZoom: 2,
|
|
1966
|
+
ariaLabelConfig: ariaLabels,
|
|
1967
|
+
children: [
|
|
1968
|
+
/* @__PURE__ */ jsx(Background, { gap: cell }),
|
|
1969
|
+
/* @__PURE__ */ jsx(Controls, { showInteractive: false })
|
|
1970
|
+
]
|
|
1971
|
+
}
|
|
1972
|
+
) }),
|
|
1973
|
+
/* @__PURE__ */ jsx("p", { className: "cb-diagram__status", role: "status", children: connectingFrom ? connectingStatus(labelOf(connectingFrom)) : "" }),
|
|
1974
|
+
/* @__PURE__ */ jsx(DiagramOutline, { id: `${base}-outline`, nodes, edges, label: outlineLabel })
|
|
1975
|
+
] });
|
|
1976
|
+
}
|
|
1977
|
+
var DiagramEditor = Object.assign(DiagramEditorRoot, { Skeleton: DiagramSkeleton });
|
|
1640
1978
|
|
|
1641
|
-
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 };
|
|
1979
|
+
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
|
@@ -363,6 +363,513 @@ html, body { background: var(--cb-bg); color: var(--cb-fg); }
|
|
|
363
363
|
--cb-skeleton-opacity-max: 1;
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
+
/* @xyflow/react/dist/base.css (MIT, see THIRD_PARTY_NOTICES.md) */
|
|
367
|
+
/* this will be exported as base.css and can be used for a basic styling */
|
|
368
|
+
/* these are the necessary styles for React/Svelte Flow, they get used by base.css and style.css */
|
|
369
|
+
.react-flow {
|
|
370
|
+
direction: ltr;
|
|
371
|
+
|
|
372
|
+
--xy-edge-stroke-default: #b1b1b7;
|
|
373
|
+
--xy-edge-stroke-width-default: 1;
|
|
374
|
+
--xy-edge-stroke-selected-default: #555;
|
|
375
|
+
|
|
376
|
+
--xy-connectionline-stroke-default: #b1b1b7;
|
|
377
|
+
--xy-connectionline-stroke-width-default: 1;
|
|
378
|
+
|
|
379
|
+
--xy-attribution-background-color-default: rgba(255, 255, 255, 0.5);
|
|
380
|
+
|
|
381
|
+
--xy-minimap-background-color-default: #fff;
|
|
382
|
+
--xy-minimap-mask-background-color-default: rgba(240, 240, 240, 0.6);
|
|
383
|
+
--xy-minimap-mask-stroke-color-default: transparent;
|
|
384
|
+
--xy-minimap-mask-stroke-width-default: 1;
|
|
385
|
+
--xy-minimap-node-background-color-default: #e2e2e2;
|
|
386
|
+
--xy-minimap-node-stroke-color-default: transparent;
|
|
387
|
+
--xy-minimap-node-stroke-width-default: 2;
|
|
388
|
+
|
|
389
|
+
--xy-background-color-default: transparent;
|
|
390
|
+
--xy-background-pattern-dots-color-default: #91919a;
|
|
391
|
+
--xy-background-pattern-lines-color-default: #eee;
|
|
392
|
+
--xy-background-pattern-cross-color-default: #e2e2e2;
|
|
393
|
+
background-color: var(--xy-background-color, var(--xy-background-color-default));
|
|
394
|
+
--xy-node-border-default: 1px solid #bbb;
|
|
395
|
+
--xy-node-border-selected-default: 1px solid #555;
|
|
396
|
+
|
|
397
|
+
--xy-handle-background-color-default: #333;
|
|
398
|
+
|
|
399
|
+
--xy-selection-background-color-default: rgba(150, 150, 180, 0.1);
|
|
400
|
+
--xy-selection-border-default: 1px dotted rgba(155, 155, 155, 0.8);
|
|
401
|
+
--xy-resize-background-color-default: #3367d9;
|
|
402
|
+
}
|
|
403
|
+
.react-flow.dark {
|
|
404
|
+
--xy-edge-stroke-default: #3e3e3e;
|
|
405
|
+
--xy-edge-stroke-width-default: 1;
|
|
406
|
+
--xy-edge-stroke-selected-default: #727272;
|
|
407
|
+
|
|
408
|
+
--xy-connectionline-stroke-default: #b1b1b7;
|
|
409
|
+
--xy-connectionline-stroke-width-default: 1;
|
|
410
|
+
|
|
411
|
+
--xy-attribution-background-color-default: rgba(150, 150, 150, 0.25);
|
|
412
|
+
|
|
413
|
+
--xy-minimap-background-color-default: #141414;
|
|
414
|
+
--xy-minimap-mask-background-color-default: rgba(60, 60, 60, 0.6);
|
|
415
|
+
--xy-minimap-mask-stroke-color-default: transparent;
|
|
416
|
+
--xy-minimap-mask-stroke-width-default: 1;
|
|
417
|
+
--xy-minimap-node-background-color-default: #2b2b2b;
|
|
418
|
+
--xy-minimap-node-stroke-color-default: transparent;
|
|
419
|
+
--xy-minimap-node-stroke-width-default: 2;
|
|
420
|
+
|
|
421
|
+
--xy-background-color-default: #141414;
|
|
422
|
+
--xy-background-pattern-dots-color-default: #555;
|
|
423
|
+
--xy-background-pattern-lines-color-default: #333;
|
|
424
|
+
--xy-background-pattern-cross-color-default: #333;
|
|
425
|
+
--xy-node-color-default: #f8f8f8;
|
|
426
|
+
}
|
|
427
|
+
.react-flow__background {
|
|
428
|
+
background-color: var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));
|
|
429
|
+
pointer-events: none;
|
|
430
|
+
z-index: -1;
|
|
431
|
+
}
|
|
432
|
+
.react-flow__container {
|
|
433
|
+
position: absolute;
|
|
434
|
+
width: 100%;
|
|
435
|
+
height: 100%;
|
|
436
|
+
top: 0;
|
|
437
|
+
left: 0;
|
|
438
|
+
}
|
|
439
|
+
.react-flow__pane {
|
|
440
|
+
z-index: 1;
|
|
441
|
+
touch-action: none;
|
|
442
|
+
}
|
|
443
|
+
.react-flow__pane.draggable {
|
|
444
|
+
cursor: grab;
|
|
445
|
+
}
|
|
446
|
+
.react-flow__pane.dragging {
|
|
447
|
+
cursor: grabbing;
|
|
448
|
+
}
|
|
449
|
+
.react-flow__pane.selection {
|
|
450
|
+
cursor: pointer;
|
|
451
|
+
}
|
|
452
|
+
.react-flow__viewport {
|
|
453
|
+
transform-origin: 0 0;
|
|
454
|
+
z-index: 2;
|
|
455
|
+
pointer-events: none;
|
|
456
|
+
}
|
|
457
|
+
.react-flow__renderer {
|
|
458
|
+
z-index: 4;
|
|
459
|
+
}
|
|
460
|
+
.react-flow__selection {
|
|
461
|
+
z-index: 6;
|
|
462
|
+
}
|
|
463
|
+
.react-flow__nodesselection-rect:focus,
|
|
464
|
+
.react-flow__nodesselection-rect:focus-visible {
|
|
465
|
+
outline: none;
|
|
466
|
+
}
|
|
467
|
+
.react-flow__edge-path {
|
|
468
|
+
stroke: var(--xy-edge-stroke, var(--xy-edge-stroke-default));
|
|
469
|
+
stroke-width: var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));
|
|
470
|
+
fill: none;
|
|
471
|
+
}
|
|
472
|
+
.react-flow__connection-path {
|
|
473
|
+
stroke: var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));
|
|
474
|
+
stroke-width: var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));
|
|
475
|
+
fill: none;
|
|
476
|
+
}
|
|
477
|
+
.react-flow .react-flow__edges {
|
|
478
|
+
position: absolute;
|
|
479
|
+
}
|
|
480
|
+
.react-flow .react-flow__edges svg {
|
|
481
|
+
overflow: visible;
|
|
482
|
+
position: absolute;
|
|
483
|
+
pointer-events: none;
|
|
484
|
+
}
|
|
485
|
+
.react-flow__edge {
|
|
486
|
+
pointer-events: visibleStroke;
|
|
487
|
+
}
|
|
488
|
+
.react-flow__edge.selectable {
|
|
489
|
+
cursor: pointer;
|
|
490
|
+
}
|
|
491
|
+
.react-flow__edge.animated path {
|
|
492
|
+
stroke-dasharray: 5;
|
|
493
|
+
animation: dashdraw 0.5s linear infinite;
|
|
494
|
+
}
|
|
495
|
+
.react-flow__edge.animated path.react-flow__edge-interaction {
|
|
496
|
+
stroke-dasharray: none;
|
|
497
|
+
animation: none;
|
|
498
|
+
}
|
|
499
|
+
.react-flow__edge.inactive {
|
|
500
|
+
pointer-events: none;
|
|
501
|
+
}
|
|
502
|
+
.react-flow__edge.selected,
|
|
503
|
+
.react-flow__edge:focus,
|
|
504
|
+
.react-flow__edge:focus-visible {
|
|
505
|
+
outline: none;
|
|
506
|
+
}
|
|
507
|
+
.react-flow__edge.selected .react-flow__edge-path,
|
|
508
|
+
.react-flow__edge.selectable:focus .react-flow__edge-path,
|
|
509
|
+
.react-flow__edge.selectable:focus-visible .react-flow__edge-path {
|
|
510
|
+
stroke: var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default));
|
|
511
|
+
}
|
|
512
|
+
.react-flow__edge-textwrapper {
|
|
513
|
+
pointer-events: all;
|
|
514
|
+
}
|
|
515
|
+
.react-flow__edge .react-flow__edge-text {
|
|
516
|
+
pointer-events: none;
|
|
517
|
+
-webkit-user-select: none;
|
|
518
|
+
-moz-user-select: none;
|
|
519
|
+
user-select: none;
|
|
520
|
+
}
|
|
521
|
+
/* Arrowhead marker styles - use CSS custom properties as default */
|
|
522
|
+
.react-flow__arrowhead polyline {
|
|
523
|
+
stroke: var(--xy-edge-stroke, var(--xy-edge-stroke-default));
|
|
524
|
+
}
|
|
525
|
+
.react-flow__arrowhead polyline.arrowclosed {
|
|
526
|
+
fill: var(--xy-edge-stroke, var(--xy-edge-stroke-default));
|
|
527
|
+
}
|
|
528
|
+
.react-flow__connection {
|
|
529
|
+
pointer-events: none;
|
|
530
|
+
}
|
|
531
|
+
.react-flow__connection .animated {
|
|
532
|
+
stroke-dasharray: 5;
|
|
533
|
+
animation: dashdraw 0.5s linear infinite;
|
|
534
|
+
}
|
|
535
|
+
svg.react-flow__connectionline {
|
|
536
|
+
z-index: 1001;
|
|
537
|
+
overflow: visible;
|
|
538
|
+
position: absolute;
|
|
539
|
+
}
|
|
540
|
+
.react-flow__nodes {
|
|
541
|
+
pointer-events: none;
|
|
542
|
+
transform-origin: 0 0;
|
|
543
|
+
}
|
|
544
|
+
.react-flow__node {
|
|
545
|
+
position: absolute;
|
|
546
|
+
-webkit-user-select: none;
|
|
547
|
+
-moz-user-select: none;
|
|
548
|
+
user-select: none;
|
|
549
|
+
pointer-events: all;
|
|
550
|
+
transform-origin: 0 0;
|
|
551
|
+
box-sizing: border-box;
|
|
552
|
+
cursor: default;
|
|
553
|
+
}
|
|
554
|
+
.react-flow__node.selectable {
|
|
555
|
+
cursor: pointer;
|
|
556
|
+
}
|
|
557
|
+
.react-flow__node.draggable {
|
|
558
|
+
cursor: grab;
|
|
559
|
+
pointer-events: all;
|
|
560
|
+
}
|
|
561
|
+
.react-flow__node.draggable.dragging {
|
|
562
|
+
cursor: grabbing;
|
|
563
|
+
}
|
|
564
|
+
.react-flow__nodesselection {
|
|
565
|
+
z-index: 3;
|
|
566
|
+
transform-origin: left top;
|
|
567
|
+
pointer-events: none;
|
|
568
|
+
}
|
|
569
|
+
.react-flow__nodesselection-rect {
|
|
570
|
+
position: absolute;
|
|
571
|
+
pointer-events: all;
|
|
572
|
+
cursor: grab;
|
|
573
|
+
}
|
|
574
|
+
.react-flow__handle {
|
|
575
|
+
position: absolute;
|
|
576
|
+
pointer-events: none;
|
|
577
|
+
min-width: 5px;
|
|
578
|
+
min-height: 5px;
|
|
579
|
+
background-color: var(--xy-handle-background-color, var(--xy-handle-background-color-default));
|
|
580
|
+
}
|
|
581
|
+
.react-flow__handle.connectingfrom {
|
|
582
|
+
pointer-events: all;
|
|
583
|
+
}
|
|
584
|
+
.react-flow__handle.connectionindicator {
|
|
585
|
+
pointer-events: all;
|
|
586
|
+
cursor: crosshair;
|
|
587
|
+
}
|
|
588
|
+
.react-flow__handle-bottom {
|
|
589
|
+
top: auto;
|
|
590
|
+
left: 50%;
|
|
591
|
+
bottom: 0;
|
|
592
|
+
transform: translate(-50%, 50%);
|
|
593
|
+
}
|
|
594
|
+
.react-flow__handle-top {
|
|
595
|
+
top: 0;
|
|
596
|
+
left: 50%;
|
|
597
|
+
transform: translate(-50%, -50%);
|
|
598
|
+
}
|
|
599
|
+
.react-flow__handle-left {
|
|
600
|
+
top: 50%;
|
|
601
|
+
left: 0;
|
|
602
|
+
transform: translate(-50%, -50%);
|
|
603
|
+
}
|
|
604
|
+
.react-flow__handle-right {
|
|
605
|
+
top: 50%;
|
|
606
|
+
right: 0;
|
|
607
|
+
transform: translate(50%, -50%);
|
|
608
|
+
}
|
|
609
|
+
.react-flow__edgeupdater {
|
|
610
|
+
cursor: move;
|
|
611
|
+
pointer-events: all;
|
|
612
|
+
}
|
|
613
|
+
.react-flow__pane.selection .react-flow__panel {
|
|
614
|
+
pointer-events: none;
|
|
615
|
+
}
|
|
616
|
+
.react-flow__panel {
|
|
617
|
+
position: absolute;
|
|
618
|
+
z-index: 5;
|
|
619
|
+
margin: 15px;
|
|
620
|
+
}
|
|
621
|
+
.react-flow__panel.top {
|
|
622
|
+
top: 0;
|
|
623
|
+
}
|
|
624
|
+
.react-flow__panel.bottom {
|
|
625
|
+
bottom: 0;
|
|
626
|
+
}
|
|
627
|
+
.react-flow__panel.top.center, .react-flow__panel.bottom.center {
|
|
628
|
+
left: 50%;
|
|
629
|
+
transform: translateX(-15px) translateX(-50%);
|
|
630
|
+
}
|
|
631
|
+
.react-flow__panel.left {
|
|
632
|
+
left: 0;
|
|
633
|
+
}
|
|
634
|
+
.react-flow__panel.right {
|
|
635
|
+
right: 0;
|
|
636
|
+
}
|
|
637
|
+
.react-flow__panel.left.center, .react-flow__panel.right.center {
|
|
638
|
+
top: 50%;
|
|
639
|
+
transform: translateY(-15px) translateY(-50%);
|
|
640
|
+
}
|
|
641
|
+
.react-flow__attribution {
|
|
642
|
+
font-size: 10px;
|
|
643
|
+
background: var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));
|
|
644
|
+
padding: 2px 3px;
|
|
645
|
+
margin: 0;
|
|
646
|
+
}
|
|
647
|
+
.react-flow__attribution a {
|
|
648
|
+
text-decoration: none;
|
|
649
|
+
color: #999;
|
|
650
|
+
}
|
|
651
|
+
@keyframes dashdraw {
|
|
652
|
+
from {
|
|
653
|
+
stroke-dashoffset: 10;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
.react-flow__edgelabel-renderer {
|
|
657
|
+
position: absolute;
|
|
658
|
+
width: 100%;
|
|
659
|
+
height: 100%;
|
|
660
|
+
pointer-events: none;
|
|
661
|
+
-webkit-user-select: none;
|
|
662
|
+
-moz-user-select: none;
|
|
663
|
+
user-select: none;
|
|
664
|
+
left: 0;
|
|
665
|
+
top: 0;
|
|
666
|
+
}
|
|
667
|
+
.react-flow__viewport-portal {
|
|
668
|
+
position: absolute;
|
|
669
|
+
width: 100%;
|
|
670
|
+
height: 100%;
|
|
671
|
+
left: 0;
|
|
672
|
+
top: 0;
|
|
673
|
+
-webkit-user-select: none;
|
|
674
|
+
-moz-user-select: none;
|
|
675
|
+
user-select: none;
|
|
676
|
+
}
|
|
677
|
+
.react-flow__minimap {
|
|
678
|
+
background: var(
|
|
679
|
+
--xy-minimap-background-color-props,
|
|
680
|
+
var(--xy-minimap-background-color, var(--xy-minimap-background-color-default))
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
.react-flow__minimap-svg {
|
|
684
|
+
display: block;
|
|
685
|
+
}
|
|
686
|
+
.react-flow__minimap-mask {
|
|
687
|
+
fill: var(
|
|
688
|
+
--xy-minimap-mask-background-color-props,
|
|
689
|
+
var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default))
|
|
690
|
+
);
|
|
691
|
+
stroke: var(
|
|
692
|
+
--xy-minimap-mask-stroke-color-props,
|
|
693
|
+
var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default))
|
|
694
|
+
);
|
|
695
|
+
stroke-width: var(
|
|
696
|
+
--xy-minimap-mask-stroke-width-props,
|
|
697
|
+
var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default))
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
.react-flow__minimap-node {
|
|
701
|
+
fill: var(
|
|
702
|
+
--xy-minimap-node-background-color-props,
|
|
703
|
+
var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default))
|
|
704
|
+
);
|
|
705
|
+
stroke: var(
|
|
706
|
+
--xy-minimap-node-stroke-color-props,
|
|
707
|
+
var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default))
|
|
708
|
+
);
|
|
709
|
+
stroke-width: var(
|
|
710
|
+
--xy-minimap-node-stroke-width-props,
|
|
711
|
+
var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default))
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
.react-flow__background-pattern.dots {
|
|
715
|
+
fill: var(
|
|
716
|
+
--xy-background-pattern-color-props,
|
|
717
|
+
var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default))
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
.react-flow__background-pattern.lines {
|
|
721
|
+
stroke: var(
|
|
722
|
+
--xy-background-pattern-color-props,
|
|
723
|
+
var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default))
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
.react-flow__background-pattern.cross {
|
|
727
|
+
stroke: var(
|
|
728
|
+
--xy-background-pattern-color-props,
|
|
729
|
+
var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default))
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
.react-flow__controls {
|
|
733
|
+
display: flex;
|
|
734
|
+
flex-direction: column;
|
|
735
|
+
}
|
|
736
|
+
.react-flow__controls.horizontal {
|
|
737
|
+
flex-direction: row;
|
|
738
|
+
}
|
|
739
|
+
.react-flow__controls-button {
|
|
740
|
+
display: flex;
|
|
741
|
+
justify-content: center;
|
|
742
|
+
align-items: center;
|
|
743
|
+
height: 26px;
|
|
744
|
+
width: 26px;
|
|
745
|
+
padding: 4px;
|
|
746
|
+
}
|
|
747
|
+
.react-flow__controls-button svg {
|
|
748
|
+
width: 100%;
|
|
749
|
+
max-width: 12px;
|
|
750
|
+
max-height: 12px;
|
|
751
|
+
fill: currentColor;
|
|
752
|
+
}
|
|
753
|
+
.react-flow__node-input,
|
|
754
|
+
.react-flow__node-default,
|
|
755
|
+
.react-flow__node-output,
|
|
756
|
+
.react-flow__node-group {
|
|
757
|
+
border: var(--xy-node-border, var(--xy-node-border-default));
|
|
758
|
+
color: var(--xy-node-color, var(--xy-node-color-default));
|
|
759
|
+
}
|
|
760
|
+
.react-flow__node-input.selected,
|
|
761
|
+
.react-flow__node-input:focus,
|
|
762
|
+
.react-flow__node-input:focus-visible,
|
|
763
|
+
.react-flow__node-default.selected,
|
|
764
|
+
.react-flow__node-default:focus,
|
|
765
|
+
.react-flow__node-default:focus-visible,
|
|
766
|
+
.react-flow__node-output.selected,
|
|
767
|
+
.react-flow__node-output:focus,
|
|
768
|
+
.react-flow__node-output:focus-visible,
|
|
769
|
+
.react-flow__node-group.selected,
|
|
770
|
+
.react-flow__node-group:focus,
|
|
771
|
+
.react-flow__node-group:focus-visible {
|
|
772
|
+
outline: none;
|
|
773
|
+
border: var(--xy-node-border-selected, var(--xy-node-border-selected-default));
|
|
774
|
+
}
|
|
775
|
+
.react-flow__nodesselection-rect,
|
|
776
|
+
.react-flow__selection {
|
|
777
|
+
background: var(--xy-selection-background-color, var(--xy-selection-background-color-default));
|
|
778
|
+
border: var(--xy-selection-border, var(--xy-selection-border-default));
|
|
779
|
+
}
|
|
780
|
+
.react-flow__resize-control {
|
|
781
|
+
position: absolute;
|
|
782
|
+
}
|
|
783
|
+
.react-flow__resize-control.left,
|
|
784
|
+
.react-flow__resize-control.right {
|
|
785
|
+
cursor: ew-resize;
|
|
786
|
+
}
|
|
787
|
+
.react-flow__resize-control.top,
|
|
788
|
+
.react-flow__resize-control.bottom {
|
|
789
|
+
cursor: ns-resize;
|
|
790
|
+
}
|
|
791
|
+
.react-flow__resize-control.top.left,
|
|
792
|
+
.react-flow__resize-control.bottom.right {
|
|
793
|
+
cursor: nwse-resize;
|
|
794
|
+
}
|
|
795
|
+
.react-flow__resize-control.bottom.left,
|
|
796
|
+
.react-flow__resize-control.top.right {
|
|
797
|
+
cursor: nesw-resize;
|
|
798
|
+
}
|
|
799
|
+
/* handle styles */
|
|
800
|
+
.react-flow__resize-control.handle {
|
|
801
|
+
width: 5px;
|
|
802
|
+
height: 5px;
|
|
803
|
+
border: 1px solid #fff;
|
|
804
|
+
border-radius: 1px;
|
|
805
|
+
background-color: var(--xy-resize-background-color, var(--xy-resize-background-color-default));
|
|
806
|
+
translate: -50% -50%;
|
|
807
|
+
}
|
|
808
|
+
.react-flow__resize-control.handle.left {
|
|
809
|
+
left: 0;
|
|
810
|
+
top: 50%;
|
|
811
|
+
}
|
|
812
|
+
.react-flow__resize-control.handle.right {
|
|
813
|
+
left: 100%;
|
|
814
|
+
top: 50%;
|
|
815
|
+
}
|
|
816
|
+
.react-flow__resize-control.handle.top {
|
|
817
|
+
left: 50%;
|
|
818
|
+
top: 0;
|
|
819
|
+
}
|
|
820
|
+
.react-flow__resize-control.handle.bottom {
|
|
821
|
+
left: 50%;
|
|
822
|
+
top: 100%;
|
|
823
|
+
}
|
|
824
|
+
.react-flow__resize-control.handle.top.left {
|
|
825
|
+
left: 0;
|
|
826
|
+
}
|
|
827
|
+
.react-flow__resize-control.handle.bottom.left {
|
|
828
|
+
left: 0;
|
|
829
|
+
}
|
|
830
|
+
.react-flow__resize-control.handle.top.right {
|
|
831
|
+
left: 100%;
|
|
832
|
+
}
|
|
833
|
+
.react-flow__resize-control.handle.bottom.right {
|
|
834
|
+
left: 100%;
|
|
835
|
+
}
|
|
836
|
+
/* line styles */
|
|
837
|
+
.react-flow__resize-control.line {
|
|
838
|
+
border-color: var(--xy-resize-background-color, var(--xy-resize-background-color-default));
|
|
839
|
+
border-width: 0;
|
|
840
|
+
border-style: solid;
|
|
841
|
+
}
|
|
842
|
+
.react-flow__resize-control.line.left,
|
|
843
|
+
.react-flow__resize-control.line.right {
|
|
844
|
+
width: 1px;
|
|
845
|
+
transform: translate(-50%, 0);
|
|
846
|
+
top: 0;
|
|
847
|
+
height: 100%;
|
|
848
|
+
}
|
|
849
|
+
.react-flow__resize-control.line.left {
|
|
850
|
+
left: 0;
|
|
851
|
+
border-left-width: 1px;
|
|
852
|
+
}
|
|
853
|
+
.react-flow__resize-control.line.right {
|
|
854
|
+
left: 100%;
|
|
855
|
+
border-right-width: 1px;
|
|
856
|
+
}
|
|
857
|
+
.react-flow__resize-control.line.top,
|
|
858
|
+
.react-flow__resize-control.line.bottom {
|
|
859
|
+
height: 1px;
|
|
860
|
+
transform: translate(0, -50%);
|
|
861
|
+
left: 0;
|
|
862
|
+
width: 100%;
|
|
863
|
+
}
|
|
864
|
+
.react-flow__resize-control.line.top {
|
|
865
|
+
top: 0;
|
|
866
|
+
border-top-width: 1px;
|
|
867
|
+
}
|
|
868
|
+
.react-flow__resize-control.line.bottom {
|
|
869
|
+
border-bottom-width: 1px;
|
|
870
|
+
top: 100%;
|
|
871
|
+
}
|
|
872
|
+
|
|
366
873
|
/* foundation/layout.css */
|
|
367
874
|
.cb-flex { display: flex; gap: var(--cb-flex-gap); }
|
|
368
875
|
.cb-flex--column { flex-direction: column; }
|
|
@@ -829,6 +1336,201 @@ html, body { background: var(--cb-bg); color: var(--cb-fg); }
|
|
|
829
1336
|
line-height: var(--cb-leading-normal);
|
|
830
1337
|
}
|
|
831
1338
|
|
|
1339
|
+
/* data/diagram/diagram.css */
|
|
1340
|
+
/* Diagram and DiagramEditor run on React Flow. Its base stylesheet (bundled before this file) owns layout and
|
|
1341
|
+
reads its colours from `--xy-*` custom properties; here those are pointed at Tokens, and the node React
|
|
1342
|
+
Flow wraps is drawn by this library. */
|
|
1343
|
+
|
|
1344
|
+
.cb-diagram {
|
|
1345
|
+
--cb-diagram-cell: var(--cb-space-5);
|
|
1346
|
+
min-inline-size: 0;
|
|
1347
|
+
position: relative;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
.cb-diagram__cell {
|
|
1351
|
+
inline-size: var(--cb-diagram-cell);
|
|
1352
|
+
pointer-events: none;
|
|
1353
|
+
position: absolute;
|
|
1354
|
+
visibility: hidden;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
.cb-diagram__hint {
|
|
1358
|
+
color: var(--cb-fg-muted);
|
|
1359
|
+
font-size: var(--cb-text-xs);
|
|
1360
|
+
margin: 0 0 var(--cb-space-2);
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
.cb-diagram__viewport {
|
|
1364
|
+
background: var(--cb-surface);
|
|
1365
|
+
block-size: var(--cb-canvas-block-size);
|
|
1366
|
+
border: var(--cb-border-width) solid var(--cb-border);
|
|
1367
|
+
border-radius: var(--cb-radius-lg);
|
|
1368
|
+
overflow: hidden;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
.cb-diagram .react-flow {
|
|
1372
|
+
--xy-background-color: var(--cb-surface);
|
|
1373
|
+
--xy-background-pattern-color: var(--cb-border);
|
|
1374
|
+
--xy-edge-stroke: var(--cb-border-strong);
|
|
1375
|
+
--xy-edge-stroke-selected: var(--cb-tone-brand);
|
|
1376
|
+
--xy-edge-stroke-width: var(--cb-border-width);
|
|
1377
|
+
--xy-connectionline-stroke: var(--cb-tone-info);
|
|
1378
|
+
--xy-connectionline-stroke-width: var(--cb-border-width);
|
|
1379
|
+
--xy-handle-background-color: var(--cb-surface);
|
|
1380
|
+
--xy-handle-border-color: var(--cb-border-strong);
|
|
1381
|
+
--xy-attribution-background-color: transparent;
|
|
1382
|
+
--xy-controls-button-background-color: var(--cb-surface);
|
|
1383
|
+
--xy-controls-button-background-color-hover: var(--cb-bg-subtle);
|
|
1384
|
+
--xy-controls-button-color: var(--cb-fg);
|
|
1385
|
+
--xy-controls-button-color-hover: var(--cb-fg);
|
|
1386
|
+
--xy-controls-button-border-color: var(--cb-border);
|
|
1387
|
+
--xy-controls-box-shadow: none;
|
|
1388
|
+
--xy-edge-label-background-color: var(--cb-surface);
|
|
1389
|
+
--xy-edge-label-color: var(--cb-fg-muted);
|
|
1390
|
+
color: var(--cb-fg);
|
|
1391
|
+
font-family: inherit;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
.cb-diagram .react-flow__edge-text {
|
|
1395
|
+
fill: var(--cb-fg-muted);
|
|
1396
|
+
font-size: var(--cb-text-xs);
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
.cb-diagram .react-flow__edge-textbg { fill: var(--cb-surface); }
|
|
1400
|
+
|
|
1401
|
+
.cb-diagram .cb-diagram__edge--neutral .react-flow__edge-path { stroke: var(--cb-tone-neutral); }
|
|
1402
|
+
.cb-diagram .cb-diagram__edge--brand .react-flow__edge-path { stroke: var(--cb-tone-brand); }
|
|
1403
|
+
.cb-diagram .cb-diagram__edge--info .react-flow__edge-path { stroke: var(--cb-tone-info); }
|
|
1404
|
+
.cb-diagram .cb-diagram__edge--success .react-flow__edge-path { stroke: var(--cb-tone-success); }
|
|
1405
|
+
.cb-diagram .cb-diagram__edge--warning .react-flow__edge-path { stroke: var(--cb-tone-warning); }
|
|
1406
|
+
.cb-diagram .cb-diagram__edge--danger .react-flow__edge-path { stroke: var(--cb-tone-danger); }
|
|
1407
|
+
|
|
1408
|
+
.cb-diagram .react-flow__node:focus-visible,
|
|
1409
|
+
.cb-diagram .react-flow__edge:focus-visible {
|
|
1410
|
+
outline: var(--cb-focus-width) solid var(--cb-focus);
|
|
1411
|
+
outline-offset: var(--cb-focus-offset);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
.cb-diagram__node {
|
|
1415
|
+
align-items: center;
|
|
1416
|
+
background: var(--cb-surface);
|
|
1417
|
+
block-size: calc(var(--cb-diagram-cell) * 3);
|
|
1418
|
+
border: var(--cb-border-width) solid var(--cb-border-strong);
|
|
1419
|
+
border-radius: var(--cb-radius-md);
|
|
1420
|
+
box-sizing: border-box;
|
|
1421
|
+
color: var(--cb-fg);
|
|
1422
|
+
display: flex;
|
|
1423
|
+
flex-direction: column;
|
|
1424
|
+
font-size: var(--cb-text-sm);
|
|
1425
|
+
gap: var(--cb-space-1);
|
|
1426
|
+
inline-size: calc(var(--cb-diagram-cell) * 8);
|
|
1427
|
+
isolation: isolate;
|
|
1428
|
+
justify-content: center;
|
|
1429
|
+
padding: var(--cb-space-1) var(--cb-space-2);
|
|
1430
|
+
position: relative;
|
|
1431
|
+
text-align: center;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
.cb-diagram--editor .cb-diagram__node { cursor: grab; }
|
|
1435
|
+
|
|
1436
|
+
.cb-diagram__node[data-shape="pill"] { border-radius: var(--cb-radius-full); }
|
|
1437
|
+
|
|
1438
|
+
/* A diamond's box is square, so the handles React Flow places at the middle of each side sit exactly on the
|
|
1439
|
+
diamond's tips and arrows meet the drawn outline. The rotated square's diagonal equals the box's side. */
|
|
1440
|
+
.cb-diagram__node[data-shape="diamond"] {
|
|
1441
|
+
background: transparent;
|
|
1442
|
+
block-size: calc(var(--cb-diagram-cell) * 4);
|
|
1443
|
+
border-color: transparent;
|
|
1444
|
+
inline-size: calc(var(--cb-diagram-cell) * 4);
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
.cb-diagram__node[data-shape="diamond"]::before {
|
|
1448
|
+
aspect-ratio: 1;
|
|
1449
|
+
background: var(--cb-surface);
|
|
1450
|
+
block-size: 70.7%;
|
|
1451
|
+
border: var(--cb-border-width) solid var(--cb-border-strong);
|
|
1452
|
+
content: "";
|
|
1453
|
+
inset: 0;
|
|
1454
|
+
margin: auto;
|
|
1455
|
+
position: absolute;
|
|
1456
|
+
rotate: 45deg;
|
|
1457
|
+
z-index: -1;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
.cb-diagram__node[data-tone="neutral"],
|
|
1461
|
+
.cb-diagram__node[data-tone="neutral"]::before { border-color: var(--cb-tone-neutral); }
|
|
1462
|
+
.cb-diagram__node[data-tone="brand"],
|
|
1463
|
+
.cb-diagram__node[data-tone="brand"]::before { border-color: var(--cb-tone-brand); }
|
|
1464
|
+
.cb-diagram__node[data-tone="info"],
|
|
1465
|
+
.cb-diagram__node[data-tone="info"]::before { border-color: var(--cb-tone-info); }
|
|
1466
|
+
.cb-diagram__node[data-tone="success"],
|
|
1467
|
+
.cb-diagram__node[data-tone="success"]::before { border-color: var(--cb-tone-success); }
|
|
1468
|
+
.cb-diagram__node[data-tone="warning"],
|
|
1469
|
+
.cb-diagram__node[data-tone="warning"]::before { border-color: var(--cb-tone-warning); }
|
|
1470
|
+
.cb-diagram__node[data-tone="danger"],
|
|
1471
|
+
.cb-diagram__node[data-tone="danger"]::before { border-color: var(--cb-tone-danger); }
|
|
1472
|
+
|
|
1473
|
+
.cb-diagram__node[data-shape="diamond"][data-tone] { border-color: transparent; }
|
|
1474
|
+
|
|
1475
|
+
.cb-diagram__node[data-selected="true"],
|
|
1476
|
+
.cb-diagram__node[data-selected="true"]::before {
|
|
1477
|
+
border-color: var(--cb-tone-brand);
|
|
1478
|
+
box-shadow: 0 0 0 var(--cb-border-width) var(--cb-tone-brand);
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
.cb-diagram__node[data-shape="diamond"][data-selected="true"] { box-shadow: none; }
|
|
1482
|
+
|
|
1483
|
+
.cb-diagram__node[data-connecting="true"],
|
|
1484
|
+
.cb-diagram__node[data-connecting="true"]::before {
|
|
1485
|
+
border-color: var(--cb-tone-info);
|
|
1486
|
+
border-style: dashed;
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
.cb-diagram__label {
|
|
1490
|
+
max-inline-size: 100%;
|
|
1491
|
+
overflow: hidden;
|
|
1492
|
+
text-overflow: ellipsis;
|
|
1493
|
+
white-space: nowrap;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
.cb-diagram .cb-diagram__handle {
|
|
1497
|
+
background: var(--cb-surface);
|
|
1498
|
+
block-size: var(--cb-space-3);
|
|
1499
|
+
border: var(--cb-border-width) solid var(--cb-border-strong);
|
|
1500
|
+
inline-size: var(--cb-space-3);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
.cb-diagram:not(.cb-diagram--editor) .cb-diagram__handle { visibility: hidden; }
|
|
1504
|
+
|
|
1505
|
+
/* Where a pointer can hover, handles appear with the node's hover or focus; on touch there is no hover, so
|
|
1506
|
+
they stay visible to tap. */
|
|
1507
|
+
@media (hover: hover) {
|
|
1508
|
+
.cb-diagram--editor .react-flow__node:not(:hover, :focus-within, .selected) .cb-diagram__handle { opacity: 0; }
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
.cb-diagram .react-flow__controls-button svg { fill: currentColor; }
|
|
1512
|
+
|
|
1513
|
+
.cb-diagram .react-flow__attribution { font-size: var(--cb-text-xs); }
|
|
1514
|
+
|
|
1515
|
+
.cb-diagram__outline,
|
|
1516
|
+
.cb-diagram__status {
|
|
1517
|
+
block-size: var(--cb-border-width);
|
|
1518
|
+
clip-path: inset(50%);
|
|
1519
|
+
inline-size: var(--cb-border-width);
|
|
1520
|
+
margin: 0;
|
|
1521
|
+
overflow: hidden;
|
|
1522
|
+
padding: 0;
|
|
1523
|
+
position: absolute;
|
|
1524
|
+
white-space: nowrap;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
@media (forced-colors: active) {
|
|
1528
|
+
.cb-diagram__node,
|
|
1529
|
+
.cb-diagram__node::before,
|
|
1530
|
+
.cb-diagram .cb-diagram__handle { border-color: CanvasText; }
|
|
1531
|
+
.cb-diagram .react-flow__edge-path { stroke: CanvasText; }
|
|
1532
|
+
}
|
|
1533
|
+
|
|
832
1534
|
/* data/donut.css */
|
|
833
1535
|
.cb-donut { position: relative; display: inline-grid; place-items: center; }
|
|
834
1536
|
.cb-donut svg { position: absolute; inset: 0; }
|
|
@@ -1073,6 +1775,19 @@ html, body { background: var(--cb-bg); color: var(--cb-fg); }
|
|
|
1073
1775
|
inset-inline: calc(var(--cb-space-8) * 3);
|
|
1074
1776
|
}
|
|
1075
1777
|
|
|
1778
|
+
/* Fullscreen hands the element the whole screen, so the fixed canvas height stops being the right
|
|
1779
|
+
size: the viewport takes the space the toolbar leaves instead of leaving the rest blank. */
|
|
1780
|
+
.cb-pan-zoom-canvas:fullscreen {
|
|
1781
|
+
border-radius: var(--cb-radius-none);
|
|
1782
|
+
display: flex;
|
|
1783
|
+
flex-direction: column;
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
.cb-pan-zoom-canvas:fullscreen .cb-pan-zoom-canvas__viewport {
|
|
1787
|
+
block-size: auto;
|
|
1788
|
+
flex: 1;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1076
1791
|
@media (prefers-reduced-motion: reduce) {
|
|
1077
1792
|
.cb-pan-zoom-canvas__content { transition: none; }
|
|
1078
1793
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ceebee/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.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
|
},
|