@7span/react-list 0.0.6 → 1.0.1
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.
- package/dist/react-list.js +380 -356
- package/dist/react-list.umd.cjs +1 -1
- package/package.json +19 -10
- package/src/components/attributes.jsx +53 -0
- package/src/components/empty.jsx +22 -0
- package/src/components/error.jsx +27 -0
- package/src/components/go-to.jsx +58 -0
- package/src/components/initial-loader.jsx +25 -0
- package/src/components/items.jsx +50 -0
- package/src/components/list.jsx +375 -0
- package/src/components/load-more.jsx +39 -0
- package/src/components/loader.jsx +29 -0
- package/src/components/pagination.jsx +158 -0
- package/src/components/per-page.jsx +65 -0
- package/src/components/refresh.jsx +34 -0
- package/src/components/search.jsx +59 -0
- package/src/components/summary.jsx +51 -0
- package/src/components/utils.js +42 -0
- package/src/context/list-provider.jsx +55 -0
- package/src/index.js +15 -0
- package/src/utils.js +31 -0
package/dist/react-list.umd.cjs
CHANGED
|
@@ -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,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],l):(C=typeof globalThis<"u"?globalThis:C||self,l(C.ReactList={},C.jsxRuntime,C.react))})(this,function(C,l,o){"use strict";const G=o.createContext(null),Q=({children:e,config:i})=>{const{requestHandler:a,stateManager:r={}}=i,[n,u]=o.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(!a)throw new Error("ListProvider: requestHandler is required.");const h=o.useMemo(()=>({requestHandler:a,stateManager:r,listState:n,setListState:u}),[a,r,n]);return l.jsx(G.Provider,{value:h,children:e})},S=()=>{const e=o.useContext(G);if(!e)throw new Error("useListContext must be used within a ListProvider");return e},U=o.memo(({children:e,renderAttribute:i})=>{const{listState:a}=S(),{attrs:r,attrSettings:n,updateAttr:u}=a,h=o.useCallback(f=>g=>{u(f,"visible",g.target.checked)},[u]),m=o.useMemo(()=>({attrs:r,attrSettings:n,updateAttr:u}),[r,n,u]);return e?e(m):l.jsx("div",{className:"react-list-attributes",children:r.map((f,g)=>{var p;return i?i({key:`attr-${g}`,attr:f,updateAttr:u,attrSettings:n}):l.jsxs("label",{children:[l.jsx("span",{children:f.label}),l.jsx("input",{type:"checkbox",checked:((p=n==null?void 0:n[f.name])==null?void 0:p.visible)??!1,onChange:h(f.name)})]},`attr-${g}`)})})}),V=o.memo(({children:e})=>{const{listState:i}=S(),{data:a,loader:r,error:n}=i,{isLoading:u,initialLoading:h}=r;return(a==null?void 0:a.length)>0||h||u||n?null:l.jsx("div",{className:"react-list-empty",children:e||l.jsx("div",{children:l.jsx("p",{children:"No data found!"})})})}),X=o.memo(({children:e})=>{const{listState:i}=S(),{error:a,loader:r}=i,{isLoading:n}=r;return!a||n?null:l.jsx("div",{className:"react-list-error",children:typeof e=="function"?e({error:a}):e||l.jsxs("div",{children:[l.jsx("h3",{children:"Error occurred"}),l.jsxs("pre",{children:[a.name,": ",a.message]})]})})}),Y=o.memo(({children:e})=>{const{listState:i}=S(),{data:a,count:r,pagination:n,setPage:u,loader:h,error:m}=i,{page:f,perPage:g}=n,{initialLoading:p,isLoading:L}=h,{pages:v,pagesCount:P}=o.useMemo(()=>{const b=Math.ceil(r/g);return{pages:Array.from({length:b},(_,y)=>y+1),pagesCount:b}},[r,g]),T=o.useCallback(b=>{u(Number(b.target.value))},[u]),k=o.useMemo(()=>({setPage:u,page:f,pages:v,pagesCount:P}),[u,f,v,P]);return p||!a||a.length===0||m?null:l.jsx("div",{className:"react-list-go-to",children:e?e(k):l.jsx("select",{value:f,onChange:T,children:v.map(b=>l.jsxs("option",{value:b,children:["Page ",b]},`page-${b}`))})})}),Z=o.memo(({children:e})=>{const{listState:i}=S(),{loader:a}=i,{initialLoading:r}=a;return o.useMemo(()=>({loading:r}),[r]),r?l.jsx("div",{className:"react-list-initial-loader",children:e||l.jsx("p",{children:"Initial Loading..."})}):null}),F=o.memo(({children:e,renderItem:i})=>{const{listState:a}=S(),{data:r=[],loader:n,error:u,setSort:h,sort:m}=a,{initialLoading:f,isLoading:g}=n,p=o.useMemo(()=>({items:r,isLoading:g,setSort:h,sort:m}),[r,m,h,g]);return f||!r||r.length===0||u?null:i?l.jsx("div",{className:"react-list-items",children:r.map((L,v)=>l.jsx("div",{children:i({item:L,index:v})},L.id||v))}):typeof e=="function"?l.jsx("div",{className:"react-list-items",children:e(p)}):l.jsx("div",{className:"react-list-items",children:r.map((L,v)=>l.jsx("pre",{children:JSON.stringify(L,null,2)},L.id||v))})}),$=(e,i)=>{if(e===i)return!0;if(e==null||i==null||typeof e!="object"||typeof i!="object")return e===i;if(Array.isArray(e)&&Array.isArray(i)){if(e.length!==i.length)return!1;for(let n=0;n<e.length;n++)if(!$(e[n],i[n]))return!1;return!0}if(Array.isArray(e)||Array.isArray(i))return!1;const a=Object.keys(e).filter(n=>e[n]!==void 0),r=Object.keys(i).filter(n=>i[n]!==void 0);if(a.length!==r.length)return!1;for(let n of a)if(!r.includes(n)||!$(e[n],i[n]))return!1;return!0},R=(e,i)=>!i||Object.keys(i).length===0?e&&Object.keys(e).length>0:!e||Object.keys(e).length===0?!1:!$(e,i),D=(e,i)=>{if(e===i)return!0;if(e==null||i==null||typeof e!=typeof i)return!1;if(typeof e=="object"){if(Array.isArray(e)!==Array.isArray(i))return!1;if(Array.isArray(e)){if(e.length!==i.length)return!1;for(let n=0;n<e.length;n++)if(!D(e[n],i[n]))return!1;return!0}const a=Object.keys(e),r=Object.keys(i);if(a.length!==r.length)return!1;for(const n of a)if(!r.includes(n)||!D(e[n],i[n]))return!1;return!0}return!1},j=({initialItems:e=[],children:i,endpoint:a,page:r=1,perPage:n=25,sortBy:u="",sortOrder:h="desc",count:m=0,search:f="",filters:g={},attrs:p,version:L=1,paginationMode:v="pagination",meta:P={},onResponse:T,afterPageChange:k,afterLoadMore:b})=>{const{requestHandler:x,setListState:_,stateManager:y}=S(),I=o.useRef(!1),O=v==="loadMore",E=o.useCallback(t=>({endpoint:a,version:L,meta:P,search:(t==null?void 0:t.search)||f,page:(t==null?void 0:t.page)||r,perPage:(t==null?void 0:t.perPage)||n,sortBy:(t==null?void 0:t.sortBy)||u,sortOrder:(t==null?void 0:t.sortOrder)||h,filters:(t==null?void 0:t.filters)||g,attrSettings:(t==null?void 0:t.attrSettings)||{},isRefresh:!1}),[a,L,P,f,r,n,u,h,g]),A=o.useCallback(()=>{var t;try{const d=E(),c=(t=y==null?void 0:y.get)==null?void 0:t.call(y,d);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(d){return console.error(d),{}}},[E,y]),N=o.useCallback(()=>{const t=A();let d=r;return O?d=1:t.page!=null&&(d=t.page),{page:d,perPage:t.perPage!=null?t.perPage:n,sortBy:t.sortBy!=null?t.sortBy:u,sortOrder:t.sortOrder!=null?t.sortOrder:h,search:t.search!=null?t.search:f,filters:t.filters!=null?t.filters:g,attrSettings:t.attrSettings||{},items:e,selection:[],error:null,response:null,count:0,isLoading:!1,initializingState:!e.length,confirmedPage:null}},[A,f,r,n,u,h,f,g,O]),[s,M]=o.useState(N),q=o.useCallback(t=>{var d;if(y){const c=E(t);(d=y==null?void 0:y.set)==null||d.call(y,c)}},[y,E]),B=o.useCallback(async(t={},d=null)=>{s.initializingState||M(c=>({...c,error:null,isLoading:!0}));try{const c=d||s,w=(d==null?void 0:d.items)??s.items,z=await x({endpoint:a,version:L,meta:P,page:c.page,perPage:c.perPage,search:c.search,sortBy:c.sortBy,sortOrder:c.sortOrder,filters:c.filters,...t});T&&T(z);let J;O?(J=c.page===1?z.items:[...w,...z.items],b&&b(z)):(J=z.items,k&&k(z));const K={...c,response:z,selection:[],items:O&&c.page>1?[...w,...z.items]:z.items,count:z.count,initializingState:!1,isLoading:!1};q(K),M(K)}catch(c){throw M(w=>({...w,error:c,items:[],count:0,initializingState:!1,isLoading:!1})),c}},[a,L,O,P,x,s]),H=o.useMemo(()=>({setPage:(t,d)=>{let c=t;t===0&&(c="");const w={...s,page:c};M(w),c&&B(d,w)},setPerPage:t=>{const d={...s,perPage:t,page:1};M(d),B({},d)},setSearch:t=>{if(t!==s.search){const d={...s,search:t,page:1};M(d),B({},d)}},setSort:({by:t,order:d})=>{const c={...s,sortBy:t,sortOrder:d,page:1};M(c),B({},c)},loadMore:()=>{const t={...s,page:s.page+1};M(t),B({},t)},clearFilters:()=>{const t={...s,filters:g,page:1};M(t),B({},t)},refresh:(t={isRefresh:!0})=>{if(O){const d={...s,page:1,items:[]};M(d),B(t,d)}else B(t)},setFilters:t=>{const d={...s,filters:t,page:1};M(d),B({},d)},updateItemById:(t,d)=>{const c=s.items.map(w=>w.id===d?{...w,...t}:w);M(w=>({...w,items:c}))},setSelection:t=>M(d=>({...d,selection:t}))}),[B,O,s]),W=o.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:R(s.filters,g),search:s.search,filters:s.filters,attrs:p||Object.keys(s.items[0]||{}),isEmpty:s.items.length===0,...H}),[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,H,p]);return o.useEffect(()=>{if(s.initializingState&&!I.current){if(I.current=!0,y!=null&&y.init){const t=E(s);y.init(t)}e.length||H.setPage(s.page)}},[]),o.useEffect(()=>{if(I.current&&!D(g,s.filters)){const t={...s,filters:g,page:1};M(t),B({},t)}},[g]),o.useEffect(()=>{_(W)},[_,s.items,s.count,s.error,s.isLoading,s.selection,s.page,s.perPage,s.sortBy,s.sortOrder]),typeof i=="function"?i(W):i},ee=o.memo(({children:e})=>{const{listState:i}=S(),{data:a,count:r,pagination:n,setPage:u,loader:h,error:m}=i,{page:f,perPage:g}=n,{isLoading:p}=h,L=o.useMemo(()=>f*g<r,[f,g,r]),v=o.useCallback(()=>{L&&!p&&u(f+1)},[L,p,u,f]),P=o.useMemo(()=>({isLoading:p,loadMore:v,hasMoreItems:L}),[p,v,L]);return!a||a.length===0||m?null:e(P)}),te=o.memo(({children:e,position:i="overlay"})=>{const{listState:a}=S(),{loader:r}=a,{isLoading:n,initializingState:u}=r;return o.useMemo(()=>({isLoading:n}),[n]),!u&&!n?null:l.jsx("div",{children:e||l.jsx("div",{children:l.jsx("p",{children:"Loading..."})})})}),se=o.memo(({children:e,pageLinks:i=5,renderFirst:a,renderPrev:r,renderPages:n,renderPage:u,renderNext:h,renderLast:m})=>{const{listState:f}=S(),{data:g,count:p,pagination:L,setPage:v,loader:P,error:T}=f,{page:k,perPage:b}=L,{initialLoading:x,isLoading:_}=P,y=o.useMemo(()=>{const A=Math.ceil(p/b),N=Math.floor(i/2),s=k*b<p;return{pagesCount:A,halfWay:N,hasNext:s,hasPrev:k!==1}},[p,b,k,i]),I=o.useMemo(()=>{const{pagesCount:A,halfWay:N}=y,s=Array.from({length:Math.min(i,A)});return k<=N?s.map((M,q)=>q+1):A-k<N?s.map((M,q)=>A-q).reverse():s.map((M,q)=>k-N+q)},[k,i,y]),O=o.useMemo(()=>({prev:()=>v(k-1),next:()=>v(k+1),first:()=>v(1),last:()=>v(y.pagesCount),setPage:A=>v(A)}),[v,k,y.pagesCount]),E=o.useMemo(()=>({page:k,perPage:b,count:p,...y,pagesToDisplay:I,...O}),[k,b,p,y,I,O]);return x||!g||g.length===0||T?null:e?e(E):l.jsxs("div",{className:"react-list-pagination",children:[a?a(E):l.jsx("button",{type:"button",disabled:!y.hasPrev,onClick:O.first,children:"First"}),r?r(E):l.jsx("button",{type:"button",disabled:!y.hasPrev,onClick:O.prev,children:"Prev"}),n?n(E):l.jsx("div",{children:I.map(A=>{const N=A===k,s={...E,page:A,isActive:N};return u?u(s):l.jsx("div",{children:N?l.jsx("span",{children:A}):l.jsx("button",{type:"button",onClick:()=>O.setPage(A),children:A})},`page-${A}`)})}),h?h(E):l.jsx("button",{type:"button",disabled:!y.hasNext,onClick:O.next,children:"Next"}),m?m(E):l.jsx("button",{type:"button",disabled:!y.hasNext,onClick:O.last,children:"Last"})]})}),ne=o.memo(({children:e,options:i=[10,25,50,100]})=>{const{listState:a}=S(),{data:r,pagination:n,setPerPage:u,loader:h,error:m}=a,{perPage:f}=n,{initialLoading:g}=h,p=o.useMemo(()=>i.map(P=>typeof P!="object"?{value:P,label:P}:P),[i]),L=o.useCallback(P=>{u(Number(P.target.value))},[u]),v=o.useMemo(()=>({perPage:f,setPerPage:u,options:p}),[f,u,p]);return g||!r||r.length===0||m?null:l.jsx("div",{className:"react-list-per-page",children:e?e(v):l.jsx("select",{value:f,onChange:L,children:p.map(P=>l.jsxs("option",{value:P.value,children:[P.label," items per page"]},`option-${P.value}`))})})}),ie=o.memo(({children:e})=>{const{listState:i}=S(),{loader:a,refresh:r}=i,{isLoading:n,initialLoading:u}=a,h=o.useCallback(()=>{r({isRefresh:!0})},[r]),m=o.useMemo(()=>({isLoading:n,refresh:h}),[n,h]);return u?null:e?e(m):l.jsx("div",{className:"react-list-refresh",children:l.jsx("button",{onClick:h,disabled:n,children:n?"Loading...":"Refresh"})})}),re=o.memo(({children:e,debounceTime:i=500})=>{const{listState:a}=S(),{search:r,setSearch:n}=a,[u,h]=o.useState(r??""),m=o.useRef(null);o.useEffect(()=>{r!==u&&h(r??"")},[r]);const f=p=>{h(p),m.current&&clearTimeout(m.current),m.current=setTimeout(()=>{n(p)},i)};o.useEffect(()=>()=>{m.current&&clearTimeout(m.current)},[]);const g={search:u,setSearch:f};return l.jsx("div",{className:"react-list-search",children:e?e(g):l.jsx("input",{type:"text",value:u,onChange:p=>f(p.target.value),placeholder:"Search..."})})}),oe=o.memo(({children:e})=>{const{listState:i}=S(),{data:a,count:r,pagination:n,loader:u,error:h}=i,{page:m,perPage:f}=n,{initialLoading:g,isLoading:p}=u,L=o.useMemo(()=>{const P=m*f-f+1,T=Math.min(m*f,r),k=(a==null?void 0:a.length)||0;return{from:P,to:T,visibleCount:k}},[m,f,r,a]),v=o.useMemo(()=>({...L,count:r}),[L,r]);return g||!a||a.length===0||h?null:l.jsx("div",{className:"react-list-summary",children:e?e(v):l.jsxs("span",{children:["Showing ",l.jsx("span",{children:L.visibleCount})," items (",l.jsxs("span",{children:[L.from," - ",L.to]}),") out of ",l.jsx("span",{children:r})]})})});C.ReactListAttributes=U,C.ReactListEmpty=V,C.ReactListError=X,C.ReactListGoTo=Y,C.ReactListInitialLoader=Z,C.ReactListItems=F,C.ReactListLoadMore=ee,C.ReactListLoader=te,C.ReactListPagination=se,C.ReactListPerPage=ne,C.ReactListProvider=Q,C.ReactListRefresh=ie,C.ReactListSearch=re,C.ReactListSummary=oe,C.default=j,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": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A simple and reusable list component for React",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"
|
|
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
|
+
});
|