Skip to content

Instantly share code, notes, and snippets.

@podhmo
Last active January 19, 2025 11:02
react-flowあたりでいい感じに依存を表示したい

react-flowあたりでいい感じに依存を表示したい

なんとなくreact-markdownを覗いてみたりして過度にパッケージが分かれすぎているんじゃないか?と思ったりした。 (実際のところは依存関係を追う事ができなくて辛い。ワーキングメモリーの限界に達したみたいな感じ)

そんなわけで必要な依存関係をいい感じに可視化して📝をしてみたいと思ったりした。 とはいえ、すべての依存関係をそのまま表示してもあんまり嬉しくない。

  • あるパッケージの依存を表示
  • 必要そうな依存をマーク
  • マークしていた関係をいい感じの出力でクリップボードにコピー

というようなことができれば良いと思ったりした(そういえばnxに依存関係をそれっぽく表示するuiが存在していた(使い物にならなかった))。

react-flow

https://reactflow.dev/

なんかテキトーに表示を試してみたい。全然理解をしていないのだけれどグラフのノードは移動できなくても良いかも。

https://reactflow.dev/learn

これで実行して済ませられるっぽいんだけれどあんまりやりたくないな。。

$ npx degit xyflow/vite-react-flow-template app-name
# deno run -A npm:degit xyflow/vite-react-flow-template app-name

https://github.com/Rich-Harris/degit

これをそのまま実行すると手軽に試せるけれどgistに載せるように分解しなければ行けないのが面倒かも?

あとviteから読み込む場合にはcssをimportできるけれど、esbuildでそれは無理なようだ(pluginが必要)。

