@zag-js/solid
Version:
The solid.js wrapper for zag
59 lines (58 loc) • 1.55 kB
JavaScript
// src/bindable.ts
import { isFunction } from "@zag-js/utils";
import { createEffect, createMemo, createSignal, onCleanup } from "solid-js";
function createBindable(props) {
const initial = props().value ?? props().defaultValue;
const eq = props().isEqual ?? Object.is;
const [value, setValue] = createSignal(initial);
const controlled = createMemo(() => props().value != void 0);
const valueRef = { current: value() };
const prevValue = { current: void 0 };
createEffect(() => {
const v = controlled() ? props().value : value();
prevValue.current = v;
valueRef.current = v;
});
const set = (v) => {
const prev = prevValue.current;
const next = isFunction(v) ? v(valueRef.current) : v;
if (props().debug) {
console.log(`[bindable > ${props().debug}] setValue`, { next, prev });
}
if (!controlled()) setValue(next);
if (!eq(next, prev)) {
props().onChange?.(next, prev);
}
};
function get() {
const v = controlled() ? props().value : value;
return isFunction(v) ? v() : v;
}
return {
initial,
ref: valueRef,
get,
set,
invoke(nextValue, prevValue2) {
props().onChange?.(nextValue, prevValue2);
},
hash(value2) {
return props().hash?.(value2) ?? String(value2);
}
};
}
createBindable.cleanup = (fn) => {
onCleanup(() => fn());
};
createBindable.ref = (defaultValue) => {
let value = defaultValue;
return {
get: () => value,
set: (next) => {
value = next;
}
};
};
export {
createBindable
};