migrating hooks, fixed colorMode
This commit is contained in:
@@ -56,11 +56,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^3.3.1",
|
||||
"@sveltejs/kit": "^2.9.0",
|
||||
"@sveltejs/kit": "^2.11.1",
|
||||
"@sveltejs/package": "^2.3.7",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.17.0",
|
||||
"@typescript-eslint/parser": "^8.17.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.18.0",
|
||||
"@typescript-eslint/parser": "^8.18.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cssnano": "^7.0.6",
|
||||
"dotenv": "^16.4.7",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { get } from 'svelte/store';
|
||||
import {
|
||||
shortcut,
|
||||
type ShortcutEventDetail,
|
||||
@@ -7,7 +6,6 @@
|
||||
} from '@svelte-put/shortcut';
|
||||
import { getElementsToRemove, isInputDOMNode, isMacOs } from '@xyflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
import type { KeyHandlerProps } from './types';
|
||||
import type { KeyDefinition, KeyDefinitionObject } from '$lib/types';
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
onselectioncontextmenu
|
||||
}: NodeSelectionProps = $props();
|
||||
|
||||
// const { nodes } = store;
|
||||
|
||||
let bounds: Rect | null = $derived.by(() => {
|
||||
if (store.selectionRectMode === 'nodes') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
||||
|
||||
import type { ConnectableContext, NodeWrapperProps } from './types';
|
||||
import type { Node, NodeEvents } from '$lib/types';
|
||||
import type { NodeEvents } from '$lib/types';
|
||||
|
||||
let {
|
||||
store,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
let { children }: SvelteFlowProviderProps = $props();
|
||||
|
||||
let store = $state.raw(createStore({ props: {} }));
|
||||
let store = $state.raw(createStore({ props: {}, nodes: [], edges: [] }));
|
||||
|
||||
setContext(key, {
|
||||
provider: true,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
import type { Node, Edge, InternalNode } from '$lib/types';
|
||||
import type { PaneProps } from './types';
|
||||
|
||||
let {
|
||||
store,
|
||||
panOnDrag = true,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import cc from 'classcat';
|
||||
import { PanOnScrollMode } from '@xyflow/system';
|
||||
|
||||
import { key, createStore } from '$lib/store';
|
||||
import { Zoom } from '$lib/container/Zoom';
|
||||
import { Pane } from '$lib/container/Pane';
|
||||
import { Viewport as ViewportComponent } from '$lib/container/Viewport';
|
||||
@@ -13,9 +14,7 @@
|
||||
import { KeyHandler } from '$lib/components/KeyHandler';
|
||||
import { ConnectionLine } from '$lib/components/ConnectionLine';
|
||||
import { Attribution } from '$lib/components/Attribution';
|
||||
import { key, createStore } from '$lib/store';
|
||||
import type { SvelteFlowProps } from './types';
|
||||
import { useColorModeClass } from '$lib/hooks/useColorModeClass';
|
||||
import { type ProviderContext, type StoreContext } from '$lib/store/types';
|
||||
|
||||
let {
|
||||
@@ -114,91 +113,86 @@
|
||||
onDestroy(() => {
|
||||
store.reset();
|
||||
});
|
||||
|
||||
let colorModeClass = $derived(useColorModeClass(store.colorMode));
|
||||
</script>
|
||||
|
||||
<!-- TODO: this is the only hack in the library so far. Can we get rid of it? -->
|
||||
{#if store.adoptNodes && store.adoptEdges}
|
||||
<div
|
||||
bind:this={domNode}
|
||||
bind:clientWidth
|
||||
bind:clientHeight
|
||||
style:width
|
||||
style:height
|
||||
{style}
|
||||
class={cc(['svelte-flow', className, $colorModeClass])}
|
||||
data-testid="svelte-flow__wrapper"
|
||||
{...props}
|
||||
role="application"
|
||||
<div
|
||||
bind:this={domNode}
|
||||
bind:clientWidth
|
||||
bind:clientHeight
|
||||
style:width
|
||||
style:height
|
||||
{style}
|
||||
class={cc(['svelte-flow', className, store.colorMode])}
|
||||
data-testid="svelte-flow__wrapper"
|
||||
{...props}
|
||||
role="application"
|
||||
>
|
||||
<KeyHandler
|
||||
{store}
|
||||
{selectionKey}
|
||||
{deleteKey}
|
||||
{panActivationKey}
|
||||
{multiSelectionKey}
|
||||
{zoomActivationKey}
|
||||
/>
|
||||
<Zoom
|
||||
{store}
|
||||
{onMoveStart}
|
||||
{onMove}
|
||||
{onMoveEnd}
|
||||
{panOnScrollMode}
|
||||
{preventScrolling}
|
||||
{zoomOnScroll}
|
||||
{zoomOnDoubleClick}
|
||||
{zoomOnPinch}
|
||||
{panOnScroll}
|
||||
{panOnDrag}
|
||||
{paneClickDistance}
|
||||
>
|
||||
<KeyHandler
|
||||
{store}
|
||||
{selectionKey}
|
||||
{deleteKey}
|
||||
{panActivationKey}
|
||||
{multiSelectionKey}
|
||||
{zoomActivationKey}
|
||||
/>
|
||||
<Zoom
|
||||
{store}
|
||||
{onMoveStart}
|
||||
{onMove}
|
||||
{onMoveEnd}
|
||||
{panOnScrollMode}
|
||||
{preventScrolling}
|
||||
{zoomOnScroll}
|
||||
{zoomOnDoubleClick}
|
||||
{zoomOnPinch}
|
||||
{panOnScroll}
|
||||
{panOnDrag}
|
||||
{paneClickDistance}
|
||||
>
|
||||
<Pane {store} {onpaneclick} {onpanecontextmenu} {panOnDrag} {selectionOnDrag}>
|
||||
<ViewportComponent {store}>
|
||||
<EdgeRenderer
|
||||
{store}
|
||||
{onedgeclick}
|
||||
{onedgecontextmenu}
|
||||
{onedgemouseenter}
|
||||
{onedgemouseleave}
|
||||
/>
|
||||
<ConnectionLine
|
||||
{store}
|
||||
containerStyle={connectionLineContainerStyle}
|
||||
style={connectionLineStyle}
|
||||
{connectionLine}
|
||||
/>
|
||||
<div class="svelte-flow__edgelabel-renderer"></div>
|
||||
<div class="svelte-flow__viewport-portal"></div>
|
||||
<NodeRenderer
|
||||
{store}
|
||||
{nodeClickDistance}
|
||||
{onnodeclick}
|
||||
{onnodecontextmenu}
|
||||
{onnodemouseenter}
|
||||
{onnodemousemove}
|
||||
{onnodemouseleave}
|
||||
{onnodedrag}
|
||||
{onnodedragstart}
|
||||
{onnodedragstop}
|
||||
/>
|
||||
<NodeSelection
|
||||
{store}
|
||||
{onselectionclick}
|
||||
{onselectioncontextmenu}
|
||||
{onnodedrag}
|
||||
{onnodedragstart}
|
||||
{onnodedragstop}
|
||||
/>
|
||||
</ViewportComponent>
|
||||
<UserSelection />
|
||||
</Pane>
|
||||
</Zoom>
|
||||
<Attribution {proOptions} position={attributionPosition} />
|
||||
{@render children?.()}
|
||||
</div>
|
||||
{/if}
|
||||
<Pane {store} {onpaneclick} {onpanecontextmenu} {panOnDrag} {selectionOnDrag}>
|
||||
<ViewportComponent {store}>
|
||||
<EdgeRenderer
|
||||
{store}
|
||||
{onedgeclick}
|
||||
{onedgecontextmenu}
|
||||
{onedgemouseenter}
|
||||
{onedgemouseleave}
|
||||
/>
|
||||
<ConnectionLine
|
||||
{store}
|
||||
containerStyle={connectionLineContainerStyle}
|
||||
style={connectionLineStyle}
|
||||
{connectionLine}
|
||||
/>
|
||||
<div class="svelte-flow__edgelabel-renderer"></div>
|
||||
<div class="svelte-flow__viewport-portal"></div>
|
||||
<NodeRenderer
|
||||
{store}
|
||||
{nodeClickDistance}
|
||||
{onnodeclick}
|
||||
{onnodecontextmenu}
|
||||
{onnodemouseenter}
|
||||
{onnodemousemove}
|
||||
{onnodemouseleave}
|
||||
{onnodedrag}
|
||||
{onnodedragstart}
|
||||
{onnodedragstop}
|
||||
/>
|
||||
<NodeSelection
|
||||
{store}
|
||||
{onselectionclick}
|
||||
{onselectioncontextmenu}
|
||||
{onnodedrag}
|
||||
{onnodedragstart}
|
||||
{onnodedragstop}
|
||||
/>
|
||||
</ViewportComponent>
|
||||
<UserSelection />
|
||||
</Pane>
|
||||
</Zoom>
|
||||
<Attribution {proOptions} position={attributionPosition} />
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.svelte-flow {
|
||||
|
||||
@@ -17,7 +17,8 @@ import type {
|
||||
ColorMode,
|
||||
OnConnect,
|
||||
OnConnectStart,
|
||||
OnConnectEnd
|
||||
OnConnectEnd,
|
||||
ColorModeClass
|
||||
} from '@xyflow/system';
|
||||
|
||||
import type {
|
||||
@@ -327,6 +328,8 @@ export type SvelteFlowProps = NodeEvents &
|
||||
* @example 'system' | 'light' | 'dark'
|
||||
*/
|
||||
colorMode?: ColorMode;
|
||||
/** Fallback color mode for SSR if colorMode is set to 'system' */
|
||||
colorModeSSR?: ColorModeClass;
|
||||
/** Class to be applied to the flow container */
|
||||
class?: string;
|
||||
/** Styles to be applied to the flow container */
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { PanOnScrollMode, type PanZoomInstance, type Transform } from '@xyflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
import zoom from '$lib/actions/zoom';
|
||||
import type { ZoomProps } from './types';
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { ColorModeClass } from '@xyflow/system';
|
||||
import { useStore } from './useStore';
|
||||
|
||||
/**
|
||||
* Hook for receiving the current color mode class 'dark' or 'light'.
|
||||
*
|
||||
*/
|
||||
export function useColorMode(): { current: ColorModeClass } {
|
||||
const { colorMode } = $derived(useStore());
|
||||
|
||||
return {
|
||||
current: colorMode
|
||||
};
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import type { ColorMode, ColorModeClass } from '@xyflow/system';
|
||||
import { readable, type Readable } from 'svelte/store';
|
||||
|
||||
function getMediaQuery() {
|
||||
if (typeof window === 'undefined' || !window.matchMedia) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return window.matchMedia('(prefers-color-scheme: dark)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for receiving the current color mode class 'dark' or 'light'.
|
||||
*
|
||||
* @internal
|
||||
* @param colorMode - The color mode to use ('dark', 'light' or 'system')
|
||||
*/
|
||||
export function useColorModeClass(colorMode: ColorMode = 'light'): Readable<ColorModeClass> {
|
||||
const colorModeClass = readable<ColorModeClass>('light', (set) => {
|
||||
if (colorMode !== 'system') {
|
||||
set(colorMode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const mediaQuery = getMediaQuery();
|
||||
const updateColorModeClass = () => set(mediaQuery?.matches ? 'dark' : 'light');
|
||||
|
||||
set(mediaQuery?.matches ? 'dark' : 'light');
|
||||
mediaQuery?.addEventListener('change', updateColorModeClass);
|
||||
|
||||
return () => {
|
||||
mediaQuery?.removeEventListener('change', updateColorModeClass);
|
||||
};
|
||||
});
|
||||
|
||||
return colorModeClass;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { useStore } from '$lib/store';
|
||||
|
||||
import type { ConnectionState } from '@xyflow/system';
|
||||
|
||||
/**
|
||||
* Hook for receiving the current connection.
|
||||
*
|
||||
* @public
|
||||
* @returns current connection as a readable store
|
||||
*/
|
||||
export function useConnection(): { current: ConnectionState } {
|
||||
const { connection } = $derived(useStore());
|
||||
|
||||
return {
|
||||
get current() {
|
||||
return connection;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { useStore } from '$lib/store';
|
||||
|
||||
import type { ConnectionState } from '@xyflow/system';
|
||||
import { derivedWarning } from './derivedWarning.svelte';
|
||||
|
||||
/**
|
||||
* Hook for receiving the current connection.
|
||||
*
|
||||
* @public
|
||||
* @returns current connection as a readable store
|
||||
*/
|
||||
export function useConnection(): ConnectionState {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
derivedWarning('useConnection', true);
|
||||
}
|
||||
|
||||
return useStore().connection;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { areConnectionMapsEqual, type HandleConnection, type HandleType } from '@xyflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
export type useHandleConnectionsParams = {
|
||||
type: HandleType;
|
||||
nodeId?: string;
|
||||
id?: string | null;
|
||||
};
|
||||
|
||||
const initialConnections: HandleConnection[] = [];
|
||||
|
||||
/**
|
||||
* Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
|
||||
*
|
||||
* @public
|
||||
* @param param.nodeId
|
||||
* @param param.type - handle type 'source' or 'target'
|
||||
* @param param.id - the handle id (this is only needed if the node has multiple handles of the same type)
|
||||
* @returns an array with connections
|
||||
*/
|
||||
export function useHandleConnections({
|
||||
type,
|
||||
nodeId: _nodeId,
|
||||
id = null
|
||||
}: useHandleConnectionsParams) {
|
||||
const { edges, connectionLookup } = $derived(useStore());
|
||||
|
||||
const contextNodeId = getContext<string>('svelteflow__node_id');
|
||||
const nodeId = _nodeId ?? contextNodeId;
|
||||
|
||||
let prevConnections: Map<string, HandleConnection> | undefined = new Map();
|
||||
let connectionsArray: HandleConnection[] = initialConnections;
|
||||
|
||||
const connections = $derived.by(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
edges;
|
||||
const nextConnections = connectionLookup.get(`${nodeId}-${type}-${id || null}`);
|
||||
if (!areConnectionMapsEqual(nextConnections, prevConnections)) {
|
||||
prevConnections = nextConnections;
|
||||
connectionsArray = Array.from(nextConnections?.values() || initialConnections);
|
||||
}
|
||||
return connectionsArray;
|
||||
});
|
||||
|
||||
return {
|
||||
get current() {
|
||||
return connections;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import { derived } from 'svelte/store';
|
||||
import { areConnectionMapsEqual, type HandleConnection, type HandleType } from '@xyflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
export type useHandleConnectionsParams = {
|
||||
type: HandleType;
|
||||
nodeId?: string;
|
||||
id?: string | null;
|
||||
};
|
||||
|
||||
const initialConnections: HandleConnection[] = [];
|
||||
|
||||
/**
|
||||
* Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
|
||||
*
|
||||
* @public
|
||||
* @param param.nodeId
|
||||
* @param param.type - handle type 'source' or 'target'
|
||||
* @param param.id - the handle id (this is only needed if the node has multiple handles of the same type)
|
||||
* @returns an array with connections
|
||||
*/
|
||||
export function useHandleConnections({ type, nodeId, id = null }: useHandleConnectionsParams) {
|
||||
const { edges, connectionLookup } = useStore();
|
||||
|
||||
const _nodeId = getContext<string>('svelteflow__node_id');
|
||||
const currentNodeId = nodeId ?? _nodeId;
|
||||
|
||||
let prevConnections: Map<string, HandleConnection> | undefined = undefined;
|
||||
|
||||
return derived(
|
||||
[edges, connectionLookup],
|
||||
([, connectionLookup], set) => {
|
||||
const nextConnections = connectionLookup.get(`${currentNodeId}-${type}-${id || null}`);
|
||||
|
||||
if (!areConnectionMapsEqual(nextConnections, prevConnections)) {
|
||||
prevConnections = nextConnections;
|
||||
set(Array.from(prevConnections?.values() || []));
|
||||
}
|
||||
},
|
||||
initialConnections
|
||||
);
|
||||
}
|
||||
@@ -33,9 +33,9 @@ export * from '$lib/utils';
|
||||
//hooks
|
||||
export * from '$lib/hooks/useSvelteFlow';
|
||||
export * from '$lib/hooks/useUpdateNodeInternals';
|
||||
export * from '$lib/hooks/useConnection';
|
||||
export * from '$lib/hooks/useConnection.svelte';
|
||||
export * from '$lib/hooks/useNodesEdges';
|
||||
export * from '$lib/hooks/useHandleConnections';
|
||||
export * from '$lib/hooks/useHandleConnections.svelte';
|
||||
export * from '$lib/hooks/useNodesData';
|
||||
export * from '$lib/hooks/useInternalNode';
|
||||
export { useInitialized, useNodesInitialized } from '$lib/hooks/useInitialized';
|
||||
|
||||
@@ -218,20 +218,37 @@ export function createStore(signals: StoreSignals): SvelteFlowStore {
|
||||
store.panZoom?.setClickDistance(distance);
|
||||
}
|
||||
|
||||
function deselect<T extends Node | Edge>(element: T) {
|
||||
return element.selected ? { ...element, selected: false } : element;
|
||||
function deselect<T extends Node | Edge>(
|
||||
elements: T[],
|
||||
elementsToDeselect: Set<string> | null = null
|
||||
): [boolean, T[]] {
|
||||
let deselected = false;
|
||||
|
||||
const newElements = elements.map((element) => {
|
||||
const shouldDeselect = elementsToDeselect ? elementsToDeselect.has(element.id) : true;
|
||||
|
||||
if (shouldDeselect && element.selected) {
|
||||
deselected = true;
|
||||
return { ...element, selected: false };
|
||||
}
|
||||
return element;
|
||||
});
|
||||
|
||||
return [deselected, newElements];
|
||||
}
|
||||
|
||||
function unselectNodesAndEdges(params?: { nodes?: Node[]; edges?: Edge[] }) {
|
||||
const nodesToDeselect = params?.nodes ? new Set(params.nodes.map((node) => node.id)) : null;
|
||||
store.nodes = store.nodes.map((node) =>
|
||||
!nodesToDeselect || nodesToDeselect.has(node.id) ? deselect(node) : node
|
||||
);
|
||||
const [nodesDeselected, newNodes] = deselect(store.nodes, nodesToDeselect);
|
||||
if (nodesDeselected) {
|
||||
store.nodes = newNodes;
|
||||
}
|
||||
|
||||
const edgesToDeselect = params?.edges ? new Set(params.edges.map((node) => node.id)) : null;
|
||||
store.edges = store.edges.map((edge) =>
|
||||
!edgesToDeselect || edgesToDeselect.has(edge.id) ? deselect(edge) : edge
|
||||
);
|
||||
const [edgesDeselected, newEdges] = deselect(store.edges, edgesToDeselect);
|
||||
if (edgesDeselected) {
|
||||
store.edges = newEdges;
|
||||
}
|
||||
}
|
||||
|
||||
function addSelectedNodes(ids: string[]) {
|
||||
@@ -252,9 +269,7 @@ export function createStore(signals: StoreSignals): SvelteFlowStore {
|
||||
});
|
||||
|
||||
if (!isMultiSelection) {
|
||||
store.edges = store.edges.map((edge) => {
|
||||
return edge.selected ? { ...edge, selected: false } : edge;
|
||||
});
|
||||
unselectNodesAndEdges({ nodes: [] });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +287,7 @@ export function createStore(signals: StoreSignals): SvelteFlowStore {
|
||||
});
|
||||
|
||||
if (!isMultiSelection) {
|
||||
store.nodes = store.nodes.map(deselect);
|
||||
unselectNodesAndEdges({ edges: [] });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ import {
|
||||
type NodeLookup,
|
||||
type ConnectionState,
|
||||
getInternalNodesBounds,
|
||||
type ColorMode,
|
||||
createMarkerIds,
|
||||
type EdgeLookup,
|
||||
type ConnectionLookup,
|
||||
type ParentLookup,
|
||||
pointToRendererPoint
|
||||
pointToRendererPoint,
|
||||
type ColorModeClass
|
||||
} from '@xyflow/system';
|
||||
|
||||
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
||||
@@ -55,6 +55,7 @@ import type {
|
||||
} from '$lib/types';
|
||||
|
||||
import type { StoreSignals } from './types';
|
||||
import { MediaQuery } from 'svelte/reactivity';
|
||||
|
||||
export const initialNodeTypes = {
|
||||
input: InputNode,
|
||||
@@ -74,14 +75,29 @@ export const getInitialStore = (signals: StoreSignals) => {
|
||||
// We use a class here, because Svelte adds getters & setter for us.
|
||||
// Inline classes have some performance implications but we just call it once (max twice).
|
||||
class SvelteFlowStore {
|
||||
get nodes() {
|
||||
_nodes: Node[] = $derived.by(() => {
|
||||
adoptUserNodes(signals.nodes, this.nodeLookup, this.parentLookup, {
|
||||
nodeExtent: this.nodeExtent,
|
||||
nodeOrigin: this.nodeOrigin,
|
||||
elevateNodesOnSelect: false,
|
||||
checkEquality: true
|
||||
});
|
||||
return signals.nodes;
|
||||
});
|
||||
|
||||
_edges: Edge[] = $derived.by(() => {
|
||||
updateConnectionLookup(this.connectionLookup, this.edgeLookup, signals.edges);
|
||||
return signals.edges;
|
||||
});
|
||||
|
||||
get nodes() {
|
||||
return this._nodes;
|
||||
}
|
||||
set nodes(nodes) {
|
||||
signals.nodes = nodes;
|
||||
}
|
||||
get edges() {
|
||||
return signals.edges;
|
||||
return this._edges;
|
||||
}
|
||||
set edges(edges) {
|
||||
signals.edges = edges;
|
||||
@@ -91,20 +107,6 @@ export const getInitialStore = (signals: StoreSignals) => {
|
||||
connectionLookup: ConnectionLookup = new Map();
|
||||
edgeLookup: EdgeLookup = new Map();
|
||||
|
||||
adoptNodes: true = $derived.by(() => {
|
||||
adoptUserNodes(signals.nodes, this.nodeLookup, this.parentLookup, {
|
||||
nodeExtent: this.nodeExtent,
|
||||
nodeOrigin: this.nodeOrigin,
|
||||
elevateNodesOnSelect: false,
|
||||
checkEquality: true
|
||||
});
|
||||
return true;
|
||||
});
|
||||
adoptEdges: true = $derived.by(() => {
|
||||
updateConnectionLookup(this.connectionLookup, this.edgeLookup, signals.edges);
|
||||
return true;
|
||||
});
|
||||
|
||||
domNode: HTMLDivElement | null = $derived(signals.domNode ?? signals.domNode ?? null);
|
||||
width: number = $derived(signals.width ?? signals.props.width ?? 0);
|
||||
height: number = $derived(signals.height ?? signals.props.height ?? 0);
|
||||
@@ -212,7 +214,17 @@ export const getInitialStore = (signals: StoreSignals) => {
|
||||
|
||||
return initialized;
|
||||
});
|
||||
colorMode: ColorMode = $derived(signals.props.colorMode ?? 'light');
|
||||
prefersDark = new MediaQuery(
|
||||
'(prefers-color-scheme: dark)',
|
||||
signals.props.colorModeSSR === 'dark'
|
||||
);
|
||||
colorMode: ColorModeClass = $derived(
|
||||
signals.props.colorMode === 'system'
|
||||
? this.prefersDark.current
|
||||
? 'dark'
|
||||
: 'light'
|
||||
: (signals.props.colorMode ?? 'light')
|
||||
);
|
||||
|
||||
constructor() {
|
||||
// Process intial fitView here
|
||||
|
||||
Reference in New Issue
Block a user