import { join as pathjoin } from "jsr:@std/path@1/join";
import { type Context, Hono } from "jsr:@hono/hono@4.6.16";
import { CODE, HTML, tsxToJs } from "jsr:@podhmo/glue@0.2.4/mini-webapp";
// serve for development
// $ deno run -A jsr:@podhmo/glue@0.2.4 serve --port 8080 ./app.ts
//
// bunle to single html file
// $ deno run -A jsr:@podhmo/glue@0.2.4 bundle --output-style html --html-id root ./client.tsx > index.html
//
const app = new Hono();
app.get("/style.css", async (ctx: Context) => {
const css = await Deno.readTextFile(
pathjoin(import.meta.dirname ?? "", ctx.req.path.substring(1)),
);
return new Response(css, { headers: { "content-type": "text/css" } });
});
app.get("/", async (ctx: Context) => {
const filename = Deno.env.get("TSX") || "client.tsx";
const filepath = pathjoin(import.meta.dirname ?? "", filename);
const title = Deno.env.get("TITLE") || "Counter";
const code = await tsxToJs(filepath);
const html = HTML({ title, css: "./style.css" }, CODE({ id: "root", code }));
return ctx.html(html);
});
export default app;
/** @jsxRuntime automatic */
/** @jsxImportSource npm:react@19 */
/** @jsxImportSourceTypes npm:@types/react@19 */
import { StrictMode, useCallback } from "npm:react@19";
import { createRoot } from "npm:react-dom@19/client";
import {
ReactFlow,
Background,
Controls,
MiniMap,
addEdge,
useNodesState,
useEdgesState,
type OnConnect,
} from 'npm:@xyflow/react@12.4';
// import "npm:@xyflow/react@12.4/dist/style.css";
import { initialNodes, nodeTypes } from './nodes.ts';
import { initialEdges, edgeTypes } from './edges.ts';
export default function App() {
const [nodes, , onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect: OnConnect = useCallback(
(connection) => setEdges((edges) => addEdge(connection, edges)),
[setEdges]
);
return (
<ReactFlow
nodes={nodes}
nodeTypes={nodeTypes}
onNodesChange={onNodesChange}
edges={edges}
edgeTypes={edgeTypes}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
>
<Background />
<MiniMap />
<Controls />
</ReactFlow>
);
}
// ----------------------------------------
// main
// ----------------------------------------
const root = createRoot(document.getElementById("root"));
root.render(
<StrictMode>
<App />
</StrictMode>,
);
{
"version": "4",
"specifiers": {
"npm:@types/react@19": "19.0.3",
"npm:@xyflow/react@*": "12.4.1_react@19.0.0_react-dom@19.0.0__react@19.0.0_@types+react@19.0.3",
"npm:@xyflow/react@12.4": "12.4.1_react@19.0.0_react-dom@19.0.0__react@19.0.0_@types+react@19.0.3",
"npm:degit@*": "2.8.4",
"npm:react-dom@19": "19.0.0_react@19.0.0",
"npm:react@19": "19.0.0"
},
"npm": {
"@types/d3-color@3.1.3": {
"integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="
},
"@types/d3-drag@3.0.7": {
"integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
"dependencies": [
"@types/d3-selection"
]
},
"@types/d3-interpolate@3.0.4": {
"integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
"dependencies": [
"@types/d3-color"
]
},
"@types/d3-selection@3.0.11": {
"integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="
},
"@types/d3-transition@3.0.9": {
"integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
"dependencies": [
"@types/d3-selection"
]
},
"@types/d3-zoom@3.0.8": {
"integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
"dependencies": [
"@types/d3-interpolate",
"@types/d3-selection"
]
},
"@types/react@19.0.3": {
"integrity": "sha512-UavfHguIjnnuq9O67uXfgy/h3SRJbidAYvNjLceB+2RIKVRBzVsh0QO+Pw6BCSQqFS9xwzKfwstXx0m6AbAREA==",
"dependencies": [
"csstype"
]
},
"@xyflow/react@12.4.1_react@19.0.0_react-dom@19.0.0__react@19.0.0_@types+react@19.0.3": {
"integrity": "sha512-h06/ONdZr7IM9UlHcgCqbVDwQVnVVUeu7Sh1b7WAcpkn/1w43Gm2qierLd8RanYeJUK8fdto/scKHxYEJsRlJA==",
"dependencies": [
"@xyflow/system",
"classcat",
"react",
"react-dom",
"zustand"
]
},
"@xyflow/system@0.0.49": {
"integrity": "sha512-U41XEPv0doyUrP9sgjquuB834/PhqcuE5a4gSo0itC4DjDU4RHjfqmPP1NnYiCu3Jee9MRJzU9Bq+tmh98jldQ==",
"dependencies": [
"@types/d3-drag",
"@types/d3-selection",
"@types/d3-transition",
"@types/d3-zoom",
"d3-drag",
"d3-selection",
"d3-zoom"
]
},
"classcat@5.0.5": {
"integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w=="
},
"csstype@3.1.3": {
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"d3-color@3.1.0": {
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="
},
"d3-dispatch@3.0.1": {
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="
},
"d3-drag@3.0.0": {
"integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
"dependencies": [
"d3-dispatch",
"d3-selection"
]
},
"d3-ease@3.0.1": {
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="
},
"d3-interpolate@3.0.1": {
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
"dependencies": [
"d3-color"
]
},
"d3-selection@3.0.0": {
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="
},
"d3-timer@3.0.1": {
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="
},
"d3-transition@3.0.1_d3-selection@3.0.0": {
"integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
"dependencies": [
"d3-color",
"d3-dispatch",
"d3-ease",
"d3-interpolate",
"d3-selection",
"d3-timer"
]
},
"d3-zoom@3.0.0_d3-selection@3.0.0": {
"integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
"dependencies": [
"d3-dispatch",
"d3-drag",
"d3-interpolate",
"d3-selection",
"d3-transition"
]
},
"degit@2.8.4": {
"integrity": "sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng=="
},
"react-dom@19.0.0_react@19.0.0": {
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
"dependencies": [
"react",
"scheduler"
]
},
"react@19.0.0": {
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="
},
"scheduler@0.25.0": {
"integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="
},
"use-sync-external-store@1.4.0_react@19.0.0": {
"integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
"dependencies": [
"react"
]
},
"zustand@4.5.6_@types+react@19.0.3_react@19.0.0": {
"integrity": "sha512-ibr/n1hBzLLj5Y+yUcU7dYw8p6WnIVzdJbnX+1YpaScvZVF2ziugqHs+LAmHw4lWO9c/zRj+K1ncgWDQuthEdQ==",
"dependencies": [
"@types/react",
"react",
"use-sync-external-store"
]
}
}
}
import type { Edge, EdgeTypes } from "npm:@xyflow/react@12.4";
export const initialEdges: Edge[] = [
{ id: "a->c", source: "a", target: "c", animated: true },
{ id: "b->d", source: "b", target: "d" },
{ id: "c->d", source: "c", target: "d", animated: true },
];
export const edgeTypes = {
// Add your custom edge types here!
} satisfies EdgeTypes;
serve:
deno cache *.tsx
deno run -A ~/ghq/github.com/podhmo/deno-glue/main.ts serve --port 8080 ./app.ts --next --debug
.PHONY: serve
import type { NodeTypes } from "npm:@xyflow/react@12.4";
import { PositionLoggerNode } from ".//nodes__PositionLoggerNode.tsx";
import { AppNode } from "./nodes__types.ts";
export const initialNodes: AppNode[] = [
{ id: "a", type: "input", position: { x: 0, y: 0 }, data: { label: "wire" } },
{
id: "b",
type: "position-logger",
position: { x: -100, y: 100 },
data: { label: "drag me!" },
},
{ id: "c", position: { x: 100, y: 100 }, data: { label: "your ideas" } },
{
id: "d",
type: "output",
position: { x: 0, y: 200 },
data: { label: "with React Flow" },
},
];
export const nodeTypes = {
"position-logger": PositionLoggerNode,
// Add any of your custom nodes here!
} satisfies NodeTypes;
/** @jsxRuntime automatic */
/** @jsxImportSource npm:react@19 */
/** @jsxImportSourceTypes npm:@types/react@19 */
import { Handle, Position, type NodeProps } from 'npm:@xyflow/react@12.4';
import { type PositionLoggerNode } from './nodes__types.ts';
export function PositionLoggerNode({
positionAbsoluteX,
positionAbsoluteY,
data,
}: NodeProps<PositionLoggerNode>) {
const x = `${Math.round(positionAbsoluteX)}px`;
const y = `${Math.round(positionAbsoluteY)}px`;
return (
// We add this class to use the same styles as React Flow's default nodes.
<div className="react-flow__node-default">
{data.label && <div>{data.label}</div>}
<div>
{x} {y}
</div>
<Handle type="source" position={Position.Bottom} />
</div>
);
}
import type { Node, BuiltInNode } from '@xyflow/react';
export type PositionLoggerNode = Node<{ label: string }, 'position-logger'>;
export type AppNode = BuiltInNode | PositionLoggerNode;
/** index.css **/
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
}
html,
body,
#root {
height: 100%;
margin: 0;
}
/* this gets exported as style.css and can be used for the default theming */
/* these are the necessary styles for React/Svelte Flow, they get used by base.css and style.css */
.react-flow {
direction: ltr;
--xy-edge-stroke-default: #b1b1b7;
--xy-edge-stroke-width-default: 1;
--xy-edge-stroke-selected-default: #555;
--xy-connectionline-stroke-default: #b1b1b7;
--xy-connectionline-stroke-width-default: 1;
--xy-attribution-background-color-default: rgba(255, 255, 255, 0.5);
--xy-minimap-background-color-default: #fff;
--xy-minimap-mask-background-color-default: rgb(240, 240, 240, 0.6);
--xy-minimap-mask-stroke-color-default: transparent;
--xy-minimap-mask-stroke-width-default: 1;
--xy-minimap-node-background-color-default: #e2e2e2;
--xy-minimap-node-stroke-color-default: transparent;
--xy-minimap-node-stroke-width-default: 2;
--xy-background-color-default: transparent;
--xy-background-pattern-dots-color-default: #91919a;
--xy-background-pattern-lines-color-default: #eee;
--xy-background-pattern-cross-color-default: #e2e2e2;
background-color: var(--xy-background-color, var(--xy-background-color-default));
--xy-node-color-default: inherit;
--xy-node-border-default: 1px solid #1a192b;
--xy-node-background-color-default: #fff;
--xy-node-group-background-color-default: rgba(240, 240, 240, 0.25);
--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, 0.08);
--xy-node-boxshadow-selected-default: 0 0 0 0.5px #1a192b;
--xy-node-border-radius-default: 3px;
--xy-handle-background-color-default: #1a192b;
--xy-handle-border-color-default: #fff;
--xy-selection-background-color-default: rgba(0, 89, 220, 0.08);
--xy-selection-border-default: 1px dotted rgba(0, 89, 220, 0.8);
--xy-controls-button-background-color-default: #fefefe;
--xy-controls-button-background-color-hover-default: #f4f4f4;
--xy-controls-button-color-default: inherit;
--xy-controls-button-color-hover-default: inherit;
--xy-controls-button-border-color-default: #eee;
--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08);
--xy-edge-label-background-color-default: #ffffff;
--xy-edge-label-color-default: inherit;
--xy-resize-background-color-default: #3367d9;
}
.react-flow.dark {
--xy-edge-stroke-default: #3e3e3e;
--xy-edge-stroke-width-default: 1;
--xy-edge-stroke-selected-default: #727272;
--xy-connectionline-stroke-default: #b1b1b7;
--xy-connectionline-stroke-width-default: 1;
--xy-attribution-background-color-default: rgba(150, 150, 150, 0.25);
--xy-minimap-background-color-default: #141414;
--xy-minimap-mask-background-color-default: rgb(60, 60, 60, 0.6);
--xy-minimap-mask-stroke-color-default: transparent;
--xy-minimap-mask-stroke-width-default: 1;
--xy-minimap-node-background-color-default: #2b2b2b;
--xy-minimap-node-stroke-color-default: transparent;
--xy-minimap-node-stroke-width-default: 2;
--xy-background-color-default: #141414;
--xy-background-pattern-dots-color-default: #777;
--xy-background-pattern-lines-color-default: #777;
--xy-background-pattern-cross-color-default: #777;
--xy-node-color-default: #f8f8f8;
--xy-node-border-default: 1px solid #3c3c3c;
--xy-node-background-color-default: #1e1e1e;
--xy-node-group-background-color-default: rgba(240, 240, 240, 0.25);
--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, 0.08);
--xy-node-boxshadow-selected-default: 0 0 0 0.5px #999;
--xy-handle-background-color-default: #bebebe;
--xy-handle-border-color-default: #1e1e1e;
--xy-selection-background-color-default: rgba(200, 200, 220, 0.08);
--xy-selection-border-default: 1px dotted rgba(200, 200, 220, 0.8);
--xy-controls-button-background-color-default: #2b2b2b;
--xy-controls-button-background-color-hover-default: #3e3e3e;
--xy-controls-button-color-default: #f8f8f8;
--xy-controls-button-color-hover-default: #fff;
--xy-controls-button-border-color-default: #5b5b5b;
--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08);
--xy-edge-label-background-color-default: #141414;
--xy-edge-label-color-default: #f8f8f8;
}
.react-flow__background {
background-color: var(--xy-background-color, var(--xy-background-color-props, var(--xy-background-color-default)));
pointer-events: none;
z-index: -1;
}
.react-flow__container {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.react-flow__pane {
z-index: 1;
}
.react-flow__pane.draggable {
cursor: grab;
}
.react-flow__pane.dragging {
cursor: grabbing;
}
.react-flow__pane.selection {
cursor: pointer;
}
.react-flow__viewport {
transform-origin: 0 0;
z-index: 2;
pointer-events: none;
}
.react-flow__renderer {
z-index: 4;
}
.react-flow__selection {
z-index: 6;
}
.react-flow__nodesselection-rect:focus,
.react-flow__nodesselection-rect:focus-visible {
outline: none;
}
.react-flow__edge-path {
stroke: var(--xy-edge-stroke, var(--xy-edge-stroke-default));
stroke-width: var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));
fill: none;
}
.react-flow__connection-path {
stroke: var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));
stroke-width: var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));
fill: none;
}
.react-flow .react-flow__edges {
position: absolute;
}
.react-flow .react-flow__edges svg {
overflow: visible;
position: absolute;
pointer-events: none;
}
.react-flow__edge {
pointer-events: visibleStroke;
}
.react-flow__edge.selectable {
cursor: pointer;
}
.react-flow__edge.animated path {
stroke-dasharray: 5;
animation: dashdraw 0.5s linear infinite;
}
.react-flow__edge.animated path.react-flow__edge-interaction {
stroke-dasharray: none;
animation: none;
}
.react-flow__edge.inactive {
pointer-events: none;
}
.react-flow__edge.selected,
.react-flow__edge:focus,
.react-flow__edge:focus-visible {
outline: none;
}
.react-flow__edge.selected .react-flow__edge-path,
.react-flow__edge.selectable:focus .react-flow__edge-path,
.react-flow__edge.selectable:focus-visible .react-flow__edge-path {
stroke: var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default));
}
.react-flow__edge-textwrapper {
pointer-events: all;
}
.react-flow__edge .react-flow__edge-text {
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.react-flow__connection {
pointer-events: none;
}
.react-flow__connection .animated {
stroke-dasharray: 5;
animation: dashdraw 0.5s linear infinite;
}
svg.react-flow__connectionline {
z-index: 1001;
overflow: visible;
position: absolute;
}
.react-flow__nodes {
pointer-events: none;
transform-origin: 0 0;
}
.react-flow__node {
position: absolute;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
pointer-events: all;
transform-origin: 0 0;
box-sizing: border-box;
cursor: default;
}
.react-flow__node.selectable {
cursor: pointer;
}
.react-flow__node.draggable {
cursor: grab;
pointer-events: all;
}
.react-flow__node.draggable.dragging {
cursor: grabbing;
}
.react-flow__nodesselection {
z-index: 3;
transform-origin: left top;
pointer-events: none;
}
.react-flow__nodesselection-rect {
position: absolute;
pointer-events: all;
cursor: grab;
}
.react-flow__handle {
position: absolute;
pointer-events: none;
min-width: 5px;
min-height: 5px;
width: 6px;
height: 6px;
background-color: var(--xy-handle-background-color, var(--xy-handle-background-color-default));
border: 1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));
border-radius: 100%;
}
.react-flow__handle.connectingfrom {
pointer-events: all;
}
.react-flow__handle.connectionindicator {
pointer-events: all;
cursor: crosshair;
}
.react-flow__handle-bottom {
top: auto;
left: 50%;
bottom: 0;
transform: translate(-50%, 50%);
}
.react-flow__handle-top {
top: 0;
left: 50%;
transform: translate(-50%, -50%);
}
.react-flow__handle-left {
top: 50%;
left: 0;
transform: translate(-50%, -50%);
}
.react-flow__handle-right {
top: 50%;
right: 0;
transform: translate(50%, -50%);
}
.react-flow__edgeupdater {
cursor: move;
pointer-events: all;
}
.react-flow__panel {
position: absolute;
z-index: 5;
margin: 15px;
}
.react-flow__panel.top {
top: 0;
}
.react-flow__panel.bottom {
bottom: 0;
}
.react-flow__panel.left {
left: 0;
}
.react-flow__panel.right {
right: 0;
}
.react-flow__panel.center {
left: 50%;
transform: translateX(-50%);
}
.react-flow__attribution {
font-size: 10px;
background: var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));
padding: 2px 3px;
margin: 0;
}
.react-flow__attribution a {
text-decoration: none;
color: #999;
}
@keyframes dashdraw {
from {
stroke-dashoffset: 10;
}
}
.react-flow__edgelabel-renderer {
position: absolute;
width: 100%;
height: 100%;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
left: 0;
top: 0;
}
.react-flow__viewport-portal {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.react-flow__minimap {
background: var(
--xy-minimap-background-color-props,
var(--xy-minimap-background-color, var(--xy-minimap-background-color-default))
);
}
.react-flow__minimap-svg {
display: block;
}
.react-flow__minimap-mask {
fill: var(
--xy-minimap-mask-background-color-props,
var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default))
);
stroke: var(
--xy-minimap-mask-stroke-color-props,
var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default))
);
stroke-width: var(
--xy-minimap-mask-stroke-width-props,
var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default))
);
}
.react-flow__minimap-node {
fill: var(
--xy-minimap-node-background-color-props,
var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default))
);
stroke: var(
--xy-minimap-node-stroke-color-props,
var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default))
);
stroke-width: var(
--xy-minimap-node-stroke-width-props,
var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default))
);
}
.react-flow__background-pattern.dots {
fill: var(
--xy-background-pattern-color-props,
var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default))
);
}
.react-flow__background-pattern.lines {
stroke: var(
--xy-background-pattern-color-props,
var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default))
);
}
.react-flow__background-pattern.cross {
stroke: var(
--xy-background-pattern-color-props,
var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default))
);
}
.react-flow__controls {
display: flex;
flex-direction: column;
box-shadow: var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default));
}
.react-flow__controls.horizontal {
flex-direction: row;
}
.react-flow__controls-button {
display: flex;
justify-content: center;
align-items: center;
height: 26px;
width: 26px;
padding: 4px;
border: none;
background: var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));
border-bottom: 1px solid
var(
--xy-controls-button-border-color-props,
var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default))
);
color: var(
--xy-controls-button-color-props,
var(--xy-controls-button-color, var(--xy-controls-button-color-default))
);
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.react-flow__controls-button svg {
width: 100%;
max-width: 12px;
max-height: 12px;
fill: currentColor;
}
.react-flow__edge.updating .react-flow__edge-path {
stroke: #777;
}
.react-flow__edge-text {
font-size: 10px;
}
.react-flow__node.selectable:focus,
.react-flow__node.selectable:focus-visible {
outline: none;
}
.react-flow__node-input,
.react-flow__node-default,
.react-flow__node-output,
.react-flow__node-group {
padding: 10px;
border-radius: var(--xy-node-border-radius, var(--xy-node-border-radius-default));
width: 150px;
font-size: 12px;
color: var(--xy-node-color, var(--xy-node-color-default));
text-align: center;
border: var(--xy-node-border, var(--xy-node-border-default));
background-color: var(--xy-node-background-color, var(--xy-node-background-color-default));
}
.react-flow__node-input.selectable:hover, .react-flow__node-default.selectable:hover, .react-flow__node-output.selectable:hover, .react-flow__node-group.selectable:hover {
box-shadow: var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default));
}
.react-flow__node-input.selectable.selected,
.react-flow__node-input.selectable:focus,
.react-flow__node-input.selectable:focus-visible,
.react-flow__node-default.selectable.selected,
.react-flow__node-default.selectable:focus,
.react-flow__node-default.selectable:focus-visible,
.react-flow__node-output.selectable.selected,
.react-flow__node-output.selectable:focus,
.react-flow__node-output.selectable:focus-visible,
.react-flow__node-group.selectable.selected,
.react-flow__node-group.selectable:focus,
.react-flow__node-group.selectable:focus-visible {
box-shadow: var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default));
}
.react-flow__node-group {
background-color: var(--xy-node-group-background-color, var(--xy-node-group-background-color-default));
}
.react-flow__nodesselection-rect,
.react-flow__selection {
background: var(--xy-selection-background-color, var(--xy-selection-background-color-default));
border: var(--xy-selection-border, var(--xy-selection-border-default));
}
.react-flow__nodesselection-rect:focus,
.react-flow__nodesselection-rect:focus-visible,
.react-flow__selection:focus,
.react-flow__selection:focus-visible {
outline: none;
}
.react-flow__controls-button:hover {
background: var(
--xy-controls-button-background-color-hover-props,
var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default))
);
color: var(
--xy-controls-button-color-hover-props,
var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default))
);
}
.react-flow__controls-button:disabled {
pointer-events: none;
}
.react-flow__controls-button:disabled svg {
fill-opacity: 0.4;
}
.react-flow__controls-button:last-child {
border-bottom: none;
}
.react-flow__resize-control {
position: absolute;
}
.react-flow__resize-control.left,
.react-flow__resize-control.right {
cursor: ew-resize;
}
.react-flow__resize-control.top,
.react-flow__resize-control.bottom {
cursor: ns-resize;
}
.react-flow__resize-control.top.left,
.react-flow__resize-control.bottom.right {
cursor: nwse-resize;
}
.react-flow__resize-control.bottom.left,
.react-flow__resize-control.top.right {
cursor: nesw-resize;
}
/* handle styles */
.react-flow__resize-control.handle {
width: 4px;
height: 4px;
border: 1px solid #fff;
border-radius: 1px;
background-color: var(--xy-resize-background-color, var(--xy-resize-background-color-default));
transform: translate(-50%, -50%);
}
.react-flow__resize-control.handle.left {
left: 0;
top: 50%;
}
.react-flow__resize-control.handle.right {
left: 100%;
top: 50%;
}
.react-flow__resize-control.handle.top {
left: 50%;
top: 0;
}
.react-flow__resize-control.handle.bottom {
left: 50%;
top: 100%;
}
.react-flow__resize-control.handle.top.left {
left: 0;
}
.react-flow__resize-control.handle.bottom.left {
left: 0;
}
.react-flow__resize-control.handle.top.right {
left: 100%;
}
.react-flow__resize-control.handle.bottom.right {
left: 100%;
}
/* line styles */
.react-flow__resize-control.line {
border-color: var(--xy-resize-background-color, var(--xy-resize-background-color-default));
border-width: 0;
border-style: solid;
}
.react-flow__resize-control.line.left,
.react-flow__resize-control.line.right {
width: 1px;
transform: translate(-50%, 0);
top: 0;
height: 100%;
}
.react-flow__resize-control.line.left {
left: 0;
border-left-width: 1px;
}
.react-flow__resize-control.line.right {
left: 100%;
border-right-width: 1px;
}
.react-flow__resize-control.line.top,
.react-flow__resize-control.line.bottom {
height: 1px;
transform: translate(0, -50%);
left: 0;
width: 100%;
}
.react-flow__resize-control.line.top {
top: 0;
border-top-width: 1px;
}
.react-flow__resize-control.line.bottom {
border-bottom-width: 1px;
top: 100%;
}
.react-flow__edge-textbg {
fill: var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default));
}
.react-flow__edge-text {
fill: var(--xy-edge-label-color, var(--xy-edge-label-color-default));
}
@podhmo
Copy link
Author

podhmo commented Jan 19, 2025

distには含まれているcssを個別にコピペする必要があるのはバカバカしい気がする。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment