@gravity-ui/graph
Version:
Modern graph editor component
77 lines (76 loc) • 2.32 kB
JavaScript
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);
}
}