UNPKG

auto-form-sync

Version:

Auto-save and restore form data using Local/Session/Custom Storage.

3 lines (2 loc) 3.82 kB
import{useRef as e,useEffect as o}from"react";const t={save(e,o){try{localStorage.setItem(e,o)}catch(e){console.error("[auto-form-sync] Failed to save to localStorage:",e)}},load(e){try{return localStorage.getItem(e)}catch(e){return console.error("[auto-form-sync] Failed to load from localStorage:",e),null}},remove(e){try{localStorage.removeItem(e)}catch(e){console.error("[auto-form-sync] Failed to remove from localStorage:",e)}}},r={save(e,o){try{sessionStorage.setItem(e,o)}catch(e){console.error("[auto-form-sync] Failed to save to sessionStorage:",e)}},load(e){try{return sessionStorage.getItem(e)}catch(e){return console.error("[auto-form-sync] Failed to load from sessionStorage:",e),null}},remove(e){try{sessionStorage.removeItem(e)}catch(e){console.error("[auto-form-sync] Failed to remove from sessionStorage:",e)}}};var n;function a(e,o){const t=e.id||e.classList[0],r=(o?.key||t).trim();if(""==r)throw new Error(`[auto-form-sync] Unable to find the storage key for this form: ${e}`);const n=document.querySelectorAll("form");if(Array.from(n).some(e=>e.dataset.key===r))throw new Error("[auto-form-sync] The key already exists. Please use different key or id name.");return r}function s(e){try{return JSON.parse(e)}catch(e){return null}}function c(e){return JSON.stringify(e)}!function(e){e.LocalStorage="LocalStorage",e.SessionStorage="SessionStorage",e.Custom="Custom"}(n||(n={}));const i=e=>{const{storage:o}=e;if(!o||o===n.SessionStorage)return r;if(o===n.LocalStorage)return t;if("object"==typeof o)return o;throw new Error(`[auto-form-sync] Invalid storage option: ${o}`)},l=(e,o)=>!("submit"===e.type||e instanceof HTMLButtonElement)&&(!e.disabled&&!e.dataset?.nosync&&!((e,o=[])=>o.some(o=>"string"==typeof o?o===e.id||o===e.name:o(e)))(e,o.exclude));async function u(e,o={}){const t=i(o),r=(e=>e.serializer??c)(o),n=(e=>e.debounce??300)(o),s=a(e,o);if(!s)return console.warn("[auto-form-sync] Unable to attach listeners: no storage key."),()=>{};const u=function(e,o=300){let t;return function(...r){clearTimeout(t),t=setTimeout(e,o,...r)}}(()=>{const n=((e,o)=>Array.from(e.elements).filter(e=>l(e,o)).map(e=>({name:e.name,id:e.id,value:"checkbox"==e.type?e.checked?"true":"false":e.value})))(e,o),a=r(n);t.save(s,a),o.onSave?.(n)},n),m=[];for(const t of e.elements){if(!l(t,o))continue;const e=t.type,r="checkbox"===e||"radio"===e||"SELECT"===t.tagName?"change":"input";t.addEventListener(r,()=>u()),m.push(()=>t.removeEventListener(r,()=>u()))}const f=async r=>{if("function"==typeof e.onsubmit){const o=e.onsubmit.call(e,r);o instanceof Promise&&await o}o.clearOnSubmit&&(await t.remove(s),o.onClear?.())};return e.addEventListener("submit",f),m.push(()=>e.removeEventListener("submit",f)),()=>m.forEach(e=>e())}async function m(e,o={}){const t=document.querySelector(e);if(!t)throw console.warn(`[auto-form-sync] Form not found: ${e}`),new Error(`[auto-form-sync] Form not found: ${e}`);return(void 0===o?.restoreOnLoad||o.restoreOnLoad)&&await async function(e,o){const t=i(o),r=o?.deserializer||s,n=a(e,o),c=await t.load(n);if(!c||!r)return void console.warn(`[auto-form-sync] Unable to load serialized data for this form: ${e}`);const l=r(c);l&&(l?.forEach(o=>{const t=e.querySelector(`[name="${o.name}"]`)??(o.id?e.querySelector(`#${o.id}`):null);t&&(t.value=o.value.toString()),"checkbox"==t?.type&&(t.checked="true"===o?.value)}),o?.onRestore?.(l))}(t,o),console.warn("[auto-form-sync] Initialized on form:",t),await u(t,o)}function f(t,r={}){const n=e(null);o(()=>{let e=!1;return(async()=>{try{e||null!=n.current||(n.current=await m(t,r))}catch(e){console.error("[useAutoFormSync] Error initializing form sync:",e)}})(),()=>{e=!0,"function"==typeof n.current&&(n.current(),n.current=null)}},[t,r])}export{m as autoFormSync,f as useAutoFormSync}; //# sourceMappingURL=index.esm.min.js.map