minimize inline style usage

This commit is contained in:
peterkogo
2025-04-15 12:57:34 +02:00
parent 2ca682c6f2
commit 1fa3b50366
18 changed files with 65 additions and 91 deletions
@@ -222,7 +222,7 @@
> >
</Controls> </Controls>
<Background variant={BackgroundVariant.Dots} /> <Background variant={BackgroundVariant.Dots} />
<MiniMap /> <MiniMap bgColor={'red'} />
<Panel position="top-right"> <Panel position="top-right">
<button onclick={moveNode}>update node pos</button> <button onclick={moveNode}>update node pos</button>
<button onclick={changeEdgeType}>update edge type</button> <button onclick={changeEdgeType}>update edge type</button>
@@ -13,14 +13,14 @@
let { let {
store = $bindable(), store = $bindable(),
type, type,
containerStyle = '', containerStyle,
style = '', style,
LineComponent LineComponent
}: { }: {
store: SvelteFlowStore; store: SvelteFlowStore;
type: ConnectionLineType; type: ConnectionLineType;
containerStyle: string; containerStyle?: string;
style: string; style?: string;
LineComponent?: Component; LineComponent?: Component;
} = $props(); } = $props();
@@ -4,10 +4,13 @@
import { useStore } from '$lib/store'; import { useStore } from '$lib/store';
import type { EdgeLabelProps } from './types'; import type { EdgeLabelProps } from './types';
import { toPxString } from '$lib/utils';
let { let {
x, x = 0,
y, y = 0,
width,
height,
selectEdgeOnClick = false, selectEdgeOnClick = false,
transparent = false, transparent = false,
style, style,
@@ -27,7 +30,8 @@
style:cursor={selectEdgeOnClick ? 'pointer' : undefined} style:cursor={selectEdgeOnClick ? 'pointer' : undefined}
style:transform="translate(-50%, -50%) translate({x}px,{y}px)" style:transform="translate(-50%, -50%) translate({x}px,{y}px)"
style:pointer-events="all" style:pointer-events="all"
{style} style:width={toPxString(width)}
style:height={toPxString(height)}
role="button" role="button"
tabindex="-1" tabindex="-1"
onclick={() => { onclick={() => {
@@ -1,12 +1,13 @@
import type { Dimensions, XYPosition } from '@xyflow/system';
import type { Snippet } from 'svelte'; import type { Snippet } from 'svelte';
import type { ClassValue, HTMLAttributes } from 'svelte/elements'; import type { ClassValue, HTMLAttributes } from 'svelte/elements';
export type EdgeLabelProps = { export type EdgeLabelProps = {
x?: number; x?: number;
y?: number; y?: number;
width?: number;
height?: number;
selectEdgeOnClick?: boolean; selectEdgeOnClick?: boolean;
transparent?: boolean; transparent?: boolean;
style?: string;
class?: ClassValue;
children?: Snippet; children?: Snippet;
} & HTMLAttributes<HTMLDivElement>; } & HTMLAttributes<HTMLDivElement>;
@@ -107,8 +107,9 @@
<EdgeLabel <EdgeLabel
x={position?.x} x={position?.x}
y={position?.y} y={position?.y}
width={size}
height={size}
class={['svelte-flow__edgeupdater nopan', `svelte-flow__edgeupdater-${type}`, className]} class={['svelte-flow__edgeupdater nopan', `svelte-flow__edgeupdater-${type}`, className]}
style={`width:${size}px; height:${size}px;` + style}
onpointerdown={onPointerDown} onpointerdown={onPointerDown}
transparent transparent
{...rest} {...rest}
@@ -5,6 +5,7 @@
import drag from '$lib/actions/drag'; import drag from '$lib/actions/drag';
import type { NodeSelectionProps } from './types'; import type { NodeSelectionProps } from './types';
import { toPxString } from '$lib/utils';
let { let {
store = $bindable(), store = $bindable(),
@@ -38,7 +39,9 @@
{#if store.selectionRectMode === 'nodes' && bounds && isNumeric(bounds.x) && isNumeric(bounds.y)} {#if store.selectionRectMode === 'nodes' && bounds && isNumeric(bounds.x) && isNumeric(bounds.y)}
<div <div
class="selection-wrapper nopan" class="selection-wrapper nopan"
style="width: {bounds.width}px; height: {bounds.height}px; transform: translate({bounds.x}px, {bounds.y}px)" style:width={toPxString(bounds.width)}
style:height={toPxString(bounds.height)}
style:transform="translate({bounds.x}px, {bounds.y}px)"
use:drag={{ use:drag={{
disabled: false, disabled: false,
store, store,
@@ -3,11 +3,11 @@
import { errorMessages, nodeHasDimensions, Position } from '@xyflow/system'; import { errorMessages, nodeHasDimensions, Position } from '@xyflow/system';
import drag from '$lib/actions/drag'; import drag from '$lib/actions/drag';
import { getNodeInlineStyleDimensions } from './utils';
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte'; import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
import type { ConnectableContext, NodeWrapperProps } from './types'; import type { ConnectableContext, NodeWrapperProps } from './types';
import type { NodeEvents } from '$lib/types'; import type { NodeEvents } from '$lib/types';
import { toPxString } from '$lib/utils';
let { let {
store = $bindable(), store = $bindable(),
@@ -33,7 +33,7 @@
connectable: _connectable, connectable: _connectable,
hidden = false, hidden = false,
dragging = false, dragging = false,
style, style = '',
class: className, class: className,
type = 'default', type = 'default',
parentId, parentId,
@@ -90,16 +90,12 @@
}); });
} }
let inlineStyleDimensions = $derived( // We need to pass width and height into the style attribute because
getNodeInlineStyleDimensions({ // style:width/height={undefined} overwrites what is defined in style string
width, let inlineDimensions = $derived({
height, width: toPxString(measuredWidth === undefined ? (width ?? initialWidth) : width),
initialWidth, height: toPxString(measuredHeight === undefined ? (height ?? initialHeight) : height)
initialHeight, });
measuredWidth,
measuredHeight
})
);
$effect(() => { $effect(() => {
// if type, sourcePosition or targetPosition changes, // if type, sourcePosition or targetPosition changes,
@@ -197,7 +193,7 @@
style:z-index={zIndex} style:z-index={zIndex}
style:transform="translate({positionX}px, {positionY}px)" style:transform="translate({positionX}px, {positionY}px)"
style:visibility={initialized ? 'visible' : 'hidden'} style:visibility={initialized ? 'visible' : 'hidden'}
style="{style ?? ''};{inlineStyleDimensions.width}{inlineStyleDimensions.height}" style="{style};width:{inlineDimensions.width};height:{inlineDimensions.height}"
onclick={onSelectNodeHandler} onclick={onSelectNodeHandler}
onpointerenter={onnodepointerenter ? (event) => onnodepointerenter({ node, event }) : undefined} onpointerenter={onnodepointerenter ? (event) => onnodepointerenter({ node, event }) : undefined}
onpointerleave={onnodepointerleave ? (event) => onnodepointerleave({ node, event }) : undefined} onpointerleave={onnodepointerleave ? (event) => onnodepointerleave({ node, event }) : undefined}
@@ -1,33 +0,0 @@
export function getNodeInlineStyleDimensions({
width,
height,
initialWidth,
initialHeight,
measuredWidth,
measuredHeight
}: {
width?: number;
height?: number;
initialWidth?: number;
initialHeight?: number;
measuredWidth?: number;
measuredHeight?: number;
}): {
width: string | undefined;
height: string | undefined;
} {
if (measuredWidth === undefined && measuredHeight === undefined) {
const styleWidth = width ?? initialWidth;
const styleHeight = height ?? initialHeight;
return {
width: styleWidth ? `width:${styleWidth}px;` : '',
height: styleHeight ? `height:${styleHeight}px;` : ''
};
}
return {
width: width ? `width:${width}px;` : '',
height: height ? `height:${height}px;` : ''
};
}
@@ -1,4 +1,6 @@
<script lang="ts"> <script lang="ts">
import { toPxString } from '$lib/utils';
let { let {
x = 0, x = 0,
y = 0, y = 0,
@@ -6,10 +8,10 @@
height = 0, height = 0,
isVisible = true isVisible = true
}: { }: {
x?: number | null; x?: number;
y?: number | null; y?: number;
width?: number | string | null; width?: number | string;
height?: number | string | null; height?: number | string;
isVisible?: boolean; isVisible?: boolean;
} = $props(); } = $props();
</script> </script>
@@ -17,8 +19,8 @@
{#if isVisible} {#if isVisible}
<div <div
class="svelte-flow__selection" class="svelte-flow__selection"
style:width={typeof width === 'string' ? width : `${width}px`} style:width={typeof width === 'string' ? width : toPxString(width)}
style:height={typeof height === 'string' ? height : `${height}px`} style:height={typeof height === 'string' ? height : toPxString(height)}
style:transform={`translate(${x}px, ${y}px)`} style:transform={`translate(${x}px, ${y}px)`}
></div> ></div>
{/if} {/if}
@@ -58,8 +58,8 @@
panOnDrag = true, panOnDrag = true,
selectionOnDrag = true, selectionOnDrag = true,
connectionLineComponent, connectionLineComponent,
connectionLineStyle = '', connectionLineStyle,
connectionLineContainerStyle = '', connectionLineContainerStyle,
connectionLineType = ConnectionLineType.Bezier, connectionLineType = ConnectionLineType.Bezier,
attributionPosition, attributionPosition,
children, children,
@@ -2,6 +2,7 @@
import type { HTMLAttributes } from 'svelte/elements'; import type { HTMLAttributes } from 'svelte/elements';
import type { Snippet } from 'svelte'; import type { Snippet } from 'svelte';
import { type SvelteFlowRestProps } from '$lib/store/types'; import { type SvelteFlowRestProps } from '$lib/store/types';
import { toPxString } from '$lib/utils';
let { let {
width, width,
@@ -87,8 +88,8 @@
bind:this={domNode} bind:this={domNode}
bind:clientHeight bind:clientHeight
bind:clientWidth bind:clientWidth
style:width style:width={toPxString(width)}
style:height style:height={toPxString(height)}
class={['svelte-flow', 'svelte-flow-container', className, colorMode]} class={['svelte-flow', 'svelte-flow-container', className, colorMode]}
data-testid="svelte-flow__wrapper" data-testid="svelte-flow__wrapper"
role="application" role="application"
@@ -7,7 +7,7 @@
<div <div
class="svelte-flow__viewport xyflow__viewport svelte-flow__container" class="svelte-flow__viewport xyflow__viewport svelte-flow__container"
style="transform: translate({store.viewport.x}px, {store.viewport.y}px) scale({store.viewport style:transform="translate({store.viewport.x}px, {store.viewport.y}px) scale({store.viewport
.zoom})" .zoom})"
> >
{@render children()} {@render children()}
@@ -37,8 +37,8 @@
zoomable = true, zoomable = true,
inversePan, inversePan,
zoomStep, zoomStep,
style = '', class: className,
class: className ...rest
}: MiniMapProps = $props(); }: MiniMapProps = $props();
let store = useStore(); let store = useStore();
@@ -83,9 +83,10 @@
<Panel <Panel
{position} {position}
style={style + (bgColor ? `;--xy-minimap-background-color-props:${bgColor}` : '')}
class={['svelte-flow__minimap', className]} class={['svelte-flow__minimap', className]}
data-testid="svelte-flow__minimap" data-testid="svelte-flow__minimap"
--xy-minimap-background-color-props={bgColor}
{...rest}
> >
{#if store.panZoom} {#if store.panZoom}
<svg <svg
@@ -37,8 +37,8 @@
ry={borderRadius} ry={borderRadius}
{width} {width}
{height} {height}
style={`${color ? `fill: ${color};` : ''}${strokeColor ? `stroke: ${strokeColor};` : ''}${ style:fill={color}
strokeWidth ? `stroke-width: ${strokeWidth};` : '' style:stroke={strokeColor}
}`} style:stroke-width={strokeWidth}
shape-rendering={shapeRendering} shape-rendering={shapeRendering}
/> />
@@ -1,5 +1,5 @@
import type { PanelPosition } from '@xyflow/system'; import type { PanelPosition } from '@xyflow/system';
import type { ClassValue } from 'svelte/elements'; import type { ClassValue, HTMLAttributes } from 'svelte/elements';
import type { Node } from '$lib/types'; import type { Node } from '$lib/types';
export type GetMiniMapNodeAttribute = (node: Node) => string; export type GetMiniMapNodeAttribute = (node: Node) => string;
@@ -46,4 +46,4 @@ export type MiniMapProps = {
inversePan?: boolean; inversePan?: boolean;
/** Step size for zooming in/out */ /** Step size for zooming in/out */
zoomStep?: number; zoomStep?: number;
}; } & HTMLAttributes<HTMLDivElement>;
@@ -26,9 +26,9 @@
onResizeStart, onResizeStart,
onResize, onResize,
onResizeEnd, onResizeEnd,
style = '',
class: className, class: className,
children children,
...rest
}: ResizeControlProps = $props(); }: ResizeControlProps = $props();
const store = useStore(); const store = useStore();
@@ -51,12 +51,6 @@
let positionClassNames = $derived(controlPosition.split('-')); let positionClassNames = $derived(controlPosition.split('-'));
let controlStyle = $derived.by(() => {
let colorStyleProp =
variant === ResizeControlVariant.Line ? 'border-color' : 'background-color';
return color ? `${style} ${colorStyleProp}: ${color};` : style;
});
onMount(() => { onMount(() => {
if (resizeControlRef) { if (resizeControlRef) {
resizer = XYResizer({ resizer = XYResizer({
@@ -116,7 +110,9 @@
<div <div
class={['svelte-flow__resize-control', 'nodrag', ...positionClassNames, variant, className]} class={['svelte-flow__resize-control', 'nodrag', ...positionClassNames, variant, className]}
bind:this={resizeControlRef} bind:this={resizeControlRef}
style={controlStyle} style:border-color={variant === ResizeControlVariant.Line ? color : undefined}
style:background-color={variant === ResizeControlVariant.Line ? undefined : color}
{...rest}
> >
{@render children?.()} {@render children?.()}
</div> </div>
@@ -1,5 +1,5 @@
import type { Snippet } from 'svelte'; import type { Snippet } from 'svelte';
import type { ClassValue } from 'svelte/elements'; import type { ClassValue, HTMLAttributes } from 'svelte/elements';
import type { import type {
ControlPosition, ControlPosition,
ResizeControlVariant, ResizeControlVariant,
@@ -44,7 +44,7 @@ export type NodeResizerProps = {
onResize?: OnResize; onResize?: OnResize;
/** Callback called when resizing ends */ /** Callback called when resizing ends */
onResizeEnd?: OnResizeEnd; onResizeEnd?: OnResizeEnd;
}; } & HTMLAttributes<HTMLDivElement>;
export type ResizeControlProps = Pick< export type ResizeControlProps = Pick<
NodeResizerProps, NodeResizerProps,
@@ -69,7 +69,5 @@ export type ResizeControlProps = Pick<
* @example ResizeControlVariant.Handle, ResizeControlVariant.Line * @example ResizeControlVariant.Handle, ResizeControlVariant.Line
*/ */
variant?: ResizeControlVariant; variant?: ResizeControlVariant;
class?: ClassValue;
style?: string;
children?: Snippet; children?: Snippet;
}; } & HTMLAttributes<HTMLDivElement>;
+4
View File
@@ -21,3 +21,7 @@ export const isNode = <NodeType extends Node = Node>(element: unknown): element
*/ */
export const isEdge = <EdgeType extends Edge = Edge>(element: unknown): element is EdgeType => export const isEdge = <EdgeType extends Edge = Edge>(element: unknown): element is EdgeType =>
isEdgeBase<EdgeType>(element); isEdgeBase<EdgeType>(element);
export function toPxString(value: number | undefined): string | undefined {
return value === undefined ? undefined : `${value}px`;
}