UNPKG

@gravity-ui/graph

Version:

Modern graph editor component

77 lines (76 loc) 2.32 kB
import { computed, signal } from "@preact/signals-core"; import { Group } from "../../components/canvas/groups"; import { ESelectionStrategy } from "../../services/selection/types"; export class GroupState { constructor(store, state, groupSelectionBucket) { this.store = store; this.groupSelectionBucket = groupSelectionBucket; this.$state = signal({ id: "", rect: { x: 0, y: 0, width: 0, height: 0, }, component: Group, }); this.$viewComponent = signal(undefined); /** * When true, the group's rect should not be auto-updated based on contained blocks. * Used during Shift+drag to keep the group visually stable. * Note: This is NOT a signal to avoid cycle detection issues in computed signals. */ this.sizeLocked = false; /** * Computed signal that reactively determines if this group is selected * by checking if its ID exists in the selection bucket */ this.$selected = computed(() => { return this.groupSelectionBucket.isSelected(this.id); }); this.$state.value = state; } setViewComponent(component) { this.$viewComponent.value = component; } getViewComponent() { return this.$viewComponent.value; } /** * Check if the group's size is locked */ isSizeLocked() { return this.sizeLocked; } /** * Lock the group's size to prevent auto-resize during block transfer */ lockSize() { this.sizeLocked = true; } /** * Unlock the group's size to allow auto-resize */ unlockSize() { this.sizeLocked = false; } get id() { return this.$state.value.id; } updateGroup(group) { this.$state.value = { ...this.$state.value, ...group, }; } setSelection(selected, strategy = ESelectionStrategy.REPLACE) { this.store.updateGroupsSelection([this.id], selected, strategy); } asTGroup() { return this.$state.value; } static fromTGroup(store, group) { return new GroupState(store, group, store.groupSelectionBucket); } }