@7span/react-list 0.0.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- (function(P,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],a):(P=typeof globalThis<"u"?globalThis:P||self,a(P.ReactList={},P.jsxRuntime,P.react))})(this,function(P,a,r){"use strict";const H=r.createContext(null),J=({children:s,config:o})=>{const{requestHandler:l,stateManager:n={}}=o,[i,u]=r.useState({data:[],response:null,error:null,count:0,selection:[],pagination:{page:1,perPage:25},loader:{isLoading:!1,initialLoading:!0},sort:{sortBy:null,sortOrder:"desc"},search:"",filters:{},attrs:[],isEmpty:!0,isInitializing:!0});if(!l)throw new Error("ListProvider: requestHandler is required.");const h=r.useMemo(()=>({requestHandler:l,stateManager:n,listState:i,setListState:u}),[l,n,i]);return a.jsx(H.Provider,{value:h,children:s})},A=()=>{const s=r.useContext(H);if(!s)throw new Error("useListContext must be used within a ListProvider");return s},K=r.memo(({children:s,renderAttribute:o})=>{const{listState:l}=A(),{attrs:n,attrSettings:i,updateAttr:u}=l,h=r.useCallback(d=>m=>{u(d,"visible",m.target.checked)},[u]),L=r.useMemo(()=>({attrs:n,attrSettings:i,updateAttr:u}),[n,i,u]);return s?s(L):a.jsx("div",{className:"react-list-attributes",children:n.map((d,m)=>{var g;return o?o({key:`attr-${m}`,attr:d,updateAttr:u,attrSettings:i}):a.jsxs("label",{children:[a.jsx("span",{children:d.label}),a.jsx("input",{type:"checkbox",checked:((g=i==null?void 0:i[d.name])==null?void 0:g.visible)??!1,onChange:h(d.name)})]},`attr-${m}`)})})}),Q=r.memo(({children:s})=>{const{listState:o}=A(),{data:l,loader:n,error:i}=o,{isLoading:u,initialLoading:h}=n;return(l==null?void 0:l.length)>0||h||u||i?null:a.jsx("div",{className:"react-list-empty",children:s||a.jsx("div",{children:a.jsx("p",{children:"No data found!"})})})}),U=r.memo(({children:s})=>{const{listState:o}=A(),{error:l,loader:n}=o,{isLoading:i}=n;return!l||i?null:a.jsx("div",{className:"react-list-error",children:typeof s=="function"?s({error:l}):s||a.jsxs("div",{children:[a.jsx("h3",{children:"Error occurred"}),a.jsxs("pre",{children:[l.name,": ",l.message]})]})})}),V=r.memo(({children:s})=>{const{listState:o}=A(),{data:l,count:n,pagination:i,setPage:u,loader:h,error:L}=o,{page:d,perPage:m}=i,{initialLoading:g,isLoading:y}=h,{pages:M,pagesCount:v}=r.useMemo(()=>{const k=Math.ceil(n/m);return{pages:Array.from({length:k},(x,p)=>p+1),pagesCount:k}},[n,m]),z=r.useCallback(k=>{u(Number(k.target.value))},[u]),b=r.useMemo(()=>({setPage:u,page:d,pages:M,pagesCount:v}),[u,d,M,v]);return g||!l||l.length===0||L?null:a.jsx("div",{className:"react-list-go-to",children:s?s(b):a.jsx("select",{value:d,onChange:z,children:M.map(k=>a.jsxs("option",{value:k,children:["Page ",k]},`page-${k}`))})})}),X=r.memo(({children:s})=>{const{listState:o}=A(),{loader:l}=o,{initialLoading:n}=l;return r.useMemo(()=>({loading:n}),[n]),n?a.jsx("div",{className:"react-list-initial-loader",children:s||a.jsx("p",{children:"Initial Loading..."})}):null}),Y=r.memo(({children:s,renderItem:o})=>{const{listState:l}=A(),{data:n=[],loader:i,error:u,setSort:h,sort:L}=l,{initialLoading:d}=i,m=r.useMemo(()=>({items:n,setSort:h,sort:L}),[n,L,h]);return d||!n||n.length===0||u?null:o?a.jsx("div",{className:"react-list-items",children:n.map((g,y)=>a.jsx("div",{children:o({item:g,index:y})},g.id||y))}):typeof s=="function"?a.jsx("div",{className:"react-list-items",children:s(m)}):a.jsx("div",{className:"react-list-items",children:n.map((g,y)=>a.jsx("pre",{children:JSON.stringify(g,null,2)},g.id||y))})}),_=(s,o)=>{if(s===o)return!0;if(s==null||o==null||typeof s!="object"||typeof o!="object")return s===o;if(Array.isArray(s)&&Array.isArray(o)){if(s.length!==o.length)return!1;for(let i=0;i<s.length;i++)if(!_(s[i],o[i]))return!1;return!0}if(Array.isArray(s)||Array.isArray(o))return!1;const l=Object.keys(s).filter(i=>s[i]!==void 0),n=Object.keys(o).filter(i=>o[i]!==void 0);if(l.length!==n.length)return!1;for(let i of l)if(!n.includes(i)||!_(s[i],o[i]))return!1;return!0},Z=(s,o)=>!o||Object.keys(o).length===0?s&&Object.keys(s).length>0:!s||Object.keys(s).length===0?!1:!_(s,o),F=({initialItems:s=[],children:o,endpoint:l,page:n=1,perPage:i=25,sortBy:u="",sortOrder:h="desc",count:L=0,search:d="",filters:m={},attrs:g,version:y=1,paginationMode:M="pagination",meta:v={},onResponse:z,afterPageChange:b,afterLoadMore:k})=>{const{requestHandler:q,setListState:x,stateManager:p}=A(),I=r.useRef(!1),w=M==="loadMore",E=r.useCallback(e=>({endpoint:l,version:y,meta:v,search:(e==null?void 0:e.search)||d,page:(e==null?void 0:e.page)||n,perPage:(e==null?void 0:e.perPage)||i,sortBy:(e==null?void 0:e.sortBy)||u,sortOrder:(e==null?void 0:e.sortOrder)||h,filters:(e==null?void 0:e.filters)||m,attrSettings:(e==null?void 0:e.attrSettings)||{},isRefresh:!1}),[l,y,v,d,n,i,u,h,m]),O=r.useCallback(()=>{var e;try{const f=E(),c=(e=p==null?void 0:p.get)==null?void 0:e.call(p,f);return{page:c==null?void 0:c.page,perPage:c==null?void 0:c.perPage,sortBy:c==null?void 0:c.sortBy,sortOrder:c==null?void 0:c.sortOrder,search:c==null?void 0:c.search,attrSettings:c==null?void 0:c.attrSettings,filters:c==null?void 0:c.filters}}catch(f){return console.error(f),{}}},[E,p]),B=r.useCallback(()=>{const e=O();let f=n;return w?f=1:e.page!=null&&(f=e.page),{page:f,perPage:e.perPage!=null?e.perPage:i,sortBy:e.sortBy!=null?e.sortBy:u,sortOrder:e.sortOrder!=null?e.sortOrder:h,search:e.search!=null?e.search:d,filters:e.filters!=null?e.filters:m,attrSettings:e.attrSettings||{},items:s,selection:[],error:null,response:null,count:0,isLoading:!1,initializingState:!s.length,confirmedPage:null}},[O,d,n,i,u,h,d,m,w]),[t,S]=r.useState(B),T=r.useCallback(e=>{var f;if(p){const c=E(e);(f=p==null?void 0:p.set)==null||f.call(p,c)}},[p,E]),N=r.useCallback(async(e={},f=null)=>{t.initializingState||S(c=>({...c,error:null,isLoading:!0}));try{const c=f||t,C=await q({endpoint:l,version:y,meta:v,page:c.page,perPage:c.perPage,search:c.search,sortBy:c.sortBy,sortOrder:c.sortOrder,filters:c.filters,...e});z&&z(C);let D;w?(prev.page===1?D=C.items:D=[...prev.items,...C.items],k&&k(C)):(D=C.items,b&&b(C));const W={...c,response:C,selection:[],items:w&&c.page>1?[...prev.items,...C.items]:C.items,count:C.count,initializingState:!1,isLoading:!1};T(W),S(W)}catch(c){throw S(C=>({...C,error:c,items:[],count:0,initializingState:!1,isLoading:!1})),c}},[l,y,w,v,q,t]),$=r.useMemo(()=>({setPage:(e,f)=>{let c=e;e===0&&(c="");const C={...t,page:c};S(C),c&&N(f,C)},setPerPage:e=>{const f={...t,perPage:e,page:1};S(f),N({},f)},setSearch:e=>{if(e!==t.search){const f={...t,search:e,page:1};S(f),N({},f)}},setSort:({by:e,order:f})=>{const c={...t,sortBy:e,sortOrder:f,page:1};S(c),N({},c)},loadMore:()=>{const e={...t,page:t.page+1};S(e),N({},e)},clearFilters:()=>{const e={...t,filters:m,page:1};S(e),N({},e)},refresh:(e={isRefresh:!0})=>{if(w){const f={...t,page:1,items:[]};S(f),N(e,f)}else N(e)},setFilters:e=>{const f={...t,filters:e,page:1};S(f),N({},f)},updateItemById:(e,f)=>{const c=t.items.map(C=>C.id===f?{...C,...e}:C);S(C=>({...C,items:c}))},setSelection:e=>S(f=>({...f,selection:e}))}),[N,w,t]),G=r.useMemo(()=>({data:t.items,response:t.response,error:t.error,count:t.count,selection:t.selection,pagination:{page:t.page,perPage:t.perPage,hasMore:t.items.length<t.count},loader:{isLoading:t.isLoading,initialLoading:t.initializingState},sort:{sortBy:t.sortBy,sortOrder:t.sortOrder},hasActiveFilters:Z(t.filters,m),search:t.search,filters:t.filters,attrs:g||Object.keys(t.items[0]||{}),isEmpty:t.items.length===0,...$}),[t.items,t.response,t.error,t.count,t.selection,t.page,t.perPage,t.isLoading,t.initializingState,t.sortBy,t.sortOrder,t.search,t.filters,$,g]);return r.useEffect(()=>{if(t.initializingState&&!I.current){if(I.current=!0,p!=null&&p.init){const e=E(t);p.init(e)}s.length||$.setPage(t.page)}},[]),r.useEffect(()=>{x(G)},[x,t.items,t.count,t.error,t.isLoading,t.selection,t.page,t.perPage,t.sortBy,t.sortOrder]),typeof o=="function"?o(G):o},R=r.memo(({children:s})=>{const{listState:o}=A(),{data:l,count:n,pagination:i,setPage:u,loader:h,error:L}=o,{page:d,perPage:m}=i,{isLoading:g}=h,y=r.useMemo(()=>d*m<n,[d,m,n]),M=r.useCallback(()=>{y&&!g&&u(d+1)},[y,g,u,d]),v=r.useMemo(()=>({isLoading:g,loadMore:M,hasMoreItems:y}),[g,M,y]);return!l||l.length===0||L?null:s(v)}),j=r.memo(({children:s,position:o="overlay"})=>{const{listState:l}=A(),{loader:n}=l,{isLoading:i,initializingState:u}=n;return r.useMemo(()=>({isLoading:i}),[i]),!u&&!i?null:a.jsx("div",{children:s||a.jsx("div",{children:a.jsx("p",{children:"Loading..."})})})}),ee=r.memo(({children:s,pageLinks:o=5,renderFirst:l,renderPrev:n,renderPages:i,renderPage:u,renderNext:h,renderLast:L})=>{const{listState:d}=A(),{data:m,count:g,pagination:y,setPage:M,loader:v,error:z}=d,{page:b,perPage:k}=y,{initialLoading:q,isLoading:x}=v,p=r.useMemo(()=>{const O=Math.ceil(g/k),B=Math.floor(o/2),t=b*k<g;return{pagesCount:O,halfWay:B,hasNext:t,hasPrev:b!==1}},[g,k,b,o]),I=r.useMemo(()=>{const{pagesCount:O,halfWay:B}=p,t=Array.from({length:Math.min(o,O)});return b<=B?t.map((S,T)=>T+1):O-b<B?t.map((S,T)=>O-T).reverse():t.map((S,T)=>b-B+T)},[b,o,p]),w=r.useMemo(()=>({prev:()=>M(b-1),next:()=>M(b+1),first:()=>M(1),last:()=>M(p.pagesCount),setPage:O=>M(O)}),[M,b,p.pagesCount]),E=r.useMemo(()=>({page:b,perPage:k,count:g,...p,pagesToDisplay:I,...w}),[b,k,g,p,I,w]);return q||!m||m.length===0||z?null:s?s(E):a.jsxs("div",{className:"react-list-pagination",children:[l?l(E):a.jsx("button",{type:"button",disabled:!p.hasPrev,onClick:w.first,children:"First"}),n?n(E):a.jsx("button",{type:"button",disabled:!p.hasPrev,onClick:w.prev,children:"Prev"}),i?i(E):a.jsx("div",{children:I.map(O=>{const B=O===b,t={...E,page:O,isActive:B};return u?u(t):a.jsx("div",{children:B?a.jsx("span",{children:O}):a.jsx("button",{type:"button",onClick:()=>w.setPage(O),children:O})},`page-${O}`)})}),h?h(E):a.jsx("button",{type:"button",disabled:!p.hasNext,onClick:w.next,children:"Next"}),L?L(E):a.jsx("button",{type:"button",disabled:!p.hasNext,onClick:w.last,children:"Last"})]})}),te=r.memo(({children:s,options:o=[10,25,50,100]})=>{const{listState:l}=A(),{data:n,pagination:i,setPerPage:u,loader:h,error:L}=l,{perPage:d}=i,{initialLoading:m}=h,g=r.useMemo(()=>o.map(v=>typeof v!="object"?{value:v,label:v}:v),[o]),y=r.useCallback(v=>{u(Number(v.target.value))},[u]),M=r.useMemo(()=>({perPage:d,setPerPage:u,options:g}),[d,u,g]);return m||!n||n.length===0||L?null:a.jsx("div",{className:"react-list-per-page",children:s?s(M):a.jsx("select",{value:d,onChange:y,children:g.map(v=>a.jsxs("option",{value:v.value,children:[v.label," items per page"]},`option-${v.value}`))})})}),se=r.memo(({children:s})=>{const{listState:o}=A(),{loader:l,refresh:n}=o,{isLoading:i,initialLoading:u}=l,h=r.useCallback(()=>{n({isRefresh:!0})},[n]),L=r.useMemo(()=>({isLoading:i,refresh:h}),[i,h]);return u?null:s?s(L):a.jsx("div",{className:"react-list-refresh",children:a.jsx("button",{onClick:h,disabled:i,children:i?"Loading...":"Refresh"})})}),ne=r.memo(({children:s,debounceTime:o=500})=>{const{listState:l}=A(),{search:n,setSearch:i}=l,[u,h]=r.useState(n??""),L=r.useRef(null);r.useEffect(()=>{n!==u&&h(n??"")},[n]);const d=g=>{h(g),L.current&&clearTimeout(L.current),L.current=setTimeout(()=>{i(g)},o)};r.useEffect(()=>()=>{L.current&&clearTimeout(L.current)},[]);const m={search:u,setSearch:d};return a.jsx("div",{className:"react-list-search",children:s?s(m):a.jsx("input",{type:"text",value:u,onChange:g=>d(g.target.value),placeholder:"Search..."})})}),ie=r.memo(({children:s})=>{const{listState:o}=A(),{data:l,count:n,pagination:i,loader:u,error:h}=o,{page:L,perPage:d}=i,{initialLoading:m,isLoading:g}=u,y=r.useMemo(()=>{const v=L*d-d+1,z=Math.min(L*d,n),b=(l==null?void 0:l.length)||0;return{from:v,to:z,visibleCount:b}},[L,d,n,l]),M=r.useMemo(()=>({...y,count:n}),[y,n]);return m||!l||l.length===0||h?null:a.jsx("div",{className:"react-list-summary",children:s?s(M):a.jsxs("span",{children:["Showing ",a.jsx("span",{children:y.visibleCount})," items (",a.jsxs("span",{children:[y.from," - ",y.to]}),") out of ",a.jsx("span",{children:n})]})})});P.ReactListAttributes=K,P.ReactListEmpty=Q,P.ReactListError=U,P.ReactListGoTo=V,P.ReactListInitialLoader=X,P.ReactListItems=Y,P.ReactListLoadMore=R,P.ReactListLoader=j,P.ReactListPagination=ee,P.ReactListPerPage=te,P.ReactListProvider=J,P.ReactListRefresh=se,P.ReactListSearch=ne,P.ReactListSummary=ie,P.default=F,Object.defineProperties(P,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
1
+ (function(C,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],a):(C=typeof globalThis<"u"?globalThis:C||self,a(C.ReactList={},C.jsxRuntime,C.react))})(this,function(C,a,r){"use strict";const H=r.createContext(null),K=({children:t,config:o})=>{const{requestHandler:l,stateManager:n={}}=o,[i,u]=r.useState({data:[],response:null,error:null,count:0,selection:[],pagination:{page:1,perPage:25},loader:{isLoading:!1,initialLoading:!0},sort:{sortBy:null,sortOrder:"desc"},search:"",filters:{},attrs:[],isEmpty:!0,isInitializing:!0});if(!l)throw new Error("ListProvider: requestHandler is required.");const f=r.useMemo(()=>({requestHandler:l,stateManager:n,listState:i,setListState:u}),[l,n,i]);return a.jsx(H.Provider,{value:f,children:t})},S=()=>{const t=r.useContext(H);if(!t)throw new Error("useListContext must be used within a ListProvider");return t},Q=r.memo(({children:t,renderAttribute:o})=>{const{listState:l}=S(),{attrs:n,attrSettings:i,updateAttr:u}=l,f=r.useCallback(d=>m=>{u(d,"visible",m.target.checked)},[u]),L=r.useMemo(()=>({attrs:n,attrSettings:i,updateAttr:u}),[n,i,u]);return t?t(L):a.jsx("div",{className:"react-list-attributes",children:n.map((d,m)=>{var h;return o?o({key:`attr-${m}`,attr:d,updateAttr:u,attrSettings:i}):a.jsxs("label",{children:[a.jsx("span",{children:d.label}),a.jsx("input",{type:"checkbox",checked:((h=i==null?void 0:i[d.name])==null?void 0:h.visible)??!1,onChange:f(d.name)})]},`attr-${m}`)})})}),U=r.memo(({children:t})=>{const{listState:o}=S(),{data:l,loader:n,error:i}=o,{isLoading:u,initialLoading:f}=n;return(l==null?void 0:l.length)>0||f||u||i?null:a.jsx("div",{className:"react-list-empty",children:t||a.jsx("div",{children:a.jsx("p",{children:"No data found!"})})})}),V=r.memo(({children:t})=>{const{listState:o}=S(),{error:l,loader:n}=o,{isLoading:i}=n;return!l||i?null:a.jsx("div",{className:"react-list-error",children:typeof t=="function"?t({error:l}):t||a.jsxs("div",{children:[a.jsx("h3",{children:"Error occurred"}),a.jsxs("pre",{children:[l.name,": ",l.message]})]})})}),X=r.memo(({children:t})=>{const{listState:o}=S(),{data:l,count:n,pagination:i,setPage:u,loader:f,error:L}=o,{page:d,perPage:m}=i,{initialLoading:h,isLoading:y}=f,{pages:v,pagesCount:P}=r.useMemo(()=>{const M=Math.ceil(n/m);return{pages:Array.from({length:M},(_,p)=>p+1),pagesCount:M}},[n,m]),T=r.useCallback(M=>{u(Number(M.target.value))},[u]),b=r.useMemo(()=>({setPage:u,page:d,pages:v,pagesCount:P}),[u,d,v,P]);return h||!l||l.length===0||L?null:a.jsx("div",{className:"react-list-go-to",children:t?t(b):a.jsx("select",{value:d,onChange:T,children:v.map(M=>a.jsxs("option",{value:M,children:["Page ",M]},`page-${M}`))})})}),Y=r.memo(({children:t})=>{const{listState:o}=S(),{loader:l}=o,{initialLoading:n}=l;return r.useMemo(()=>({loading:n}),[n]),n?a.jsx("div",{className:"react-list-initial-loader",children:t||a.jsx("p",{children:"Initial Loading..."})}):null}),Z=r.memo(({children:t,renderItem:o})=>{const{listState:l}=S(),{data:n=[],loader:i,error:u,setSort:f,sort:L}=l,{initialLoading:d,isLoading:m}=i,h=r.useMemo(()=>({items:n,isLoading:m,setSort:f,sort:L}),[n,L,f,m]);return d||!n||n.length===0||u?null:o?a.jsx("div",{className:"react-list-items",children:n.map((y,v)=>a.jsx("div",{children:o({item:y,index:v})},y.id||v))}):typeof t=="function"?a.jsx("div",{className:"react-list-items",children:t(h)}):a.jsx("div",{className:"react-list-items",children:n.map((y,v)=>a.jsx("pre",{children:JSON.stringify(y,null,2)},y.id||v))})}),$=(t,o)=>{if(t===o)return!0;if(t==null||o==null||typeof t!="object"||typeof o!="object")return t===o;if(Array.isArray(t)&&Array.isArray(o)){if(t.length!==o.length)return!1;for(let i=0;i<t.length;i++)if(!$(t[i],o[i]))return!1;return!0}if(Array.isArray(t)||Array.isArray(o))return!1;const l=Object.keys(t).filter(i=>t[i]!==void 0),n=Object.keys(o).filter(i=>o[i]!==void 0);if(l.length!==n.length)return!1;for(let i of l)if(!n.includes(i)||!$(t[i],o[i]))return!1;return!0},F=(t,o)=>!o||Object.keys(o).length===0?t&&Object.keys(t).length>0:!t||Object.keys(t).length===0?!1:!$(t,o),R=({initialItems:t=[],children:o,endpoint:l,page:n=1,perPage:i=25,sortBy:u="",sortOrder:f="desc",count:L=0,search:d="",filters:m={},attrs:h,version:y=1,paginationMode:v="pagination",meta:P={},onResponse:T,afterPageChange:b,afterLoadMore:M})=>{const{requestHandler:x,setListState:_,stateManager:p}=S(),q=r.useRef(!1),A=v==="loadMore",w=r.useCallback(e=>({endpoint:l,version:y,meta:P,search:(e==null?void 0:e.search)||d,page:(e==null?void 0:e.page)||n,perPage:(e==null?void 0:e.perPage)||i,sortBy:(e==null?void 0:e.sortBy)||u,sortOrder:(e==null?void 0:e.sortOrder)||f,filters:(e==null?void 0:e.filters)||m,attrSettings:(e==null?void 0:e.attrSettings)||{},isRefresh:!1}),[l,y,P,d,n,i,u,f,m]),k=r.useCallback(()=>{var e;try{const g=w(),c=(e=p==null?void 0:p.get)==null?void 0:e.call(p,g);return{page:c==null?void 0:c.page,perPage:c==null?void 0:c.perPage,sortBy:c==null?void 0:c.sortBy,sortOrder:c==null?void 0:c.sortOrder,search:c==null?void 0:c.search,attrSettings:c==null?void 0:c.attrSettings,filters:c==null?void 0:c.filters}}catch(g){return console.error(g),{}}},[w,p]),B=r.useCallback(()=>{const e=k();let g=n;return A?g=1:e.page!=null&&(g=e.page),{page:g,perPage:e.perPage!=null?e.perPage:i,sortBy:e.sortBy!=null?e.sortBy:u,sortOrder:e.sortOrder!=null?e.sortOrder:f,search:e.search!=null?e.search:d,filters:e.filters!=null?e.filters:m,attrSettings:e.attrSettings||{},items:t,selection:[],error:null,response:null,count:0,isLoading:!1,initializingState:!t.length,confirmedPage:null}},[k,d,n,i,u,f,d,m,A]),[s,O]=r.useState(B),I=r.useCallback(e=>{var g;if(p){const c=w(e);(g=p==null?void 0:p.set)==null||g.call(p,c)}},[p,w]),N=r.useCallback(async(e={},g=null)=>{s.initializingState||O(c=>({...c,error:null,isLoading:!0}));try{const c=g||s,E=(g==null?void 0:g.items)??s.items,z=await x({endpoint:l,version:y,meta:P,page:c.page,perPage:c.perPage,search:c.search,sortBy:c.sortBy,sortOrder:c.sortOrder,filters:c.filters,...e});T&&T(z);let W;A?(W=c.page===1?z.items:[...E,...z.items],M&&M(z)):(W=z.items,b&&b(z));const J={...c,response:z,selection:[],items:A&&c.page>1?[...E,...z.items]:z.items,count:z.count,initializingState:!1,isLoading:!1};I(J),O(J)}catch(c){throw O(E=>({...E,error:c,items:[],count:0,initializingState:!1,isLoading:!1})),c}},[l,y,A,P,x,s]),D=r.useMemo(()=>({setPage:(e,g)=>{let c=e;e===0&&(c="");const E={...s,page:c};O(E),c&&N(g,E)},setPerPage:e=>{const g={...s,perPage:e,page:1};O(g),N({},g)},setSearch:e=>{if(e!==s.search){const g={...s,search:e,page:1};O(g),N({},g)}},setSort:({by:e,order:g})=>{const c={...s,sortBy:e,sortOrder:g,page:1};O(c),N({},c)},loadMore:()=>{const e={...s,page:s.page+1};O(e),N({},e)},clearFilters:()=>{const e={...s,filters:m,page:1};O(e),N({},e)},refresh:(e={isRefresh:!0})=>{if(A){const g={...s,page:1,items:[]};O(g),N(e,g)}else N(e)},setFilters:e=>{const g={...s,filters:e,page:1};O(g),N({},g)},updateItemById:(e,g)=>{const c=s.items.map(E=>E.id===g?{...E,...e}:E);O(E=>({...E,items:c}))},setSelection:e=>O(g=>({...g,selection:e}))}),[N,A,s]),G=r.useMemo(()=>({data:s.items,response:s.response,error:s.error,count:s.count,selection:s.selection,pagination:{page:s.page,perPage:s.perPage,hasMore:s.items.length<s.count},loader:{isLoading:s.isLoading,initialLoading:s.initializingState},sort:{sortBy:s.sortBy,sortOrder:s.sortOrder},hasActiveFilters:F(s.filters,m),search:s.search,filters:s.filters,attrs:h||Object.keys(s.items[0]||{}),isEmpty:s.items.length===0,...D}),[s.items,s.response,s.error,s.count,s.selection,s.page,s.perPage,s.isLoading,s.initializingState,s.sortBy,s.sortOrder,s.search,s.filters,D,h]);return r.useEffect(()=>{if(s.initializingState&&!q.current){if(q.current=!0,p!=null&&p.init){const e=w(s);p.init(e)}t.length||D.setPage(s.page)}},[]),r.useEffect(()=>{_(G)},[_,s.items,s.count,s.error,s.isLoading,s.selection,s.page,s.perPage,s.sortBy,s.sortOrder]),typeof o=="function"?o(G):o},j=r.memo(({children:t})=>{const{listState:o}=S(),{data:l,count:n,pagination:i,setPage:u,loader:f,error:L}=o,{page:d,perPage:m}=i,{isLoading:h}=f,y=r.useMemo(()=>d*m<n,[d,m,n]),v=r.useCallback(()=>{y&&!h&&u(d+1)},[y,h,u,d]),P=r.useMemo(()=>({isLoading:h,loadMore:v,hasMoreItems:y}),[h,v,y]);return!l||l.length===0||L?null:t(P)}),ee=r.memo(({children:t,position:o="overlay"})=>{const{listState:l}=S(),{loader:n}=l,{isLoading:i,initializingState:u}=n;return r.useMemo(()=>({isLoading:i}),[i]),!u&&!i?null:a.jsx("div",{children:t||a.jsx("div",{children:a.jsx("p",{children:"Loading..."})})})}),se=r.memo(({children:t,pageLinks:o=5,renderFirst:l,renderPrev:n,renderPages:i,renderPage:u,renderNext:f,renderLast:L})=>{const{listState:d}=S(),{data:m,count:h,pagination:y,setPage:v,loader:P,error:T}=d,{page:b,perPage:M}=y,{initialLoading:x,isLoading:_}=P,p=r.useMemo(()=>{const k=Math.ceil(h/M),B=Math.floor(o/2),s=b*M<h;return{pagesCount:k,halfWay:B,hasNext:s,hasPrev:b!==1}},[h,M,b,o]),q=r.useMemo(()=>{const{pagesCount:k,halfWay:B}=p,s=Array.from({length:Math.min(o,k)});return b<=B?s.map((O,I)=>I+1):k-b<B?s.map((O,I)=>k-I).reverse():s.map((O,I)=>b-B+I)},[b,o,p]),A=r.useMemo(()=>({prev:()=>v(b-1),next:()=>v(b+1),first:()=>v(1),last:()=>v(p.pagesCount),setPage:k=>v(k)}),[v,b,p.pagesCount]),w=r.useMemo(()=>({page:b,perPage:M,count:h,...p,pagesToDisplay:q,...A}),[b,M,h,p,q,A]);return x||!m||m.length===0||T?null:t?t(w):a.jsxs("div",{className:"react-list-pagination",children:[l?l(w):a.jsx("button",{type:"button",disabled:!p.hasPrev,onClick:A.first,children:"First"}),n?n(w):a.jsx("button",{type:"button",disabled:!p.hasPrev,onClick:A.prev,children:"Prev"}),i?i(w):a.jsx("div",{children:q.map(k=>{const B=k===b,s={...w,page:k,isActive:B};return u?u(s):a.jsx("div",{children:B?a.jsx("span",{children:k}):a.jsx("button",{type:"button",onClick:()=>A.setPage(k),children:k})},`page-${k}`)})}),f?f(w):a.jsx("button",{type:"button",disabled:!p.hasNext,onClick:A.next,children:"Next"}),L?L(w):a.jsx("button",{type:"button",disabled:!p.hasNext,onClick:A.last,children:"Last"})]})}),te=r.memo(({children:t,options:o=[10,25,50,100]})=>{const{listState:l}=S(),{data:n,pagination:i,setPerPage:u,loader:f,error:L}=l,{perPage:d}=i,{initialLoading:m}=f,h=r.useMemo(()=>o.map(P=>typeof P!="object"?{value:P,label:P}:P),[o]),y=r.useCallback(P=>{u(Number(P.target.value))},[u]),v=r.useMemo(()=>({perPage:d,setPerPage:u,options:h}),[d,u,h]);return m||!n||n.length===0||L?null:a.jsx("div",{className:"react-list-per-page",children:t?t(v):a.jsx("select",{value:d,onChange:y,children:h.map(P=>a.jsxs("option",{value:P.value,children:[P.label," items per page"]},`option-${P.value}`))})})}),ne=r.memo(({children:t})=>{const{listState:o}=S(),{loader:l,refresh:n}=o,{isLoading:i,initialLoading:u}=l,f=r.useCallback(()=>{n({isRefresh:!0})},[n]),L=r.useMemo(()=>({isLoading:i,refresh:f}),[i,f]);return u?null:t?t(L):a.jsx("div",{className:"react-list-refresh",children:a.jsx("button",{onClick:f,disabled:i,children:i?"Loading...":"Refresh"})})}),ie=r.memo(({children:t,debounceTime:o=500})=>{const{listState:l}=S(),{search:n,setSearch:i}=l,[u,f]=r.useState(n??""),L=r.useRef(null);r.useEffect(()=>{n!==u&&f(n??"")},[n]);const d=h=>{f(h),L.current&&clearTimeout(L.current),L.current=setTimeout(()=>{i(h)},o)};r.useEffect(()=>()=>{L.current&&clearTimeout(L.current)},[]);const m={search:u,setSearch:d};return a.jsx("div",{className:"react-list-search",children:t?t(m):a.jsx("input",{type:"text",value:u,onChange:h=>d(h.target.value),placeholder:"Search..."})})}),re=r.memo(({children:t})=>{const{listState:o}=S(),{data:l,count:n,pagination:i,loader:u,error:f}=o,{page:L,perPage:d}=i,{initialLoading:m,isLoading:h}=u,y=r.useMemo(()=>{const P=L*d-d+1,T=Math.min(L*d,n),b=(l==null?void 0:l.length)||0;return{from:P,to:T,visibleCount:b}},[L,d,n,l]),v=r.useMemo(()=>({...y,count:n}),[y,n]);return m||!l||l.length===0||f?null:a.jsx("div",{className:"react-list-summary",children:t?t(v):a.jsxs("span",{children:["Showing ",a.jsx("span",{children:y.visibleCount})," items (",a.jsxs("span",{children:[y.from," - ",y.to]}),") out of ",a.jsx("span",{children:n})]})})});C.ReactListAttributes=Q,C.ReactListEmpty=U,C.ReactListError=V,C.ReactListGoTo=X,C.ReactListInitialLoader=Y,C.ReactListItems=Z,C.ReactListLoadMore=j,C.ReactListLoader=ee,C.ReactListPagination=se,C.ReactListPerPage=te,C.ReactListProvider=K,C.ReactListRefresh=ne,C.ReactListSearch=ie,C.ReactListSummary=re,C.default=R,Object.defineProperties(C,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json CHANGED
@@ -1,23 +1,32 @@
1
1
  {
2
2
  "name": "@7span/react-list",
3
- "version": "0.0.6",
3
+ "version": "1.0.0",
4
4
  "description": "A simple and reusable list component for React",
5
5
  "type": "module",
6
- "main": "dist/react-list.js",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "lint": "eslint .",
10
+ "preview": "vite preview",
11
+ "prepublishOnly": "npm run build"
12
+ },
13
+ "main": "src/index.js",
14
+ "exports": {
15
+ ".": "./src/index.js"
16
+ },
7
17
  "files": [
8
- "dist"
18
+ "dist",
19
+ "src"
9
20
  ],
21
+ "peerDependencies": {
22
+ "react": "^18.2.0 || ^19.0.0",
23
+ "react-dom": "^18.2.0 || ^19.0.0"
24
+ },
10
25
  "publishConfig": {
11
26
  "access": "public"
12
27
  },
13
28
  "devDependencies": {
14
29
  "@vitejs/plugin-react": "^4.3.4",
15
30
  "vite": "^6.3.1"
16
- },
17
- "scripts": {
18
- "dev": "vite",
19
- "build": "vite build",
20
- "lint": "eslint .",
21
- "preview": "vite preview"
22
31
  }
23
- }
32
+ }
@@ -0,0 +1,53 @@
1
+ import { memo, useCallback, useMemo } from "react";
2
+ import { useListContext } from "../context/list-provider";
3
+
4
+ export const ReactListAttributes = memo(({ children, renderAttribute }) => {
5
+ const { listState } = useListContext();
6
+ const { attrs, attrSettings, updateAttr } = listState;
7
+
8
+ const handleAttrChange = useCallback(
9
+ (attrName) => (e) => {
10
+ updateAttr(attrName, "visible", e.target.checked);
11
+ },
12
+ [updateAttr]
13
+ );
14
+
15
+ const scope = useMemo(
16
+ () => ({
17
+ attrs,
18
+ attrSettings,
19
+ updateAttr,
20
+ }),
21
+ [attrs, attrSettings, updateAttr]
22
+ );
23
+
24
+ if (children) {
25
+ return children(scope);
26
+ }
27
+
28
+ return (
29
+ <div className="react-list-attributes">
30
+ {attrs.map((attr, index) => {
31
+ if (renderAttribute) {
32
+ return renderAttribute({
33
+ key: `attr-${index}`,
34
+ attr,
35
+ updateAttr,
36
+ attrSettings,
37
+ });
38
+ }
39
+
40
+ return (
41
+ <label key={`attr-${index}`}>
42
+ <span>{attr.label}</span>
43
+ <input
44
+ type="checkbox"
45
+ checked={attrSettings?.[attr.name]?.visible ?? false}
46
+ onChange={handleAttrChange(attr.name)}
47
+ />
48
+ </label>
49
+ );
50
+ })}
51
+ </div>
52
+ );
53
+ });
@@ -0,0 +1,22 @@
1
+ import { memo } from "react";
2
+ import { useListContext } from "../context/list-provider";
3
+
4
+ export const ReactListEmpty = memo(({ children }) => {
5
+ const { listState } = useListContext();
6
+ const { data: items, loader, error } = listState;
7
+ const { isLoading, initialLoading } = loader;
8
+
9
+ if (items?.length > 0 || initialLoading || isLoading || error) {
10
+ return null;
11
+ }
12
+
13
+ return (
14
+ <div className="react-list-empty">
15
+ {children || (
16
+ <div>
17
+ <p>No data found!</p>
18
+ </div>
19
+ )}
20
+ </div>
21
+ );
22
+ });
@@ -0,0 +1,27 @@
1
+ import { memo } from "react";
2
+ import { useListContext } from "../context/list-provider";
3
+
4
+ export const ReactListError = memo(({ children }) => {
5
+ const { listState } = useListContext();
6
+ const { error, loader } = listState;
7
+ const { isLoading } = loader;
8
+
9
+ if (!error || isLoading) {
10
+ return null;
11
+ }
12
+
13
+ return (
14
+ <div className="react-list-error">
15
+ {typeof children === "function"
16
+ ? children({ error })
17
+ : children || (
18
+ <div>
19
+ <h3>Error occurred</h3>
20
+ <pre>
21
+ {error.name}: {error.message}
22
+ </pre>
23
+ </div>
24
+ )}
25
+ </div>
26
+ );
27
+ });
@@ -0,0 +1,58 @@
1
+ import { memo, useCallback, useMemo } from "react";
2
+ import { useListContext } from "../context/list-provider";
3
+
4
+ export const ReactListGoTo = memo(({ children }) => {
5
+ const { listState } = useListContext();
6
+ const { data, count, pagination, setPage, loader, error } = listState;
7
+ const { page, perPage } = pagination;
8
+ const { initialLoading, isLoading } = loader;
9
+
10
+ const { pages, pagesCount } = useMemo(() => {
11
+ const pagesCount = Math.ceil(count / perPage);
12
+ const pages = Array.from({ length: pagesCount }, (_, i) => i + 1);
13
+ return { pages, pagesCount };
14
+ }, [count, perPage]);
15
+
16
+ const handlePageChange = useCallback(
17
+ (e) => {
18
+ setPage(Number(e.target.value));
19
+ },
20
+ [setPage]
21
+ );
22
+
23
+ const scope = useMemo(
24
+ () => ({
25
+ setPage,
26
+ page,
27
+ pages,
28
+ pagesCount,
29
+ }),
30
+ [setPage, page, pages, pagesCount]
31
+ );
32
+
33
+ if (initialLoading) return null;
34
+
35
+ if (!data || data.length === 0) {
36
+ return null;
37
+ }
38
+
39
+ if (error) {
40
+ return null;
41
+ }
42
+
43
+ return (
44
+ <div className="react-list-go-to">
45
+ {children ? (
46
+ children(scope)
47
+ ) : (
48
+ <select value={page} onChange={handlePageChange}>
49
+ {pages.map((pageNum) => (
50
+ <option key={`page-${pageNum}`} value={pageNum}>
51
+ Page {pageNum}
52
+ </option>
53
+ ))}
54
+ </select>
55
+ )}
56
+ </div>
57
+ );
58
+ });
@@ -0,0 +1,25 @@
1
+ import { memo, useMemo } from "react";
2
+ import { useListContext } from "../context/list-provider";
3
+
4
+ export const ReactListInitialLoader = memo(({ children }) => {
5
+ const { listState } = useListContext();
6
+ const { loader } = listState;
7
+ const { initialLoading } = loader;
8
+
9
+ const scope = useMemo(
10
+ () => ({
11
+ loading: initialLoading,
12
+ }),
13
+ [initialLoading]
14
+ );
15
+
16
+ if (!initialLoading) {
17
+ return null;
18
+ }
19
+
20
+ return (
21
+ <div className="react-list-initial-loader">
22
+ {children || <p>Initial Loading...</p>}
23
+ </div>
24
+ );
25
+ });
@@ -0,0 +1,50 @@
1
+ import { memo, useMemo } from "react";
2
+ import { useListContext } from "../context/list-provider";
3
+
4
+ export const ReactListItems = memo(({ children, renderItem }) => {
5
+ const { listState } = useListContext();
6
+ const { data: items = [], loader, error, setSort, sort } = listState;
7
+ const { initialLoading, isLoading } = loader;
8
+
9
+ const scope = useMemo(
10
+ () => ({
11
+ items,
12
+ isLoading,
13
+ setSort,
14
+ sort,
15
+ }),
16
+ [items, sort, setSort, isLoading]
17
+ );
18
+
19
+ if (initialLoading) return null;
20
+
21
+ if (!items || items.length === 0) {
22
+ return null;
23
+ }
24
+
25
+ if (error) {
26
+ return null;
27
+ }
28
+
29
+ if (renderItem) {
30
+ return (
31
+ <div className="react-list-items">
32
+ {items.map((item, index) => (
33
+ <div key={item.id || index}>{renderItem({ item, index })}</div>
34
+ ))}
35
+ </div>
36
+ );
37
+ }
38
+
39
+ if (typeof children === "function") {
40
+ return <div className="react-list-items">{children(scope)}</div>;
41
+ }
42
+
43
+ return (
44
+ <div className="react-list-items">
45
+ {items.map((item, index) => (
46
+ <pre key={item.id || index}>{JSON.stringify(item, null, 2)}</pre>
47
+ ))}
48
+ </div>
49
+ );
50
+ });