query-state-hook
Version:
Easily manage the state of your React components via URL query parameters
2 lines (1 loc) • 5.49 kB
JavaScript
(function(c,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],n):(c=typeof globalThis<"u"?globalThis:c||self,n(c.URLStateHanlder={},c.React))})(this,function(c,n){"use strict";var U=Object.defineProperty;var v=(c,n,S)=>n in c?U(c,n,{enumerable:!0,configurable:!0,writable:!0,value:S}):c[n]=S;var g=(c,n,S)=>v(c,typeof n!="symbol"?n+"":n,S);class S{constructor(t){g(this,"queryName");g(this,"urlSearchParams");this.queryName=t.queryName,this.urlSearchParams=new URLSearchParams(t.searchParams)}set(t){return this.urlSearchParams.set(this.queryName,t)}append(t){return this.urlSearchParams.append(this.queryName,t)}get(){return this.urlSearchParams.get(this.queryName)}getAll(){return this.urlSearchParams.getAll(this.queryName)}delete(){return this.urlSearchParams.delete(this.queryName)}has(){return this.urlSearchParams.has(this.queryName)}entries(){return this.urlSearchParams.entries()}keys(){return this.urlSearchParams.keys()}sort(){return this.urlSearchParams.sort()}values(){return this.urlSearchParams.values()}toString(){return this.urlSearchParams.toString()}}class h{constructor(t){this.props=t}static build(t){return new h(t)}static customValidation(t){return new h({name:t.name,values:[],defaultValue:"",get:t.getState,set:t.setState})}getState(t){const e=new S({queryName:this.props.name,searchParams:t});if(this.props.get)return this.customGet(e);const r=e.get();if(!r)return this.props.defaultValue;const s=r.split(",");if(s.length>1)return this.matchedValuesInArray(this.props.values,s);const i=this.props.values.find(o=>o===r);return i||this.props.defaultValue}setState(t,e){const r=new S({queryName:this.props.name,searchParams:t});if(Array.isArray(e)){if(this.props.set)return this.customSet(r,e);const s=this.matchedValuesInArray(this.props.values,e);return s.length>0&&r.set(s.join(",")),r.toString()}return this.props.set?this.customSet(r,e):!e&&!this.props.defaultValue?(r.delete(),r.toString()):e?this.props.values.includes(e)?(r.set(`${e}`),r.toString()):(r.set(this.props.defaultValue.toString()),r.toString()):(r.set(this.props.defaultValue.toString()),r.toString())}matchedValuesInArray(t,e){const r=new Set(t),s=new Set(e).intersection(r);return Array.from(s)}customSet(t,e){const r=this.props.set(t,e);return r===void 0?(t.set(e?`${e}`:""),t.toString()):r.toString()}customGet(t){const e=this.props.get(t);if(e===void 0)return t.get()??"";const r=e.split(",");return r.length>1?r:e}}function y(u){throw new Error("Unhandled type "+u)}function V(u){const{currentState:t,deleteValue:e,name:r,searchParams:s}=u;if(e==="all")return s.delete(r),s;const o=new Set([t].flat()).difference(new Set([e].flat()));return o.size===0?(s.delete(r),s):(s.set(r,Array.from(o).toString()),s)}class f{constructor(t){this.props=t}static buildComposed(t){return new f(t)}static container(t){return new f({name:"",ids:t})}getState(t,e){return this.build(e).getState(t)}setState({key:t,searchParams:e,value:r}){return this.build(t).setState(e,r)}getAll(t){const e=new URLSearchParams;return Object.entries(this.props.ids).forEach(([r,s])=>{const i=r,o=this.build(i).getState(t);o&&e.set(this.buildNameFromKey(i),o.toString())}),e.toString()}build(t){const e=this.props.ids[t],r=e.type;let s;switch(r){case"custom":s=h.customValidation({name:this.buildNameFromKey(t),getState:e.params.getState,setState:e.params.setState});break;case"simple":s=h.build({name:this.buildNameFromKey(t),values:e.params.values,defaultValue:e.params.defaultValue});break;case"any":s=h.customValidation({name:this.buildNameFromKey(t),getState(i){return i.get()??""},setState(i,o){return o?(i.set(o),i):(i.delete(),i)}});break;default:throw y(r)}return s}buildNameFromKey(t){const e=this.props.name;return e?`${e}.${t}`:t}}function A(u){const{props:t,searchParams:e,updateSearchParams:r}=u,[s,i]=n.useState(e);n.useEffect(()=>{i(e)},[e]);const o=n.useMemo(()=>t.name?f.buildComposed({ids:t.ids,name:t.name}):f.container(t.ids),[t]),d=n.useCallback((a,l)=>{const p=o.setState({searchParams:s,key:a,value:l}),P=new URLSearchParams(p);r(P),i(P)},[o]),m=n.useCallback(a=>o.getState(e,a),[e]);return{state:{value(a){return o.getState(s,a)},is(a,l){return this.value(a)===l},has(a,l){return m(a).includes(l)},isArray:b,firstElement(a){const l=m(a);return b(l)?l[0]:l},validateAll(){return o.getAll(e)}},clean(a,l){const p=V({currentState:m(a),deleteValue:l,name:N({name:t.name,id:a}),searchParams:e});r(p)},setState:d}}function b(u){return Array.isArray(u)}function N(u){return u.name?`${u.name}.${u.id}`:u.id}function q({props:u,searchParams:t,updateSearchParams:e}){const[r,s]=n.useState(t);n.useEffect(()=>{s(t)},[t]);const i=n.useMemo(()=>{const m=u.type;switch(m){case"custom":return h.customValidation(u.params);case"simple":return h.build(u.params);case"any":return h.customValidation({name:u.params.name,getState(a){return a.get()??""},setState(a,l){return l?(a.set(l),a):(a.delete(),a)}});default:throw y(m)}},[]),o=n.useCallback(m=>{const a=i.setState(r,m),l=new URLSearchParams(a);s(l),e(l)},[r]),d=n.useMemo(()=>i.getState(r),[r]);return{state:{value:d,is(m){return d===m},has(m){return d.includes(m)},isArray:w,firstElement(){return w(d)?d[0]:d}},setState:o,clean(m){const a=V({currentState:d,deleteValue:m,name:u.params.name,searchParams:t});e(a)}}}function w(u){return Array.isArray(u)}c.URLStateHandler=h,c.useUrlMultiState=A,c.useUrlState=q,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});