From a59f77aa6db39b9b61baa5a5b9c7396025ba5fa7 Mon Sep 17 00:00:00 2001 From: thepaperpilot <thepaperpilot@gmail.com> Date: Sat, 22 Apr 2023 19:21:16 -0500 Subject: [PATCH] Support classes and styles to be defined by node types --- src/features/boards/BoardNode.vue | 9 ++++++--- src/features/boards/board.ts | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/features/boards/BoardNode.vue b/src/features/boards/BoardNode.vue index 47ca3fe..a2300b1 100644 --- a/src/features/boards/BoardNode.vue +++ b/src/features/boards/BoardNode.vue @@ -1,8 +1,9 @@ <template> + <!-- Ugly casting to prevent TS compiler error about style because vue doesn't think it supports arrays when it does --> <g class="boardnode" - :class="{ [node.type]: true, isSelected, isDraggable }" - :style="{ opacity: dragging?.id === node.id && hasDragged ? 0.5 : 1 }" + :class="{ [node.type]: true, isSelected, isDraggable, ...classes }" + :style="[{ opacity: dragging?.id === node.id && hasDragged ? 0.5 : 1 }, style ?? []] as unknown as (string | CSSProperties)" :transform="`translate(${position.x},${position.y})${isSelected ? ' scale(1.2)' : ''}`" > <BoardNodeAction @@ -141,7 +142,7 @@ import type { BoardNode, GenericBoardNodeAction, GenericNodeType } from "feature import { ProgressDisplay, Shape, getNodeProperty } from "features/boards/board"; import { isVisible } from "features/feature"; import settings from "game/settings"; -import { computed, toRefs, unref, watch } from "vue"; +import { CSSProperties, computed, toRefs, unref, watch } from "vue"; import BoardNodeAction from "./BoardNodeAction.vue"; const sqrtTwo = Math.sqrt(2); @@ -244,6 +245,8 @@ const canAccept = computed( unref(props.hasDragged) && getNodeProperty(props.nodeType.value.canAccept, unref(props.node)) ); +const style = computed(() => getNodeProperty(props.nodeType.value.style, unref(props.node))); +const classes = computed(() => getNodeProperty(props.nodeType.value.classes, unref(props.node))); function mouseDown(e: MouseEvent | TouchEvent) { emit("mouseDown", e, props.node.value.id, isDraggable.value); diff --git a/src/features/boards/board.ts b/src/features/boards/board.ts index 961d517..a86b5ae 100644 --- a/src/features/boards/board.ts +++ b/src/features/boards/board.ts @@ -92,6 +92,10 @@ export interface NodeTypeOptions { label?: NodeComputable<NodeLabel | null>; /** The size of the node - diameter for circles, width and height for squares. */ size: NodeComputable<number>; + /** CSS to apply to this node. */ + style?: NodeComputable<StyleValue>; + /** Dictionary of CSS classes to apply to this node. */ + classes?: NodeComputable<Record<string, boolean>>; /** Whether the node is draggable or not. */ draggable?: NodeComputable<boolean>; /** The shape of the node. */ @@ -137,6 +141,8 @@ export type NodeType<T extends NodeTypeOptions> = Replace< title: GetComputableType<T["title"]>; label: GetComputableType<T["label"]>; size: GetComputableTypeWithDefault<T["size"], 50>; + style: GetComputableType<T["style"]>; + classes: GetComputableType<T["classes"]>; draggable: GetComputableTypeWithDefault<T["draggable"], false>; shape: GetComputableTypeWithDefault<T["shape"], Shape.Circle>; canAccept: GetComputableTypeWithDefault<T["canAccept"], false>; @@ -378,6 +384,8 @@ export function createBoard<T extends BoardOptions>( processComputable(nodeType as NodeTypeOptions, "label"); processComputable(nodeType as NodeTypeOptions, "size"); setDefault(nodeType, "size", 50); + processComputable(nodeType as NodeTypeOptions, "style"); + processComputable(nodeType as NodeTypeOptions, "classes"); processComputable(nodeType as NodeTypeOptions, "draggable"); setDefault(nodeType, "draggable", false); processComputable(nodeType as NodeTypeOptions, "shape");