export htmlattributes as props where possible
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@xyflow/svelte",
|
||||
"version": "1.0.0-next.8",
|
||||
"version": "1.0.0-next.9",
|
||||
"description": "Svelte Flow - A highly customizable Svelte library for building node-based editors, workflow systems, diagrams and more.",
|
||||
"keywords": [
|
||||
"svelte",
|
||||
|
||||
@@ -1,41 +1,45 @@
|
||||
<script lang="ts">
|
||||
import { getContext, type Snippet } from 'svelte';
|
||||
import type { ClassValue } from 'svelte/elements';
|
||||
import { getContext } from 'svelte';
|
||||
import { portal } from '$lib/actions/portal';
|
||||
|
||||
import { EdgeLabelRenderer } from '$lib/components/EdgeLabelRenderer';
|
||||
import { useStore } from '$lib/store';
|
||||
import type { EdgeLabelProps } from './types';
|
||||
|
||||
let {
|
||||
x,
|
||||
y,
|
||||
selectEdgeOnClick = false,
|
||||
transparent = false,
|
||||
style,
|
||||
class: className,
|
||||
children
|
||||
}: {
|
||||
x?: number;
|
||||
y?: number;
|
||||
style?: string;
|
||||
class?: ClassValue;
|
||||
children?: Snippet;
|
||||
} = $props();
|
||||
children,
|
||||
...rest
|
||||
}: EdgeLabelProps = $props();
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const id = getContext<string>('svelteflow__edge_id');
|
||||
</script>
|
||||
|
||||
<EdgeLabelRenderer>
|
||||
<div
|
||||
class={['svelte-flow__edge-label', className]}
|
||||
style:transform="translate(-50%, -50%) translate({x}px,{y}px)"
|
||||
style={'pointer-events: all;' + style}
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
onkeyup={() => {}}
|
||||
onclick={() => {
|
||||
if (id) store.handleEdgeSelection(id);
|
||||
}}
|
||||
>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
</EdgeLabelRenderer>
|
||||
<div
|
||||
use:portal={'edgelabel'}
|
||||
class={['svelte-flow__edge-label', { transparent }, className]}
|
||||
style:cursor={selectEdgeOnClick ? 'pointer' : undefined}
|
||||
style:transform="translate(-50%, -50%) translate({x}px,{y}px)"
|
||||
style:pointer-events="all"
|
||||
{style}
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
onclick={() => {
|
||||
if (selectEdgeOnClick && id) store.handleEdgeSelection(id);
|
||||
}}
|
||||
{...rest}
|
||||
>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.transparent {
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default as EdgeLabel } from './EdgeLabel.svelte';
|
||||
export * from './types';
|
||||
|
||||
12
packages/svelte/src/lib/components/EdgeLabel/types.ts
Normal file
12
packages/svelte/src/lib/components/EdgeLabel/types.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
export type EdgeLabelProps = {
|
||||
x?: number;
|
||||
y?: number;
|
||||
selectEdgeOnClick?: boolean;
|
||||
transparent?: boolean;
|
||||
style?: string;
|
||||
class?: ClassValue;
|
||||
children?: Snippet;
|
||||
} & HTMLAttributes<HTMLDivElement>;
|
||||
@@ -4,7 +4,8 @@
|
||||
import { XYHandle, type HandleType, type XYPosition } from '@xyflow/system';
|
||||
import { getContext, type Snippet } from 'svelte';
|
||||
import type { ClassValue } from 'svelte/elements';
|
||||
import { portal } from '$lib/actions/portal';
|
||||
import EdgeLabel from '../EdgeLabel/EdgeLabel.svelte';
|
||||
import type { EdgeReconnectAnchorProps } from './types';
|
||||
|
||||
let {
|
||||
type,
|
||||
@@ -13,16 +14,9 @@
|
||||
class: className,
|
||||
size = 25,
|
||||
style,
|
||||
children
|
||||
}: {
|
||||
type: HandleType;
|
||||
reconnecting?: boolean;
|
||||
style?: string;
|
||||
class?: ClassValue;
|
||||
position?: XYPosition;
|
||||
size?: number;
|
||||
children?: Snippet;
|
||||
} = $props();
|
||||
children,
|
||||
...rest
|
||||
}: EdgeReconnectAnchorProps = $props();
|
||||
|
||||
const store = useStore();
|
||||
|
||||
@@ -110,17 +104,16 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<div
|
||||
use:portal={'edgelabel'}
|
||||
<EdgeLabel
|
||||
x={position?.x}
|
||||
y={position?.y}
|
||||
class={['svelte-flow__edgeupdater nopan', `svelte-flow__edgeupdater-${type}`, className]}
|
||||
style:position="absolute"
|
||||
style:width={`${size}px`}
|
||||
style:height={`${size}px`}
|
||||
style:transform={`translate(-50%, -50%) ${position ? `translate(${position.x}px, ${position.y}px` : ''}`}
|
||||
{style}
|
||||
style={`width:${size}px; height:${size}px;` + style}
|
||||
onpointerdown={onPointerDown}
|
||||
transparent
|
||||
{...rest}
|
||||
>
|
||||
{#if !reconnecting && children}
|
||||
{@render children()}
|
||||
{/if}
|
||||
</div>
|
||||
</EdgeLabel>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default as EdgeReconnectAnchor } from './EdgeReconnectAnchor.svelte';
|
||||
export * from './types';
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { HandleType, XYPosition } from '@xyflow/system';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
export type EdgeReconnectAnchorProps = {
|
||||
type: HandleType;
|
||||
reconnecting?: boolean;
|
||||
style?: string;
|
||||
class?: ClassValue;
|
||||
position?: XYPosition;
|
||||
size?: number;
|
||||
children?: Snippet;
|
||||
} & HTMLAttributes<HTMLDivElement>;
|
||||
@@ -4,19 +4,20 @@
|
||||
Position,
|
||||
XYHandle,
|
||||
isMouseEvent,
|
||||
type HandleConnection,
|
||||
areConnectionMapsEqual,
|
||||
handleConnectionChange,
|
||||
ConnectionMode,
|
||||
getHostForElement,
|
||||
type HandleConnection,
|
||||
type Optional,
|
||||
type ConnectionState,
|
||||
type Connection
|
||||
} from '@xyflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
import type { HandleProps } from '$lib/types';
|
||||
|
||||
import type { ConnectableContext } from '../NodeWrapper/types';
|
||||
import type { HandleProps } from './types';
|
||||
|
||||
let {
|
||||
id: handleId = null,
|
||||
@@ -30,7 +31,8 @@
|
||||
isValidConnection,
|
||||
onconnect,
|
||||
ondisconnect,
|
||||
children
|
||||
children,
|
||||
...rest
|
||||
}: HandleProps = $props();
|
||||
|
||||
const nodeId = getContext<string>('svelteflow__node_id');
|
||||
@@ -226,6 +228,7 @@ The Handle component is the part of a node that can be used to connect nodes.
|
||||
{style}
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
{...rest}
|
||||
>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default as Handle } from './Handle.svelte';
|
||||
export * from './types';
|
||||
|
||||
10
packages/svelte/src/lib/components/Handle/types.ts
Normal file
10
packages/svelte/src/lib/components/Handle/types.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { Connection, HandleProps as HandlePropsSystem } from '@xyflow/system';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
export type HandleProps = HandlePropsSystem & {
|
||||
class?: ClassValue;
|
||||
onconnect?: (connections: Connection[]) => void;
|
||||
ondisconnect?: (connections: Connection[]) => void;
|
||||
children?: Snippet;
|
||||
} & HTMLAttributes<HTMLDivElement>;
|
||||
@@ -1,11 +1,10 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
import { portal } from '$lib/actions/portal';
|
||||
import type { ViewportPortalProps } from './types';
|
||||
|
||||
let { children }: { children?: Snippet } = $props();
|
||||
let { children, ...rest }: ViewportPortalProps = $props();
|
||||
</script>
|
||||
|
||||
<div use:portal={'viewport'}>
|
||||
<div use:portal={'viewport'} {...rest}>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default as ViewportPortal } from './ViewportPortal.svelte';
|
||||
export * from './types';
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
export type ViewportPortalProps = {
|
||||
children?: Snippet;
|
||||
} & HTMLAttributes<HTMLDivElement>;
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import type { BaseEdgeProps } from '../../types';
|
||||
import EdgeLabel from '../EdgeLabel/EdgeLabel.svelte';
|
||||
|
||||
@@ -16,7 +15,7 @@
|
||||
interactionWidth = 20,
|
||||
class: className,
|
||||
...rest
|
||||
}: BaseEdgeProps & HTMLAttributes<SVGPathElement> = $props();
|
||||
}: BaseEdgeProps = $props();
|
||||
</script>
|
||||
|
||||
<path
|
||||
@@ -41,7 +40,7 @@
|
||||
{/if}
|
||||
|
||||
{#if label}
|
||||
<EdgeLabel x={labelX} y={labelY} style={labelStyle}>
|
||||
<EdgeLabel x={labelX} y={labelY} style={labelStyle} selectEdgeOnClick>
|
||||
{label}
|
||||
</EdgeLabel>
|
||||
{/if}
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div
|
||||
bind:this={container}
|
||||
class="svelte-flow__pane"
|
||||
class="svelte-flow__pane svelte-flow__container"
|
||||
class:draggable={panOnDrag === true || (Array.isArray(panOnDrag) && panOnDrag.includes(0))}
|
||||
class:dragging={store.dragging}
|
||||
class:selection={isSelecting}
|
||||
@@ -230,13 +230,3 @@
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.svelte-flow__pane {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default as Pane } from './Pane.svelte';
|
||||
export * from './types';
|
||||
|
||||
@@ -2,13 +2,7 @@
|
||||
import type { PanelProps } from './types';
|
||||
import { useStore } from '$lib/store';
|
||||
|
||||
let {
|
||||
position = 'top-right',
|
||||
style,
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
}: PanelProps = $props();
|
||||
let { position = 'top-right', style, class: className, children, ...rest }: PanelProps = $props();
|
||||
|
||||
const store = useStore();
|
||||
|
||||
@@ -19,7 +13,7 @@
|
||||
class={['svelte-flow__panel', className, ...positionClasses]}
|
||||
{style}
|
||||
style:pointer-events={store.selectionRectMode ? 'none' : ''}
|
||||
{...restProps}
|
||||
{...rest}
|
||||
>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export { default as Panel } from './Panel.svelte';
|
||||
export type { PanelProps } from './types';
|
||||
export * from './types';
|
||||
|
||||
@@ -6,19 +6,9 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="svelte-flow__viewport xyflow__viewport"
|
||||
class="svelte-flow__viewport xyflow__viewport svelte-flow__container"
|
||||
style="transform: translate({store.viewport.x}px, {store.viewport.y}px) scale({store.viewport
|
||||
.zoom})"
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.svelte-flow__viewport {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="svelte-flow__zoom"
|
||||
class="svelte-flow__zoom svelte-flow__container"
|
||||
use:zoom={{
|
||||
viewport: store.viewport,
|
||||
minZoom: store.minZoom,
|
||||
@@ -74,14 +74,3 @@
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.svelte-flow__zoom {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -55,7 +55,7 @@ export type {
|
||||
EdgeTypes,
|
||||
DefaultEdgeOptions
|
||||
} from '$lib/types/edges';
|
||||
export type { HandleProps, FitViewOptions, OnBeforeDelete } from '$lib/types/general';
|
||||
export type { FitViewOptions, OnBeforeDelete } from '$lib/types/general';
|
||||
export type { Node, NodeTypes, BuiltInNode, NodeProps, InternalNode } from '$lib/types/nodes';
|
||||
export type { SvelteFlowStore } from '$lib/store/types';
|
||||
export * from '$lib/types/events';
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</script>
|
||||
|
||||
<svg
|
||||
class={['svelte-flow__background', className]}
|
||||
class={['svelte-flow__background', 'svelte-flow__container', className]}
|
||||
data-testid="svelte-flow__background"
|
||||
style:--xy-background-color-props={bgColor}
|
||||
style:--xy-background-pattern-color-props={patternColor}
|
||||
@@ -69,13 +69,3 @@
|
||||
</pattern>
|
||||
<rect x="0" y="0" width="100%" height="100%" fill={`url(#${patternId})`} />
|
||||
</svg>
|
||||
|
||||
<style>
|
||||
.svelte-flow__background {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
fitViewOptions,
|
||||
children,
|
||||
before,
|
||||
after
|
||||
after,
|
||||
...rest
|
||||
}: ControlsProps = $props();
|
||||
|
||||
const store = useStore();
|
||||
@@ -74,6 +75,7 @@
|
||||
data-testid="svelte-flow__controls"
|
||||
aria-label={ariaLabel ?? 'Svelte Flow controls'}
|
||||
{style}
|
||||
{...rest}
|
||||
>
|
||||
{#if before}
|
||||
{@render before()}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { ClassValue, HTMLButtonAttributes } from 'svelte/elements';
|
||||
import type { ClassValue, HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
||||
import type { PanelPosition } from '@xyflow/system';
|
||||
|
||||
import type { FitViewOptions } from '$lib/types';
|
||||
@@ -29,7 +29,7 @@ export type ControlsProps = {
|
||||
before?: Snippet;
|
||||
after?: Snippet;
|
||||
fitViewOptions?: FitViewOptions;
|
||||
};
|
||||
} & HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
export type ControlButtonProps = HTMLButtonAttributes & {
|
||||
class?: ClassValue;
|
||||
|
||||
@@ -43,8 +43,6 @@
|
||||
|
||||
let store = useStore();
|
||||
|
||||
// let nodes = $derived(store.nodes);
|
||||
|
||||
const nodeColorFunc = nodeColor === undefined ? undefined : getAttrFunction(nodeColor);
|
||||
const nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor);
|
||||
const nodeClassFunc = getAttrFunction(nodeClass);
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
align = 'center',
|
||||
offset = 10,
|
||||
isVisible,
|
||||
children
|
||||
children,
|
||||
...rest
|
||||
}: NodeToolbarProps = $props();
|
||||
|
||||
const store = useStore();
|
||||
@@ -66,12 +67,13 @@
|
||||
|
||||
{#if store.domNode && isActive && toolbarNodes}
|
||||
<div
|
||||
data-id={toolbarNodes.reduce((acc, node) => `${acc}${node.id} `, '').trim()}
|
||||
class="svelte-flow__node-toolbar"
|
||||
use:portal={'root'}
|
||||
class="svelte-flow__node-toolbar"
|
||||
data-id={toolbarNodes.reduce((acc, node) => `${acc}${node.id} `, '').trim()}
|
||||
style:position="absolute"
|
||||
style:transform
|
||||
style:z-index={zIndex}
|
||||
{...rest}
|
||||
>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Position, Align } from '@xyflow/system';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
export type NodeToolbarProps = {
|
||||
/** The id of the node, or array of ids the toolbar should be displayed at */
|
||||
@@ -18,4 +19,4 @@ export type NodeToolbarProps = {
|
||||
/** If true, node toolbar is visible even if node is not selected */
|
||||
isVisible?: boolean;
|
||||
children?: Snippet;
|
||||
};
|
||||
} & HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {
|
||||
} from '@xyflow/system';
|
||||
|
||||
import type { Node } from '$lib/types';
|
||||
import type { ClassValue } from 'svelte/elements';
|
||||
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
/**
|
||||
* An `Edge` is the complete description with everything Svelte Flow needs to know in order to
|
||||
@@ -46,7 +46,7 @@ export type BaseEdgeProps = Pick<
|
||||
*/
|
||||
markerEnd?: string;
|
||||
class?: ClassValue;
|
||||
};
|
||||
} & HTMLAttributes<SVGPathElement>;
|
||||
|
||||
type SmoothStepEdge<EdgeData extends Record<string, unknown> = Record<string, unknown>> = Edge<
|
||||
EdgeData,
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { ClassValue } from 'svelte/elements';
|
||||
import type { ShortcutModifierDefinition } from '@svelte-put/shortcut';
|
||||
import type {
|
||||
FitViewOptionsBase,
|
||||
XYPosition,
|
||||
Handle,
|
||||
Connection,
|
||||
OnBeforeDeleteBase,
|
||||
HandleProps as HandlePropsSystem
|
||||
OnBeforeDeleteBase
|
||||
} from '@xyflow/system';
|
||||
|
||||
import type { Node } from './nodes';
|
||||
@@ -24,14 +21,6 @@ export type ConnectionData = {
|
||||
connectionStatus: string | null;
|
||||
};
|
||||
|
||||
export type HandleProps = HandlePropsSystem & {
|
||||
class?: ClassValue;
|
||||
style?: string;
|
||||
onconnect?: (connections: Connection[]) => void;
|
||||
ondisconnect?: (connections: Connection[]) => void;
|
||||
children?: Snippet;
|
||||
};
|
||||
|
||||
export type FitViewOptions<NodeType extends Node = Node> = FitViewOptionsBase<NodeType>;
|
||||
|
||||
export type OnDelete = (params: { nodes: Node[]; edges: Edge[] }) => void;
|
||||
|
||||
@@ -7,3 +7,15 @@
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.svelte-flow__nodes {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.svelte-flow__edgelabel-renderer {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.svelte-flow__zoom {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
position: absolute;
|
||||
padding: 2px;
|
||||
font-size: 10px;
|
||||
cursor: pointer;
|
||||
color: var(--xy-edge-label-color, var(--xy-edge-label-color-default));
|
||||
background: var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default));
|
||||
}
|
||||
@@ -20,3 +19,7 @@
|
||||
.svelte-flow__edgelabel-renderer {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.svelte-flow__zoom {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user