UNPKG

@smkit/ui

Version:

UI Kit of SberMarketing

132 lines (131 loc) 4.09 kB
import { get, derived, writable } from 'svelte/store'; import { isBrowser } from '../utils'; export const searchTerm = writable(''); export function cachedDerived(stores, callback, settings) { let oldValue; let timeout; const store = derived(stores, ($stores, set, update) => { if (JSON.stringify(oldValue) === JSON.stringify($stores)) return; oldValue = structuredClone($stores); if (settings?.delay) { clearTimeout(timeout); timeout = setTimeout(async () => { callback($stores, set, update); }, settings.delay); } else { callback($stores, set, update); } }); return store; } export function storable(data, storeKey) { const store = writable(data); const { subscribe, set } = store; isBrowser && localStorage[`storable_${storeKey}`] && set(JSON.parse(localStorage[`storable_${storeKey}`])); return { subscribe, set: (n) => { isBrowser && (localStorage[`storable_${storeKey}`] = JSON.stringify(n)); set(n); }, update: (cb) => { const updatedStore = cb(get(store)); isBrowser && (localStorage[`storable_${storeKey}`] = JSON.stringify(updatedStore)); set(updatedStore); } }; } export function overridable(store, onChange) { const update = (updater, sideEffect) => { store.update((curr) => { const next = updater(curr); let res = next; if (onChange) { res = onChange({ curr, next }); } sideEffect && sideEffect(next); return res; }); }; const set = (curr) => { update(() => curr); }; return { ...store, update, set }; } export function debouncedWritable(baseValue, delay) { const { subscribe, set, update } = writable(baseValue); let timeout; function delayedSet(newValue) { clearTimeout(timeout); timeout = setTimeout(() => { set(newValue); }, delay || 100); } return { set: delayedSet, subscribe, update }; } export function urlParamsWritable(value, key = 'saved', compress = false, delay = 100) { const getSearchParams = (field, url) => { let decoded = null; try { decoded = url.searchParams.get(field); if (!decoded) return null; decoded = decodeURIComponent(decoded); if (compress) { decoded = unzipurl(decoded); } if (typeof value === 'object') { decoded = JSON.parse(decoded); } } catch (e) { console.error(`Unexpected searchParams value for ${field}: ${e}`); } return decoded; }; const encodeJSON = (data) => { if (compress) { return zipurl(JSON.stringify(data)); } return JSON.stringify(data); }; const updateSearchParams = (kv) => { if (!isBrowser || !window) return; const url = new URL(window.location.toString()); if (!url) return; for (const [k, v] of Object.entries(kv)) { if (v) { const encodedValue = typeof value === 'object' ? encodeJSON(v) : v.toString(); url.searchParams.set(encodeURIComponent(k), encodeURIComponent(encodedValue)); } else { url.searchParams.delete(k); } } history.pushState({}, `updated ${key}`, url); }; const saved = isBrowser ? getSearchParams(key, new URL(location.href)) || value : value; const store = writable(saved); let timeout; store.subscribe((v) => { if (!delay) { updateSearchParams({ [key]: v }); return; } clearTimeout(timeout); timeout = setTimeout(() => { updateSearchParams({ [key]: v }); }, delay); }); return store; }