import { watch, type Ref } from 'vue' import { buildDimensionString, createDimensionWatcher, createStyleWatcher, } from '@/utils/styleUtils.ts' import type { FormBuilderStore } from '@/utils/styleUtils.ts' export type StoreStyleWatcherEntry = { ref: Ref storePath: string syncPaths: string[] } export type StoreDimensionWatcherEntry = { valueRef: Ref unitRef: Ref storePath: string syncPaths: string[] } export type CallbackStyleWatcherEntry = { watchRef: Ref getCurrentValue: () => string | undefined onChange: () => void } export type CallbackDimensionWatcherEntry = { valueRef: Ref unitRef: Ref getCurrentValue: () => string | undefined onChange: () => void } export const registerDeferredWatchGroup = ( sources: ReadonlyArray>, isSyncingFromStore: Ref, onChange: () => void, ) => { watch(sources, () => { if (isSyncingFromStore.value) return setTimeout(() => { onChange() }, 0) }) } export const registerStoreStyleWatchers = ( entries: StoreStyleWatcherEntry[], formBuilderStore: FormBuilderStore, isSyncingFromStore: Ref, ) => { entries.forEach((entry) => { createStyleWatcher({ ref: entry.ref, storePath: entry.storePath, syncPaths: entry.syncPaths, formBuilderStore, isSyncingFromStore, }) }) } export const registerStoreDimensionWatchers = ( entries: StoreDimensionWatcherEntry[], formBuilderStore: FormBuilderStore, isSyncingFromStore: Ref, ) => { entries.forEach((entry) => { createDimensionWatcher( entry.valueRef as unknown as Ref, entry.unitRef, entry.storePath, entry.syncPaths, formBuilderStore, isSyncingFromStore, ) }) } export const registerCallbackStyleWatchers = ( entries: CallbackStyleWatcherEntry[], isSyncingFromStore: Ref, ) => { entries.forEach((entry) => { watch(entry.watchRef, (newValue) => { if (isSyncingFromStore.value) return setTimeout(() => { if (newValue !== entry.getCurrentValue()) { entry.onChange() } }, 0) }) }) } export const registerCallbackDimensionWatchers = ( entries: CallbackDimensionWatcherEntry[], isSyncingFromStore: Ref, ) => { entries.forEach((entry) => { watch([entry.valueRef, entry.unitRef], () => { if (isSyncingFromStore.value) return setTimeout(() => { const currentValue = entry.getCurrentValue() const newValue = buildDimensionString(entry.valueRef.value, entry.unitRef.value) if (newValue !== '' && newValue !== currentValue) { entry.onChange() } }, 0) }) }) }