UNPKG

@rkosafo/cai.components

Version:

This package is under development and not ready for public use.

49 lines (43 loc) 1.37 kB
import { getContext, setContext } from "svelte"; /** * @template T * @typedef {Object} SingleSelectionContext * @property {T=} value */ /** @type {symbol} */ const SINGLE_SELECTION_KEY = Symbol("singleton"); /** * @template T * @param {boolean} [nonReactive=false] - use a non-reactive placeholder to allow multiple selection and keep context shallow * @returns {SingleSelectionContext<T>} */ export function createSingleSelectionContext(nonReactive = false) { const context = $state({ value: undefined }); return setContext(SINGLE_SELECTION_KEY, nonReactive ? {} : context); } /** * @template T * @param {SingleSelectionContext<T>} context * @param {boolean} open * @param {T=} value * @returns {SingleSelectionContext<T>} */ function setSelected(context, open, value) { if (Object.hasOwn(context, 'value')) { if (open) context.value = value; else if (context.value === value) context.value = undefined; } return context; } /** * @template T * @param {(value: T) => void} callback * @returns {(open: boolean, v?: T) => SingleSelectionContext<T>} */ export function useSingleSelection(callback) { const context = getContext(SINGLE_SELECTION_KEY) ?? createSingleSelectionContext(false); $effect(() => { if (context.value !== undefined) callback(context.value); }); return (open, v) => setSelected(context, open, v); }