@apipass/design-system 1.20.1 → 1.21.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,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),g=require("react");;/* empty css */const X=require("../../primitives/Search/Search.cjs"),i=require("../../primitives/Table/Table.cjs"),Y=require("../../icons/IconChevronDown.cjs"),Z=require("../../icons/IconChevronRight.cjs"),K=require("../../primitives/PermissionGate/PermissionGate.cjs"),ee=require("../../icons/IconArrowLeft.cjs"),ae=require("../../icons/IconArrowRight.cjs"),se=require("../../layout/Flex/Flex.cjs");function te(s,l){if(l<=6)return Array.from({length:l},(h,u)=>u+1);const n=[1,2,3],r=[l-1,l];return s<=4?[...n,"...",...r]:s>=l-3?[1,2,"...",l-2,l-1,l]:[1,"...",s-1,s,s+1,"...",l]}function le({currentPage:s,totalPages:l,onPageChange:n,previousLabel:r,nextLabel:h}){const u=te(s,l);return e.jsxs("div",{className:"data-table-pagination",children:[e.jsxs("button",{onClick:()=>n(Math.max(1,s-1)),disabled:s===1,className:"data-table-page-btn data-table-page-nav","aria-label":r,children:[e.jsx(ee.IconArrowLeft,{size:"16"}),r]}),e.jsx("div",{className:"data-table-page-numbers",children:u.map((o,f)=>o==="..."?e.jsx("span",{className:"data-table-page-ellipsis",children:"..."},`ellipsis-${f}`):e.jsx("button",{onClick:()=>n(o),className:`data-table-page-btn${o===s?" data-table-page-btn-active":""}`,children:o},o))}),e.jsxs("button",{onClick:()=>n(Math.min(l,s+1)),disabled:s===l,className:"data-table-page-btn data-table-page-nav","aria-label":h,children:[h,e.jsx(ae.IconArrowRight,{size:"16"})]})]})}function ne({action:s,item:l}){const n=s.isAllowed!==!1,r=e.jsx("button",{className:"data-table-row-action-btn","aria-label":s.label,disabled:!n,onClick:n?()=>s.onPress(l):void 0,children:s.icon});return n?r:e.jsx(K.PermissionGate,{isAllowed:!1,noAccessLabel:s.noAccessLabel??"",children:r})}function L({columns:s,data:l,actions:n,rowActions:r,rowActionsLabel:h="",searchPlaceholder:u="Search...",searchKeys:o=[],isLoading:f=!1,loadingMessage:M="Loading...",emptyMessage:$="No records found",previousLabel:A="Previous",nextLabel:D="Next",pageSize:j=10,nestedColumns:q,getNestedData:y,nestedLoadingMessage:P="Loading...",nestedEmptyMessage:B="No records found",nestedSearchKeys:E,nestedSearchPlaceholder:z,nestedActions:m,nestedPageSize:F}){const[w,G]=g.useState(""),[H,R]=g.useState(1),[O,Q]=g.useState(new Set),[k,N]=g.useState(new Map),I=!!y&&!!q,C=!!r;function _(a){const t=a.id;Q(c=>{const b=new Set(c);if(b.has(t))b.delete(t);else if(b.add(t),!k.has(t)){const d=y(a);d instanceof Promise?(N(x=>new Map(x).set(t,{status:"loading",data:[]})),d.then(x=>{N(W=>new Map(W).set(t,{status:"loaded",data:x}))})):N(x=>new Map(x).set(t,{status:"loaded",data:d}))}return b})}const p=o.length>0,J=p||!!n,v=g.useMemo(()=>{if(!w.trim()||!p)return l;const a=w.toLowerCase();return l.filter(t=>o.some(c=>String(t[c]??"").toLowerCase().includes(a)))},[l,w,o,p]),T=Math.max(1,Math.ceil(v.length/j)),S=Math.min(H,T),U=v.slice((S-1)*j,S*j);function V(a,t){return t.render?t.render(a):String(a[t.key]??"")}return e.jsxs(se.Flex,{direction:"column",gap:"300",className:"data-table",children:[J&&e.jsxs("div",{className:"data-table-toolbar",children:[p&&e.jsx(X.Search,{placeholder:u,onSearch:a=>{G(a),R(1)},className:"data-table-search"}),n&&e.jsx("div",{className:"data-table-actions",children:n})]}),f?e.jsx("div",{role:"status","aria-live":"polite","aria-label":M,className:"data-table-status",children:M}):v.length===0?e.jsx("div",{role:"status",className:"data-table-status data-table-empty",children:$}):e.jsxs(i.Table,{grid:!0,children:[e.jsxs(i.TableHead,{children:[I&&e.jsx(i.TableColumn,{className:"data-table-expand-col"}),s.map((a,t)=>e.jsx(i.TableColumn,{align:a.align,isRowHeader:t===0,children:a.label},String(a.key))),C&&e.jsx(i.TableColumn,{align:"right",className:"data-table-row-actions-col",children:h})]}),e.jsx(i.TableBody,{children:U.flatMap(a=>{const t=O.has(a.id),c=k.get(a.id),b=[e.jsxs(i.TableRow,{id:a.id,children:[I&&e.jsx(i.TableCell,{className:"data-table-expand-cell",children:e.jsx("button",{className:"data-table-expand-btn","aria-label":t?"Collapse row":"Expand row","aria-expanded":t,onClick:()=>_(a),children:t?e.jsx(Y.IconChevronDown,{size:"16"}):e.jsx(Z.IconChevronRight,{size:"16"})})}),s.map(d=>e.jsx(i.TableCell,{align:d.align,children:V(a,d)},String(d.key))),C&&e.jsx(i.TableCell,{align:"right",className:"data-table-row-actions-cell",children:e.jsx("div",{className:"data-table-row-actions",children:(typeof r=="function"?r(a):r).map(d=>e.jsx(ne,{action:d,item:a},d.key))})})]},a.id)];return t&&b.push(e.jsx(i.TableRow,{id:`${a.id}-nested`,className:"data-table-nested-row",children:e.jsx(i.TableCell,{colSpan:s.length+1+(C?1:0),className:"data-table-nested-cell",children:e.jsx(L,{columns:q,data:(c==null?void 0:c.data)??[],isLoading:!c||c.status==="loading",loadingMessage:P,emptyMessage:B,searchKeys:E,searchPlaceholder:z,actions:m==null?void 0:m(a),pageSize:F??j})})},`${a.id}-nested`)),b})})]}),T>1&&e.jsx(le,{currentPage:S,totalPages:T,onPageChange:R,previousLabel:A,nextLabel:D})]})}exports.DataTable=L;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),h=require("react");;/* empty css */const Z=require("../../primitives/Search/Search.cjs"),t=require("../../primitives/Table/Table.cjs"),_=require("../../icons/IconChevronDown.cjs"),A=require("../../icons/IconChevronRight.cjs"),K=require("../../primitives/Pagination/Pagination.cjs"),ee=require("../../primitives/PermissionGate/PermissionGate.cjs"),ae=require("../../layout/Flex/Flex.cjs");function se({action:n,item:c}){const o=n.isAllowed!==!1,d=e.jsx("button",{className:"data-table-row-action-btn","aria-label":n.label,disabled:!o,onClick:o?()=>n.onPress(c):void 0,children:n.icon});return o?d:e.jsx(ee.PermissionGate,{isAllowed:!1,noAccessLabel:n.noAccessLabel??"",children:d})}function M({columns:n,data:c,actions:o,rowActions:d,rowActionsLabel:R="",searchPlaceholder:L="Search...",searchKeys:g=[],isLoading:k=!1,loadingMessage:N="Loading...",emptyMessage:D="No records found",previousLabel:I="Previous",nextLabel:$="Next",pageSize:b=10,nestedColumns:T,getNestedData:S,nestedLoadingMessage:B="Loading...",nestedEmptyMessage:E="No records found",nestedSearchKeys:F,nestedSearchPlaceholder:G,nestedActions:j,nestedPageSize:H}){const[p,O]=h.useState(""),[Q,v]=h.useState(1),[z,J]=h.useState(new Set),[P,w]=h.useState(new Map),q=!!S&&!!T,f=!!d;function U(a){const s=a.id;J(r=>{const i=new Set(r);if(i.has(s))i.delete(s);else if(i.add(s),!P.has(s)){const l=S(a);l instanceof Promise?(w(u=>new Map(u).set(s,{status:"loading",data:[]})),l.then(u=>{w(Y=>new Map(Y).set(s,{status:"loaded",data:u}))})):w(u=>new Map(u).set(s,{status:"loaded",data:l}))}return i})}const x=g.length>0,V=x||!!o,m=h.useMemo(()=>{if(!p.trim()||!x)return c;const a=p.toLowerCase();return c.filter(s=>g.some(r=>String(s[r]??"").toLowerCase().includes(a)))},[c,p,g,x]),y=Math.max(1,Math.ceil(m.length/b)),C=Math.min(Q,y),W=m.slice((C-1)*b,C*b);function X(a,s){return s.render?s.render(a):String(a[s.key]??"")}return e.jsxs(ae.Flex,{direction:"column",gap:"300",className:"data-table",children:[V&&e.jsxs("div",{className:"data-table-toolbar",children:[x&&e.jsx(Z.Search,{placeholder:L,onSearch:a=>{O(a),v(1)},className:"data-table-search"}),o&&e.jsx("div",{className:"data-table-actions",children:o})]}),k?e.jsx("div",{role:"status","aria-live":"polite","aria-label":N,className:"data-table-status",children:N}):m.length===0?e.jsx("div",{role:"status",className:"data-table-status data-table-empty",children:D}):e.jsxs(t.Table,{grid:!0,children:[e.jsxs(t.TableHead,{children:[q&&e.jsx(t.TableColumn,{className:"data-table-expand-col"}),n.map((a,s)=>e.jsx(t.TableColumn,{align:a.align,isRowHeader:s===0,children:a.label},String(a.key))),f&&e.jsx(t.TableColumn,{align:"right",className:"data-table-row-actions-col",children:R})]}),e.jsx(t.TableBody,{children:W.flatMap(a=>{const s=z.has(a.id),r=P.get(a.id),i=[e.jsxs(t.TableRow,{id:a.id,children:[q&&e.jsx(t.TableCell,{className:"data-table-expand-cell",children:e.jsx("button",{className:"data-table-expand-btn","aria-label":s?"Collapse row":"Expand row","aria-expanded":s,onClick:()=>U(a),children:s?e.jsx(_.IconChevronDown,{size:"16"}):e.jsx(A.IconChevronRight,{size:"16"})})}),n.map(l=>e.jsx(t.TableCell,{align:l.align,children:X(a,l)},String(l.key))),f&&e.jsx(t.TableCell,{align:"right",className:"data-table-row-actions-cell",children:e.jsx("div",{className:"data-table-row-actions",children:(typeof d=="function"?d(a):d).map(l=>e.jsx(se,{action:l,item:a},l.key))})})]},a.id)];return s&&i.push(e.jsx(t.TableRow,{id:`${a.id}-nested`,className:"data-table-nested-row",children:e.jsx(t.TableCell,{colSpan:n.length+1+(f?1:0),className:"data-table-nested-cell",children:e.jsx(M,{columns:T,data:(r==null?void 0:r.data)??[],isLoading:!r||r.status==="loading",loadingMessage:B,emptyMessage:E,searchKeys:F,searchPlaceholder:G,actions:j==null?void 0:j(a),pageSize:H??b})})},`${a.id}-nested`)),i})})]}),e.jsx(K.Pagination,{page:C,totalPages:y,onPageChange:v,previousLabel:I,nextLabel:$})]})}exports.DataTable=M;
2
2
  //# sourceMappingURL=DataTable.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.cjs","sources":["../../../../../src/ui/components/DataTable/DataTable.tsx"],"sourcesContent":["import {\n PermissionGate,\n Search,\n Table,\n TableBody,\n TableCell,\n TableColumn,\n TableHead,\n TableRow,\n} from \"primitives\";\nimport { Flex } from \"layout\";\nimport { IconArrowLeft, IconArrowRight, IconChevronDown, IconChevronRight } from \"icons\";\nimport type { ReactNode } from \"react\";\nimport { useMemo, useState } from \"react\";\nimport \"./datatable.css\";\n\nfunction buildPages(current: number, total: number): (number | \"...\")[] {\n if (total <= 6) return Array.from({ length: total }, (_, i) => i + 1);\n const head = [1, 2, 3];\n const tail = [total - 1, total];\n if (current <= 4) return [...head, \"...\", ...tail];\n if (current >= total - 3) return [1, 2, \"...\", total - 2, total - 1, total];\n return [1, \"...\", current - 1, current, current + 1, \"...\", total];\n}\n\ninterface PaginationProps {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n previousLabel: string;\n nextLabel: string;\n}\n\nfunction Pagination({\n currentPage,\n totalPages,\n onPageChange,\n previousLabel,\n nextLabel,\n}: PaginationProps) {\n const pages = buildPages(currentPage, totalPages);\n return (\n <div className=\"data-table-pagination\">\n <button\n onClick={() => onPageChange(Math.max(1, currentPage - 1))}\n disabled={currentPage === 1}\n className=\"data-table-page-btn data-table-page-nav\"\n aria-label={previousLabel}\n >\n <IconArrowLeft size=\"16\" />\n {previousLabel}\n </button>\n <div className=\"data-table-page-numbers\">\n {pages.map((p, i) =>\n p === \"...\" ? (\n <span key={`ellipsis-${i}`} className=\"data-table-page-ellipsis\">\n ...\n </span>\n ) : (\n <button\n key={p}\n onClick={() => onPageChange(p as number)}\n className={`data-table-page-btn${p === currentPage ? \" data-table-page-btn-active\" : \"\"}`}\n >\n {p}\n </button>\n ),\n )}\n </div>\n <button\n onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}\n disabled={currentPage === totalPages}\n className=\"data-table-page-btn data-table-page-nav\"\n aria-label={nextLabel}\n >\n {nextLabel}\n <IconArrowRight size=\"16\" />\n </button>\n </div>\n );\n}\n\nexport interface Column<T> {\n key: keyof T | string;\n label: string;\n align?: \"start\" | \"center\" | \"right\";\n render?: (item: T) => ReactNode;\n}\n\nexport interface RowActionDef<T> {\n /** Unique key for this action. */\n key: string;\n /** aria-label for the button. */\n label: string;\n /** Icon element rendered inside the button. */\n icon: ReactNode;\n /** When false, button is disabled and a tooltip with `noAccessLabel` is shown. Default: true. */\n isAllowed?: boolean;\n /** Tooltip text shown when `isAllowed` is false. */\n noAccessLabel?: string;\n /** Called with the row item when the button is pressed. */\n onPress: (item: T) => void;\n}\n\nfunction RowActionButton<T>({\n action,\n item,\n}: {\n action: RowActionDef<T>;\n item: T;\n}) {\n const allowed = action.isAllowed !== false;\n const btn = (\n <button\n className=\"data-table-row-action-btn\"\n aria-label={action.label}\n disabled={!allowed}\n onClick={allowed ? () => action.onPress(item) : undefined}\n >\n {action.icon}\n </button>\n );\n if (allowed) return btn;\n return (\n <PermissionGate isAllowed={false} noAccessLabel={action.noAccessLabel ?? \"\"}>\n {btn}\n </PermissionGate>\n );\n}\n\ntype NestedStatus = { status: \"loading\"; data: never[] } | { status: \"loaded\"; data: any[] };\n\nexport interface DataTableProps<T extends { id: string }> {\n columns: Column<T>[];\n data: T[];\n actions?: ReactNode;\n /** Per-row action buttons rendered in a dedicated last column. */\n rowActions?: RowActionDef<T>[] | ((item: T) => RowActionDef<T>[]);\n /** Label for the row actions column header. Defaults to empty string. */\n rowActionsLabel?: string;\n searchPlaceholder?: string;\n searchKeys?: (keyof T)[];\n isLoading?: boolean;\n loadingMessage?: string;\n emptyMessage?: string;\n previousLabel?: string;\n nextLabel?: string;\n pageSize?: number;\n nestedColumns?: Column<any>[];\n getNestedData?: (item: T) => any[] | Promise<any[]>;\n nestedLoadingMessage?: string;\n nestedEmptyMessage?: string;\n nestedSearchKeys?: (keyof any)[];\n nestedSearchPlaceholder?: string;\n nestedActions?: (item: T) => ReactNode;\n nestedPageSize?: number;\n}\n\nexport function DataTable<T extends { id: string }>({\n columns,\n data,\n actions,\n rowActions,\n rowActionsLabel = \"\",\n searchPlaceholder = \"Search...\",\n searchKeys = [],\n isLoading = false,\n loadingMessage = \"Loading...\",\n emptyMessage = \"No records found\",\n previousLabel = \"Previous\",\n nextLabel = \"Next\",\n pageSize = 10,\n nestedColumns,\n getNestedData,\n nestedLoadingMessage = \"Loading...\",\n nestedEmptyMessage = \"No records found\",\n nestedSearchKeys,\n nestedSearchPlaceholder,\n nestedActions,\n nestedPageSize,\n}: DataTableProps<T>) {\n const [query, setQuery] = useState(\"\");\n const [page, setPage] = useState(1);\n const [expanded, setExpanded] = useState<Set<string>>(new Set());\n const [nestedCache, setNestedCache] = useState<Map<string, NestedStatus>>(new Map());\n\n const hasNested = !!getNestedData && !!nestedColumns;\n const hasRowActions = !!rowActions;\n\n function toggleRow(item: T) {\n const id = item.id;\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n if (!nestedCache.has(id)) {\n const result = getNestedData!(item);\n if (result instanceof Promise) {\n setNestedCache((c) => new Map(c).set(id, { status: \"loading\", data: [] }));\n result.then((rows) => {\n setNestedCache((c) => new Map(c).set(id, { status: \"loaded\", data: rows }));\n });\n } else {\n setNestedCache((c) => new Map(c).set(id, { status: \"loaded\", data: result }));\n }\n }\n }\n return next;\n });\n }\n\n const hasSearch = searchKeys.length > 0;\n const hasToolbar = hasSearch || !!actions;\n\n const filtered = useMemo(() => {\n if (!query.trim() || !hasSearch) return data;\n const lower = query.toLowerCase();\n return data.filter((item) =>\n searchKeys.some((k) =>\n String(item[k] ?? \"\")\n .toLowerCase()\n .includes(lower),\n ),\n );\n }, [data, query, searchKeys, hasSearch]);\n\n const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));\n const currentPage = Math.min(page, totalPages);\n const pageData = filtered.slice(\n (currentPage - 1) * pageSize,\n currentPage * pageSize,\n );\n\n function getCell(item: T, col: Column<T>): ReactNode {\n if (col.render) return col.render(item);\n return String((item as Record<string, unknown>)[col.key as string] ?? \"\");\n }\n\n return (\n <Flex direction=\"column\" gap=\"300\" className=\"data-table\">\n {hasToolbar && (\n <div className=\"data-table-toolbar\">\n {hasSearch && (\n <Search\n placeholder={searchPlaceholder}\n onSearch={(v) => {\n setQuery(v);\n setPage(1);\n }}\n className=\"data-table-search\"\n />\n )}\n {actions && <div className=\"data-table-actions\">{actions}</div>}\n </div>\n )}\n\n {isLoading ? (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label={loadingMessage}\n className=\"data-table-status\"\n >\n {loadingMessage}\n </div>\n ) : filtered.length === 0 ? (\n <div role=\"status\" className=\"data-table-status data-table-empty\">\n {emptyMessage}\n </div>\n ) : (\n <Table grid>\n <TableHead>\n {hasNested && <TableColumn className=\"data-table-expand-col\" />}\n {columns.map((col, idx) => (\n <TableColumn\n key={String(col.key)}\n align={col.align}\n isRowHeader={idx === 0}\n >\n {col.label}\n </TableColumn>\n ))}\n {hasRowActions && (\n <TableColumn align=\"right\" className=\"data-table-row-actions-col\">\n {rowActionsLabel}\n </TableColumn>\n )}\n </TableHead>\n <TableBody>\n {pageData.flatMap((item) => {\n const isExpanded = expanded.has(item.id);\n const cached = nestedCache.get(item.id);\n const rows: ReactNode[] = [\n <TableRow key={item.id} id={item.id}>\n {hasNested && (\n <TableCell className=\"data-table-expand-cell\">\n <button\n className=\"data-table-expand-btn\"\n aria-label={isExpanded ? \"Collapse row\" : \"Expand row\"}\n aria-expanded={isExpanded}\n onClick={() => toggleRow(item)}\n >\n {isExpanded ? (\n <IconChevronDown size=\"16\" />\n ) : (\n <IconChevronRight size=\"16\" />\n )}\n </button>\n </TableCell>\n )}\n {columns.map((col) => (\n <TableCell key={String(col.key)} align={col.align}>\n {getCell(item, col)}\n </TableCell>\n ))}\n {hasRowActions && (\n <TableCell align=\"right\" className=\"data-table-row-actions-cell\">\n <div className=\"data-table-row-actions\">\n {(typeof rowActions === \"function\"\n ? rowActions(item)\n : rowActions!\n ).map((action) => (\n <RowActionButton key={action.key} action={action} item={item} />\n ))}\n </div>\n </TableCell>\n )}\n </TableRow>,\n ];\n if (isExpanded) {\n rows.push(\n <TableRow key={`${item.id}-nested`} id={`${item.id}-nested`} className=\"data-table-nested-row\">\n <TableCell\n colSpan={columns.length + 1 + (hasRowActions ? 1 : 0)}\n className=\"data-table-nested-cell\"\n >\n <DataTable\n columns={nestedColumns!}\n data={cached?.data ?? []}\n isLoading={!cached || cached.status === \"loading\"}\n loadingMessage={nestedLoadingMessage}\n emptyMessage={nestedEmptyMessage}\n searchKeys={nestedSearchKeys}\n searchPlaceholder={nestedSearchPlaceholder}\n actions={nestedActions?.(item)}\n pageSize={nestedPageSize ?? pageSize}\n />\n </TableCell>\n </TableRow>,\n );\n }\n return rows;\n })}\n </TableBody>\n </Table>\n )}\n\n {totalPages > 1 && (\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n onPageChange={setPage}\n previousLabel={previousLabel}\n nextLabel={nextLabel}\n />\n )}\n </Flex>\n );\n}\n"],"names":["buildPages","current","total","_","i","head","tail","Pagination","currentPage","totalPages","onPageChange","previousLabel","nextLabel","pages","jsxs","jsx","IconArrowLeft","p","IconArrowRight","RowActionButton","action","item","allowed","btn","PermissionGate","DataTable","columns","data","actions","rowActions","rowActionsLabel","searchPlaceholder","searchKeys","isLoading","loadingMessage","emptyMessage","pageSize","nestedColumns","getNestedData","nestedLoadingMessage","nestedEmptyMessage","nestedSearchKeys","nestedSearchPlaceholder","nestedActions","nestedPageSize","query","setQuery","useState","page","setPage","expanded","setExpanded","nestedCache","setNestedCache","hasNested","hasRowActions","toggleRow","id","prev","next","result","c","rows","hasSearch","hasToolbar","filtered","useMemo","lower","k","pageData","getCell","col","Flex","Search","v","Table","TableHead","TableColumn","idx","TableBody","isExpanded","cached","TableRow","TableCell","IconChevronDown","IconChevronRight"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable.cjs","sources":["../../../../../src/ui/components/DataTable/DataTable.tsx"],"sourcesContent":["import {\n Pagination,\n PermissionGate,\n Search,\n Table,\n TableBody,\n TableCell,\n TableColumn,\n TableHead,\n TableRow,\n} from \"primitives\";\nimport { Flex } from \"layout\";\nimport { IconChevronDown, IconChevronRight } from \"icons\";\nimport type { ReactNode } from \"react\";\nimport { useMemo, useState } from \"react\";\nimport \"./datatable.css\";\n\nexport interface Column<T> {\n key: keyof T | string;\n label: string;\n align?: \"start\" | \"center\" | \"right\";\n render?: (item: T) => ReactNode;\n}\n\nexport interface RowActionDef<T> {\n /** Unique key for this action. */\n key: string;\n /** aria-label for the button. */\n label: string;\n /** Icon element rendered inside the button. */\n icon: ReactNode;\n /** When false, button is disabled and a tooltip with `noAccessLabel` is shown. Default: true. */\n isAllowed?: boolean;\n /** Tooltip text shown when `isAllowed` is false. */\n noAccessLabel?: string;\n /** Called with the row item when the button is pressed. */\n onPress: (item: T) => void;\n}\n\nfunction RowActionButton<T>({\n action,\n item,\n}: {\n action: RowActionDef<T>;\n item: T;\n}) {\n const allowed = action.isAllowed !== false;\n const btn = (\n <button\n className=\"data-table-row-action-btn\"\n aria-label={action.label}\n disabled={!allowed}\n onClick={allowed ? () => action.onPress(item) : undefined}\n >\n {action.icon}\n </button>\n );\n if (allowed) return btn;\n return (\n <PermissionGate isAllowed={false} noAccessLabel={action.noAccessLabel ?? \"\"}>\n {btn}\n </PermissionGate>\n );\n}\n\ntype NestedStatus = { status: \"loading\"; data: never[] } | { status: \"loaded\"; data: any[] };\n\nexport interface DataTableProps<T extends { id: string }> {\n columns: Column<T>[];\n data: T[];\n actions?: ReactNode;\n /** Per-row action buttons rendered in a dedicated last column. */\n rowActions?: RowActionDef<T>[] | ((item: T) => RowActionDef<T>[]);\n /** Label for the row actions column header. Defaults to empty string. */\n rowActionsLabel?: string;\n searchPlaceholder?: string;\n searchKeys?: (keyof T)[];\n isLoading?: boolean;\n loadingMessage?: string;\n emptyMessage?: string;\n previousLabel?: string;\n nextLabel?: string;\n pageSize?: number;\n nestedColumns?: Column<any>[];\n getNestedData?: (item: T) => any[] | Promise<any[]>;\n nestedLoadingMessage?: string;\n nestedEmptyMessage?: string;\n nestedSearchKeys?: (keyof any)[];\n nestedSearchPlaceholder?: string;\n nestedActions?: (item: T) => ReactNode;\n nestedPageSize?: number;\n}\n\nexport function DataTable<T extends { id: string }>({\n columns,\n data,\n actions,\n rowActions,\n rowActionsLabel = \"\",\n searchPlaceholder = \"Search...\",\n searchKeys = [],\n isLoading = false,\n loadingMessage = \"Loading...\",\n emptyMessage = \"No records found\",\n previousLabel = \"Previous\",\n nextLabel = \"Next\",\n pageSize = 10,\n nestedColumns,\n getNestedData,\n nestedLoadingMessage = \"Loading...\",\n nestedEmptyMessage = \"No records found\",\n nestedSearchKeys,\n nestedSearchPlaceholder,\n nestedActions,\n nestedPageSize,\n}: DataTableProps<T>) {\n const [query, setQuery] = useState(\"\");\n const [page, setPage] = useState(1);\n const [expanded, setExpanded] = useState<Set<string>>(new Set());\n const [nestedCache, setNestedCache] = useState<Map<string, NestedStatus>>(new Map());\n\n const hasNested = !!getNestedData && !!nestedColumns;\n const hasRowActions = !!rowActions;\n\n function toggleRow(item: T) {\n const id = item.id;\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n if (!nestedCache.has(id)) {\n const result = getNestedData!(item);\n if (result instanceof Promise) {\n setNestedCache((c) => new Map(c).set(id, { status: \"loading\", data: [] }));\n result.then((rows) => {\n setNestedCache((c) => new Map(c).set(id, { status: \"loaded\", data: rows }));\n });\n } else {\n setNestedCache((c) => new Map(c).set(id, { status: \"loaded\", data: result }));\n }\n }\n }\n return next;\n });\n }\n\n const hasSearch = searchKeys.length > 0;\n const hasToolbar = hasSearch || !!actions;\n\n const filtered = useMemo(() => {\n if (!query.trim() || !hasSearch) return data;\n const lower = query.toLowerCase();\n return data.filter((item) =>\n searchKeys.some((k) =>\n String(item[k] ?? \"\")\n .toLowerCase()\n .includes(lower),\n ),\n );\n }, [data, query, searchKeys, hasSearch]);\n\n const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));\n const currentPage = Math.min(page, totalPages);\n const pageData = filtered.slice(\n (currentPage - 1) * pageSize,\n currentPage * pageSize,\n );\n\n function getCell(item: T, col: Column<T>): ReactNode {\n if (col.render) return col.render(item);\n return String((item as Record<string, unknown>)[col.key as string] ?? \"\");\n }\n\n return (\n <Flex direction=\"column\" gap=\"300\" className=\"data-table\">\n {hasToolbar && (\n <div className=\"data-table-toolbar\">\n {hasSearch && (\n <Search\n placeholder={searchPlaceholder}\n onSearch={(v) => {\n setQuery(v);\n setPage(1);\n }}\n className=\"data-table-search\"\n />\n )}\n {actions && <div className=\"data-table-actions\">{actions}</div>}\n </div>\n )}\n\n {isLoading ? (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label={loadingMessage}\n className=\"data-table-status\"\n >\n {loadingMessage}\n </div>\n ) : filtered.length === 0 ? (\n <div role=\"status\" className=\"data-table-status data-table-empty\">\n {emptyMessage}\n </div>\n ) : (\n <Table grid>\n <TableHead>\n {hasNested && <TableColumn className=\"data-table-expand-col\" />}\n {columns.map((col, idx) => (\n <TableColumn\n key={String(col.key)}\n align={col.align}\n isRowHeader={idx === 0}\n >\n {col.label}\n </TableColumn>\n ))}\n {hasRowActions && (\n <TableColumn align=\"right\" className=\"data-table-row-actions-col\">\n {rowActionsLabel}\n </TableColumn>\n )}\n </TableHead>\n <TableBody>\n {pageData.flatMap((item) => {\n const isExpanded = expanded.has(item.id);\n const cached = nestedCache.get(item.id);\n const rows: ReactNode[] = [\n <TableRow key={item.id} id={item.id}>\n {hasNested && (\n <TableCell className=\"data-table-expand-cell\">\n <button\n className=\"data-table-expand-btn\"\n aria-label={isExpanded ? \"Collapse row\" : \"Expand row\"}\n aria-expanded={isExpanded}\n onClick={() => toggleRow(item)}\n >\n {isExpanded ? (\n <IconChevronDown size=\"16\" />\n ) : (\n <IconChevronRight size=\"16\" />\n )}\n </button>\n </TableCell>\n )}\n {columns.map((col) => (\n <TableCell key={String(col.key)} align={col.align}>\n {getCell(item, col)}\n </TableCell>\n ))}\n {hasRowActions && (\n <TableCell align=\"right\" className=\"data-table-row-actions-cell\">\n <div className=\"data-table-row-actions\">\n {(typeof rowActions === \"function\"\n ? rowActions(item)\n : rowActions!\n ).map((action) => (\n <RowActionButton key={action.key} action={action} item={item} />\n ))}\n </div>\n </TableCell>\n )}\n </TableRow>,\n ];\n if (isExpanded) {\n rows.push(\n <TableRow key={`${item.id}-nested`} id={`${item.id}-nested`} className=\"data-table-nested-row\">\n <TableCell\n colSpan={columns.length + 1 + (hasRowActions ? 1 : 0)}\n className=\"data-table-nested-cell\"\n >\n <DataTable\n columns={nestedColumns!}\n data={cached?.data ?? []}\n isLoading={!cached || cached.status === \"loading\"}\n loadingMessage={nestedLoadingMessage}\n emptyMessage={nestedEmptyMessage}\n searchKeys={nestedSearchKeys}\n searchPlaceholder={nestedSearchPlaceholder}\n actions={nestedActions?.(item)}\n pageSize={nestedPageSize ?? pageSize}\n />\n </TableCell>\n </TableRow>,\n );\n }\n return rows;\n })}\n </TableBody>\n </Table>\n )}\n\n <Pagination\n page={currentPage}\n totalPages={totalPages}\n onPageChange={setPage}\n previousLabel={previousLabel}\n nextLabel={nextLabel}\n />\n </Flex>\n );\n}\n"],"names":["RowActionButton","action","item","allowed","btn","jsx","PermissionGate","DataTable","columns","data","actions","rowActions","rowActionsLabel","searchPlaceholder","searchKeys","isLoading","loadingMessage","emptyMessage","previousLabel","nextLabel","pageSize","nestedColumns","getNestedData","nestedLoadingMessage","nestedEmptyMessage","nestedSearchKeys","nestedSearchPlaceholder","nestedActions","nestedPageSize","query","setQuery","useState","page","setPage","expanded","setExpanded","nestedCache","setNestedCache","hasNested","hasRowActions","toggleRow","id","prev","next","result","c","rows","hasSearch","hasToolbar","filtered","useMemo","lower","k","totalPages","currentPage","pageData","getCell","col","Flex","jsxs","Search","v","Table","TableHead","TableColumn","idx","TableBody","isExpanded","cached","TableRow","TableCell","IconChevronDown","IconChevronRight","Pagination"],"mappings":"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"}
@@ -1,229 +1,175 @@
1
- import { jsxs as c, jsx as a } from "react/jsx-runtime";
2
- import { useState as g, useMemo as Z } from "react";
1
+ import { jsxs as h, jsx as e } from "react/jsx-runtime";
2
+ import { useState as u, useMemo as A } from "react";
3
3
  /* empty css */
4
4
  import { Search as K } from "../../primitives/Search/Search.js";
5
- import { Table as aa, TableHead as ea, TableColumn as T, TableBody as ta, TableRow as z, TableCell as w } from "../../primitives/Table/Table.js";
5
+ import { Table as aa, TableHead as ea, TableColumn as M, TableBody as ta, TableRow as E, TableCell as g } from "../../primitives/Table/Table.js";
6
6
  import { IconChevronDown as la } from "../../icons/IconChevronDown.js";
7
7
  import { IconChevronRight as na } from "../../icons/IconChevronRight.js";
8
- import { PermissionGate as sa } from "../../primitives/PermissionGate/PermissionGate.js";
9
- import { IconArrowLeft as ia } from "../../icons/IconArrowLeft.js";
10
- import { IconArrowRight as ra } from "../../icons/IconArrowRight.js";
11
- import { Flex as da } from "../../layout/Flex/Flex.js";
12
- function oa(t, n) {
13
- if (n <= 6) return Array.from({ length: n }, (b, m) => m + 1);
14
- const s = [1, 2, 3], i = [n - 1, n];
15
- return t <= 4 ? [...s, "...", ...i] : t >= n - 3 ? [1, 2, "...", n - 2, n - 1, n] : [1, "...", t - 1, t, t + 1, "...", n];
16
- }
17
- function ca({
18
- currentPage: t,
19
- totalPages: n,
20
- onPageChange: s,
21
- previousLabel: i,
22
- nextLabel: b
23
- }) {
24
- const m = oa(t, n);
25
- return /* @__PURE__ */ c("div", { className: "data-table-pagination", children: [
26
- /* @__PURE__ */ c(
27
- "button",
28
- {
29
- onClick: () => s(Math.max(1, t - 1)),
30
- disabled: t === 1,
31
- className: "data-table-page-btn data-table-page-nav",
32
- "aria-label": i,
33
- children: [
34
- /* @__PURE__ */ a(ia, { size: "16" }),
35
- i
36
- ]
37
- }
38
- ),
39
- /* @__PURE__ */ a("div", { className: "data-table-page-numbers", children: m.map(
40
- (d, N) => d === "..." ? /* @__PURE__ */ a("span", { className: "data-table-page-ellipsis", children: "..." }, `ellipsis-${N}`) : /* @__PURE__ */ a(
41
- "button",
42
- {
43
- onClick: () => s(d),
44
- className: `data-table-page-btn${d === t ? " data-table-page-btn-active" : ""}`,
45
- children: d
46
- },
47
- d
48
- )
49
- ) }),
50
- /* @__PURE__ */ c(
51
- "button",
52
- {
53
- onClick: () => s(Math.min(n, t + 1)),
54
- disabled: t === n,
55
- className: "data-table-page-btn data-table-page-nav",
56
- "aria-label": b,
57
- children: [
58
- b,
59
- /* @__PURE__ */ a(ra, { size: "16" })
60
- ]
61
- }
62
- )
63
- ] });
64
- }
65
- function ha({
66
- action: t,
67
- item: n
8
+ import { Pagination as sa } from "../../primitives/Pagination/Pagination.js";
9
+ import { PermissionGate as ra } from "../../primitives/PermissionGate/PermissionGate.js";
10
+ import { Flex as oa } from "../../layout/Flex/Flex.js";
11
+ function da({
12
+ action: n,
13
+ item: i
68
14
  }) {
69
- const s = t.isAllowed !== !1, i = /* @__PURE__ */ a(
15
+ const r = n.isAllowed !== !1, o = /* @__PURE__ */ e(
70
16
  "button",
71
17
  {
72
18
  className: "data-table-row-action-btn",
73
- "aria-label": t.label,
74
- disabled: !s,
75
- onClick: s ? () => t.onPress(n) : void 0,
76
- children: t.icon
19
+ "aria-label": n.label,
20
+ disabled: !r,
21
+ onClick: r ? () => n.onPress(i) : void 0,
22
+ children: n.icon
77
23
  }
78
24
  );
79
- return s ? i : /* @__PURE__ */ a(sa, { isAllowed: !1, noAccessLabel: t.noAccessLabel ?? "", children: i });
25
+ return r ? o : /* @__PURE__ */ e(ra, { isAllowed: !1, noAccessLabel: n.noAccessLabel ?? "", children: o });
80
26
  }
81
- function ba({
82
- columns: t,
83
- data: n,
84
- actions: s,
85
- rowActions: i,
86
- rowActionsLabel: b = "",
87
- searchPlaceholder: m = "Search...",
88
- searchKeys: d = [],
89
- isLoading: N = !1,
90
- loadingMessage: R = "Loading...",
91
- emptyMessage: A = "No records found",
92
- previousLabel: B = "Previous",
93
- nextLabel: D = "Next",
94
- pageSize: f = 10,
95
- nestedColumns: L,
96
- getNestedData: I,
97
- nestedLoadingMessage: H = "Loading...",
98
- nestedEmptyMessage: P = "No records found",
99
- nestedSearchKeys: q,
100
- nestedSearchPlaceholder: F,
101
- nestedActions: x,
102
- nestedPageSize: G
27
+ function ia({
28
+ columns: n,
29
+ data: i,
30
+ actions: r,
31
+ rowActions: o,
32
+ rowActionsLabel: j = "",
33
+ searchPlaceholder: B = "Search...",
34
+ searchKeys: m = [],
35
+ isLoading: D = !1,
36
+ loadingMessage: P = "Loading...",
37
+ emptyMessage: H = "No records found",
38
+ previousLabel: I = "Previous",
39
+ nextLabel: $ = "Next",
40
+ pageSize: b = 10,
41
+ nestedColumns: S,
42
+ getNestedData: y,
43
+ nestedLoadingMessage: q = "Loading...",
44
+ nestedEmptyMessage: F = "No records found",
45
+ nestedSearchKeys: G,
46
+ nestedSearchPlaceholder: Q,
47
+ nestedActions: f,
48
+ nestedPageSize: z
103
49
  }) {
104
- const [v, Q] = g(""), [_, $] = g(1), [J, O] = g(/* @__PURE__ */ new Set()), [E, C] = g(/* @__PURE__ */ new Map()), j = !!I && !!L, M = !!i;
105
- function U(e) {
106
- const l = e.id;
107
- O((o) => {
108
- const h = new Set(o);
109
- if (h.has(l))
110
- h.delete(l);
111
- else if (h.add(l), !E.has(l)) {
112
- const r = I(e);
113
- r instanceof Promise ? (C((p) => new Map(p).set(l, { status: "loading", data: [] })), r.then((p) => {
114
- C((Y) => new Map(Y).set(l, { status: "loaded", data: p }));
115
- })) : C((p) => new Map(p).set(l, { status: "loaded", data: r }));
50
+ const [w, J] = u(""), [O, T] = u(1), [U, V] = u(/* @__PURE__ */ new Set()), [L, N] = u(/* @__PURE__ */ new Map()), k = !!y && !!S, x = !!o;
51
+ function W(a) {
52
+ const t = a.id;
53
+ V((s) => {
54
+ const d = new Set(s);
55
+ if (d.has(t))
56
+ d.delete(t);
57
+ else if (d.add(t), !L.has(t)) {
58
+ const l = y(a);
59
+ l instanceof Promise ? (N((c) => new Map(c).set(t, { status: "loading", data: [] })), l.then((c) => {
60
+ N((_) => new Map(_).set(t, { status: "loaded", data: c }));
61
+ })) : N((c) => new Map(c).set(t, { status: "loaded", data: l }));
116
62
  }
117
- return h;
63
+ return d;
118
64
  });
119
65
  }
120
- const u = d.length > 0, V = u || !!s, y = Z(() => {
121
- if (!v.trim() || !u) return n;
122
- const e = v.toLowerCase();
123
- return n.filter(
124
- (l) => d.some(
125
- (o) => String(l[o] ?? "").toLowerCase().includes(e)
66
+ const p = m.length > 0, X = p || !!r, C = A(() => {
67
+ if (!w.trim() || !p) return i;
68
+ const a = w.toLowerCase();
69
+ return i.filter(
70
+ (t) => m.some(
71
+ (s) => String(t[s] ?? "").toLowerCase().includes(a)
126
72
  )
127
73
  );
128
- }, [n, v, d, u]), S = Math.max(1, Math.ceil(y.length / f)), k = Math.min(_, S), W = y.slice(
129
- (k - 1) * f,
130
- k * f
74
+ }, [i, w, m, p]), R = Math.max(1, Math.ceil(C.length / b)), v = Math.min(O, R), Y = C.slice(
75
+ (v - 1) * b,
76
+ v * b
131
77
  );
132
- function X(e, l) {
133
- return l.render ? l.render(e) : String(e[l.key] ?? "");
78
+ function Z(a, t) {
79
+ return t.render ? t.render(a) : String(a[t.key] ?? "");
134
80
  }
135
- return /* @__PURE__ */ c(da, { direction: "column", gap: "300", className: "data-table", children: [
136
- V && /* @__PURE__ */ c("div", { className: "data-table-toolbar", children: [
137
- u && /* @__PURE__ */ a(
81
+ return /* @__PURE__ */ h(oa, { direction: "column", gap: "300", className: "data-table", children: [
82
+ X && /* @__PURE__ */ h("div", { className: "data-table-toolbar", children: [
83
+ p && /* @__PURE__ */ e(
138
84
  K,
139
85
  {
140
- placeholder: m,
141
- onSearch: (e) => {
142
- Q(e), $(1);
86
+ placeholder: B,
87
+ onSearch: (a) => {
88
+ J(a), T(1);
143
89
  },
144
90
  className: "data-table-search"
145
91
  }
146
92
  ),
147
- s && /* @__PURE__ */ a("div", { className: "data-table-actions", children: s })
93
+ r && /* @__PURE__ */ e("div", { className: "data-table-actions", children: r })
148
94
  ] }),
149
- N ? /* @__PURE__ */ a(
95
+ D ? /* @__PURE__ */ e(
150
96
  "div",
151
97
  {
152
98
  role: "status",
153
99
  "aria-live": "polite",
154
- "aria-label": R,
100
+ "aria-label": P,
155
101
  className: "data-table-status",
156
- children: R
102
+ children: P
157
103
  }
158
- ) : y.length === 0 ? /* @__PURE__ */ a("div", { role: "status", className: "data-table-status data-table-empty", children: A }) : /* @__PURE__ */ c(aa, { grid: !0, children: [
159
- /* @__PURE__ */ c(ea, { children: [
160
- j && /* @__PURE__ */ a(T, { className: "data-table-expand-col" }),
161
- t.map((e, l) => /* @__PURE__ */ a(
162
- T,
104
+ ) : C.length === 0 ? /* @__PURE__ */ e("div", { role: "status", className: "data-table-status data-table-empty", children: H }) : /* @__PURE__ */ h(aa, { grid: !0, children: [
105
+ /* @__PURE__ */ h(ea, { children: [
106
+ k && /* @__PURE__ */ e(M, { className: "data-table-expand-col" }),
107
+ n.map((a, t) => /* @__PURE__ */ e(
108
+ M,
163
109
  {
164
- align: e.align,
165
- isRowHeader: l === 0,
166
- children: e.label
110
+ align: a.align,
111
+ isRowHeader: t === 0,
112
+ children: a.label
167
113
  },
168
- String(e.key)
114
+ String(a.key)
169
115
  )),
170
- M && /* @__PURE__ */ a(T, { align: "right", className: "data-table-row-actions-col", children: b })
116
+ x && /* @__PURE__ */ e(M, { align: "right", className: "data-table-row-actions-col", children: j })
171
117
  ] }),
172
- /* @__PURE__ */ a(ta, { children: W.flatMap((e) => {
173
- const l = J.has(e.id), o = E.get(e.id), h = [
174
- /* @__PURE__ */ c(z, { id: e.id, children: [
175
- j && /* @__PURE__ */ a(w, { className: "data-table-expand-cell", children: /* @__PURE__ */ a(
118
+ /* @__PURE__ */ e(ta, { children: Y.flatMap((a) => {
119
+ const t = U.has(a.id), s = L.get(a.id), d = [
120
+ /* @__PURE__ */ h(E, { id: a.id, children: [
121
+ k && /* @__PURE__ */ e(g, { className: "data-table-expand-cell", children: /* @__PURE__ */ e(
176
122
  "button",
177
123
  {
178
124
  className: "data-table-expand-btn",
179
- "aria-label": l ? "Collapse row" : "Expand row",
180
- "aria-expanded": l,
181
- onClick: () => U(e),
182
- children: l ? /* @__PURE__ */ a(la, { size: "16" }) : /* @__PURE__ */ a(na, { size: "16" })
125
+ "aria-label": t ? "Collapse row" : "Expand row",
126
+ "aria-expanded": t,
127
+ onClick: () => W(a),
128
+ children: t ? /* @__PURE__ */ e(la, { size: "16" }) : /* @__PURE__ */ e(na, { size: "16" })
183
129
  }
184
130
  ) }),
185
- t.map((r) => /* @__PURE__ */ a(w, { align: r.align, children: X(e, r) }, String(r.key))),
186
- M && /* @__PURE__ */ a(w, { align: "right", className: "data-table-row-actions-cell", children: /* @__PURE__ */ a("div", { className: "data-table-row-actions", children: (typeof i == "function" ? i(e) : i).map((r) => /* @__PURE__ */ a(ha, { action: r, item: e }, r.key)) }) })
187
- ] }, e.id)
131
+ n.map((l) => /* @__PURE__ */ e(g, { align: l.align, children: Z(a, l) }, String(l.key))),
132
+ x && /* @__PURE__ */ e(g, { align: "right", className: "data-table-row-actions-cell", children: /* @__PURE__ */ e("div", { className: "data-table-row-actions", children: (typeof o == "function" ? o(a) : o).map((l) => /* @__PURE__ */ e(da, { action: l, item: a }, l.key)) }) })
133
+ ] }, a.id)
188
134
  ];
189
- return l && h.push(
190
- /* @__PURE__ */ a(z, { id: `${e.id}-nested`, className: "data-table-nested-row", children: /* @__PURE__ */ a(
191
- w,
135
+ return t && d.push(
136
+ /* @__PURE__ */ e(E, { id: `${a.id}-nested`, className: "data-table-nested-row", children: /* @__PURE__ */ e(
137
+ g,
192
138
  {
193
- colSpan: t.length + 1 + (M ? 1 : 0),
139
+ colSpan: n.length + 1 + (x ? 1 : 0),
194
140
  className: "data-table-nested-cell",
195
- children: /* @__PURE__ */ a(
196
- ba,
141
+ children: /* @__PURE__ */ e(
142
+ ia,
197
143
  {
198
- columns: L,
199
- data: (o == null ? void 0 : o.data) ?? [],
200
- isLoading: !o || o.status === "loading",
201
- loadingMessage: H,
202
- emptyMessage: P,
203
- searchKeys: q,
204
- searchPlaceholder: F,
205
- actions: x == null ? void 0 : x(e),
206
- pageSize: G ?? f
144
+ columns: S,
145
+ data: (s == null ? void 0 : s.data) ?? [],
146
+ isLoading: !s || s.status === "loading",
147
+ loadingMessage: q,
148
+ emptyMessage: F,
149
+ searchKeys: G,
150
+ searchPlaceholder: Q,
151
+ actions: f == null ? void 0 : f(a),
152
+ pageSize: z ?? b
207
153
  }
208
154
  )
209
155
  }
210
- ) }, `${e.id}-nested`)
211
- ), h;
156
+ ) }, `${a.id}-nested`)
157
+ ), d;
212
158
  }) })
213
159
  ] }),
214
- S > 1 && /* @__PURE__ */ a(
215
- ca,
160
+ /* @__PURE__ */ e(
161
+ sa,
216
162
  {
217
- currentPage: k,
218
- totalPages: S,
219
- onPageChange: $,
220
- previousLabel: B,
221
- nextLabel: D
163
+ page: v,
164
+ totalPages: R,
165
+ onPageChange: T,
166
+ previousLabel: I,
167
+ nextLabel: $
222
168
  }
223
169
  )
224
170
  ] });
225
171
  }
226
172
  export {
227
- ba as DataTable
173
+ ia as DataTable
228
174
  };
229
175
  //# sourceMappingURL=DataTable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.js","sources":["../../../../../src/ui/components/DataTable/DataTable.tsx"],"sourcesContent":["import {\n PermissionGate,\n Search,\n Table,\n TableBody,\n TableCell,\n TableColumn,\n TableHead,\n TableRow,\n} from \"primitives\";\nimport { Flex } from \"layout\";\nimport { IconArrowLeft, IconArrowRight, IconChevronDown, IconChevronRight } from \"icons\";\nimport type { ReactNode } from \"react\";\nimport { useMemo, useState } from \"react\";\nimport \"./datatable.css\";\n\nfunction buildPages(current: number, total: number): (number | \"...\")[] {\n if (total <= 6) return Array.from({ length: total }, (_, i) => i + 1);\n const head = [1, 2, 3];\n const tail = [total - 1, total];\n if (current <= 4) return [...head, \"...\", ...tail];\n if (current >= total - 3) return [1, 2, \"...\", total - 2, total - 1, total];\n return [1, \"...\", current - 1, current, current + 1, \"...\", total];\n}\n\ninterface PaginationProps {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n previousLabel: string;\n nextLabel: string;\n}\n\nfunction Pagination({\n currentPage,\n totalPages,\n onPageChange,\n previousLabel,\n nextLabel,\n}: PaginationProps) {\n const pages = buildPages(currentPage, totalPages);\n return (\n <div className=\"data-table-pagination\">\n <button\n onClick={() => onPageChange(Math.max(1, currentPage - 1))}\n disabled={currentPage === 1}\n className=\"data-table-page-btn data-table-page-nav\"\n aria-label={previousLabel}\n >\n <IconArrowLeft size=\"16\" />\n {previousLabel}\n </button>\n <div className=\"data-table-page-numbers\">\n {pages.map((p, i) =>\n p === \"...\" ? (\n <span key={`ellipsis-${i}`} className=\"data-table-page-ellipsis\">\n ...\n </span>\n ) : (\n <button\n key={p}\n onClick={() => onPageChange(p as number)}\n className={`data-table-page-btn${p === currentPage ? \" data-table-page-btn-active\" : \"\"}`}\n >\n {p}\n </button>\n ),\n )}\n </div>\n <button\n onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}\n disabled={currentPage === totalPages}\n className=\"data-table-page-btn data-table-page-nav\"\n aria-label={nextLabel}\n >\n {nextLabel}\n <IconArrowRight size=\"16\" />\n </button>\n </div>\n );\n}\n\nexport interface Column<T> {\n key: keyof T | string;\n label: string;\n align?: \"start\" | \"center\" | \"right\";\n render?: (item: T) => ReactNode;\n}\n\nexport interface RowActionDef<T> {\n /** Unique key for this action. */\n key: string;\n /** aria-label for the button. */\n label: string;\n /** Icon element rendered inside the button. */\n icon: ReactNode;\n /** When false, button is disabled and a tooltip with `noAccessLabel` is shown. Default: true. */\n isAllowed?: boolean;\n /** Tooltip text shown when `isAllowed` is false. */\n noAccessLabel?: string;\n /** Called with the row item when the button is pressed. */\n onPress: (item: T) => void;\n}\n\nfunction RowActionButton<T>({\n action,\n item,\n}: {\n action: RowActionDef<T>;\n item: T;\n}) {\n const allowed = action.isAllowed !== false;\n const btn = (\n <button\n className=\"data-table-row-action-btn\"\n aria-label={action.label}\n disabled={!allowed}\n onClick={allowed ? () => action.onPress(item) : undefined}\n >\n {action.icon}\n </button>\n );\n if (allowed) return btn;\n return (\n <PermissionGate isAllowed={false} noAccessLabel={action.noAccessLabel ?? \"\"}>\n {btn}\n </PermissionGate>\n );\n}\n\ntype NestedStatus = { status: \"loading\"; data: never[] } | { status: \"loaded\"; data: any[] };\n\nexport interface DataTableProps<T extends { id: string }> {\n columns: Column<T>[];\n data: T[];\n actions?: ReactNode;\n /** Per-row action buttons rendered in a dedicated last column. */\n rowActions?: RowActionDef<T>[] | ((item: T) => RowActionDef<T>[]);\n /** Label for the row actions column header. Defaults to empty string. */\n rowActionsLabel?: string;\n searchPlaceholder?: string;\n searchKeys?: (keyof T)[];\n isLoading?: boolean;\n loadingMessage?: string;\n emptyMessage?: string;\n previousLabel?: string;\n nextLabel?: string;\n pageSize?: number;\n nestedColumns?: Column<any>[];\n getNestedData?: (item: T) => any[] | Promise<any[]>;\n nestedLoadingMessage?: string;\n nestedEmptyMessage?: string;\n nestedSearchKeys?: (keyof any)[];\n nestedSearchPlaceholder?: string;\n nestedActions?: (item: T) => ReactNode;\n nestedPageSize?: number;\n}\n\nexport function DataTable<T extends { id: string }>({\n columns,\n data,\n actions,\n rowActions,\n rowActionsLabel = \"\",\n searchPlaceholder = \"Search...\",\n searchKeys = [],\n isLoading = false,\n loadingMessage = \"Loading...\",\n emptyMessage = \"No records found\",\n previousLabel = \"Previous\",\n nextLabel = \"Next\",\n pageSize = 10,\n nestedColumns,\n getNestedData,\n nestedLoadingMessage = \"Loading...\",\n nestedEmptyMessage = \"No records found\",\n nestedSearchKeys,\n nestedSearchPlaceholder,\n nestedActions,\n nestedPageSize,\n}: DataTableProps<T>) {\n const [query, setQuery] = useState(\"\");\n const [page, setPage] = useState(1);\n const [expanded, setExpanded] = useState<Set<string>>(new Set());\n const [nestedCache, setNestedCache] = useState<Map<string, NestedStatus>>(new Map());\n\n const hasNested = !!getNestedData && !!nestedColumns;\n const hasRowActions = !!rowActions;\n\n function toggleRow(item: T) {\n const id = item.id;\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n if (!nestedCache.has(id)) {\n const result = getNestedData!(item);\n if (result instanceof Promise) {\n setNestedCache((c) => new Map(c).set(id, { status: \"loading\", data: [] }));\n result.then((rows) => {\n setNestedCache((c) => new Map(c).set(id, { status: \"loaded\", data: rows }));\n });\n } else {\n setNestedCache((c) => new Map(c).set(id, { status: \"loaded\", data: result }));\n }\n }\n }\n return next;\n });\n }\n\n const hasSearch = searchKeys.length > 0;\n const hasToolbar = hasSearch || !!actions;\n\n const filtered = useMemo(() => {\n if (!query.trim() || !hasSearch) return data;\n const lower = query.toLowerCase();\n return data.filter((item) =>\n searchKeys.some((k) =>\n String(item[k] ?? \"\")\n .toLowerCase()\n .includes(lower),\n ),\n );\n }, [data, query, searchKeys, hasSearch]);\n\n const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));\n const currentPage = Math.min(page, totalPages);\n const pageData = filtered.slice(\n (currentPage - 1) * pageSize,\n currentPage * pageSize,\n );\n\n function getCell(item: T, col: Column<T>): ReactNode {\n if (col.render) return col.render(item);\n return String((item as Record<string, unknown>)[col.key as string] ?? \"\");\n }\n\n return (\n <Flex direction=\"column\" gap=\"300\" className=\"data-table\">\n {hasToolbar && (\n <div className=\"data-table-toolbar\">\n {hasSearch && (\n <Search\n placeholder={searchPlaceholder}\n onSearch={(v) => {\n setQuery(v);\n setPage(1);\n }}\n className=\"data-table-search\"\n />\n )}\n {actions && <div className=\"data-table-actions\">{actions}</div>}\n </div>\n )}\n\n {isLoading ? (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label={loadingMessage}\n className=\"data-table-status\"\n >\n {loadingMessage}\n </div>\n ) : filtered.length === 0 ? (\n <div role=\"status\" className=\"data-table-status data-table-empty\">\n {emptyMessage}\n </div>\n ) : (\n <Table grid>\n <TableHead>\n {hasNested && <TableColumn className=\"data-table-expand-col\" />}\n {columns.map((col, idx) => (\n <TableColumn\n key={String(col.key)}\n align={col.align}\n isRowHeader={idx === 0}\n >\n {col.label}\n </TableColumn>\n ))}\n {hasRowActions && (\n <TableColumn align=\"right\" className=\"data-table-row-actions-col\">\n {rowActionsLabel}\n </TableColumn>\n )}\n </TableHead>\n <TableBody>\n {pageData.flatMap((item) => {\n const isExpanded = expanded.has(item.id);\n const cached = nestedCache.get(item.id);\n const rows: ReactNode[] = [\n <TableRow key={item.id} id={item.id}>\n {hasNested && (\n <TableCell className=\"data-table-expand-cell\">\n <button\n className=\"data-table-expand-btn\"\n aria-label={isExpanded ? \"Collapse row\" : \"Expand row\"}\n aria-expanded={isExpanded}\n onClick={() => toggleRow(item)}\n >\n {isExpanded ? (\n <IconChevronDown size=\"16\" />\n ) : (\n <IconChevronRight size=\"16\" />\n )}\n </button>\n </TableCell>\n )}\n {columns.map((col) => (\n <TableCell key={String(col.key)} align={col.align}>\n {getCell(item, col)}\n </TableCell>\n ))}\n {hasRowActions && (\n <TableCell align=\"right\" className=\"data-table-row-actions-cell\">\n <div className=\"data-table-row-actions\">\n {(typeof rowActions === \"function\"\n ? rowActions(item)\n : rowActions!\n ).map((action) => (\n <RowActionButton key={action.key} action={action} item={item} />\n ))}\n </div>\n </TableCell>\n )}\n </TableRow>,\n ];\n if (isExpanded) {\n rows.push(\n <TableRow key={`${item.id}-nested`} id={`${item.id}-nested`} className=\"data-table-nested-row\">\n <TableCell\n colSpan={columns.length + 1 + (hasRowActions ? 1 : 0)}\n className=\"data-table-nested-cell\"\n >\n <DataTable\n columns={nestedColumns!}\n data={cached?.data ?? []}\n isLoading={!cached || cached.status === \"loading\"}\n loadingMessage={nestedLoadingMessage}\n emptyMessage={nestedEmptyMessage}\n searchKeys={nestedSearchKeys}\n searchPlaceholder={nestedSearchPlaceholder}\n actions={nestedActions?.(item)}\n pageSize={nestedPageSize ?? pageSize}\n />\n </TableCell>\n </TableRow>,\n );\n }\n return rows;\n })}\n </TableBody>\n </Table>\n )}\n\n {totalPages > 1 && (\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n onPageChange={setPage}\n previousLabel={previousLabel}\n nextLabel={nextLabel}\n />\n )}\n </Flex>\n );\n}\n"],"names":["buildPages","current","total","_","i","head","tail","Pagination","currentPage","totalPages","onPageChange","previousLabel","nextLabel","pages","jsxs","jsx","IconArrowLeft","p","IconArrowRight","RowActionButton","action","item","allowed","btn","PermissionGate","DataTable","columns","data","actions","rowActions","rowActionsLabel","searchPlaceholder","searchKeys","isLoading","loadingMessage","emptyMessage","pageSize","nestedColumns","getNestedData","nestedLoadingMessage","nestedEmptyMessage","nestedSearchKeys","nestedSearchPlaceholder","nestedActions","nestedPageSize","query","setQuery","useState","page","setPage","expanded","setExpanded","nestedCache","setNestedCache","hasNested","hasRowActions","toggleRow","id","prev","next","result","c","rows","hasSearch","hasToolbar","filtered","useMemo","lower","k","pageData","getCell","col","Flex","Search","v","Table","TableHead","TableColumn","idx","TableBody","isExpanded","cached","TableRow","TableCell","IconChevronDown","IconChevronRight"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable.js","sources":["../../../../../src/ui/components/DataTable/DataTable.tsx"],"sourcesContent":["import {\n Pagination,\n PermissionGate,\n Search,\n Table,\n TableBody,\n TableCell,\n TableColumn,\n TableHead,\n TableRow,\n} from \"primitives\";\nimport { Flex } from \"layout\";\nimport { IconChevronDown, IconChevronRight } from \"icons\";\nimport type { ReactNode } from \"react\";\nimport { useMemo, useState } from \"react\";\nimport \"./datatable.css\";\n\nexport interface Column<T> {\n key: keyof T | string;\n label: string;\n align?: \"start\" | \"center\" | \"right\";\n render?: (item: T) => ReactNode;\n}\n\nexport interface RowActionDef<T> {\n /** Unique key for this action. */\n key: string;\n /** aria-label for the button. */\n label: string;\n /** Icon element rendered inside the button. */\n icon: ReactNode;\n /** When false, button is disabled and a tooltip with `noAccessLabel` is shown. Default: true. */\n isAllowed?: boolean;\n /** Tooltip text shown when `isAllowed` is false. */\n noAccessLabel?: string;\n /** Called with the row item when the button is pressed. */\n onPress: (item: T) => void;\n}\n\nfunction RowActionButton<T>({\n action,\n item,\n}: {\n action: RowActionDef<T>;\n item: T;\n}) {\n const allowed = action.isAllowed !== false;\n const btn = (\n <button\n className=\"data-table-row-action-btn\"\n aria-label={action.label}\n disabled={!allowed}\n onClick={allowed ? () => action.onPress(item) : undefined}\n >\n {action.icon}\n </button>\n );\n if (allowed) return btn;\n return (\n <PermissionGate isAllowed={false} noAccessLabel={action.noAccessLabel ?? \"\"}>\n {btn}\n </PermissionGate>\n );\n}\n\ntype NestedStatus = { status: \"loading\"; data: never[] } | { status: \"loaded\"; data: any[] };\n\nexport interface DataTableProps<T extends { id: string }> {\n columns: Column<T>[];\n data: T[];\n actions?: ReactNode;\n /** Per-row action buttons rendered in a dedicated last column. */\n rowActions?: RowActionDef<T>[] | ((item: T) => RowActionDef<T>[]);\n /** Label for the row actions column header. Defaults to empty string. */\n rowActionsLabel?: string;\n searchPlaceholder?: string;\n searchKeys?: (keyof T)[];\n isLoading?: boolean;\n loadingMessage?: string;\n emptyMessage?: string;\n previousLabel?: string;\n nextLabel?: string;\n pageSize?: number;\n nestedColumns?: Column<any>[];\n getNestedData?: (item: T) => any[] | Promise<any[]>;\n nestedLoadingMessage?: string;\n nestedEmptyMessage?: string;\n nestedSearchKeys?: (keyof any)[];\n nestedSearchPlaceholder?: string;\n nestedActions?: (item: T) => ReactNode;\n nestedPageSize?: number;\n}\n\nexport function DataTable<T extends { id: string }>({\n columns,\n data,\n actions,\n rowActions,\n rowActionsLabel = \"\",\n searchPlaceholder = \"Search...\",\n searchKeys = [],\n isLoading = false,\n loadingMessage = \"Loading...\",\n emptyMessage = \"No records found\",\n previousLabel = \"Previous\",\n nextLabel = \"Next\",\n pageSize = 10,\n nestedColumns,\n getNestedData,\n nestedLoadingMessage = \"Loading...\",\n nestedEmptyMessage = \"No records found\",\n nestedSearchKeys,\n nestedSearchPlaceholder,\n nestedActions,\n nestedPageSize,\n}: DataTableProps<T>) {\n const [query, setQuery] = useState(\"\");\n const [page, setPage] = useState(1);\n const [expanded, setExpanded] = useState<Set<string>>(new Set());\n const [nestedCache, setNestedCache] = useState<Map<string, NestedStatus>>(new Map());\n\n const hasNested = !!getNestedData && !!nestedColumns;\n const hasRowActions = !!rowActions;\n\n function toggleRow(item: T) {\n const id = item.id;\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n if (!nestedCache.has(id)) {\n const result = getNestedData!(item);\n if (result instanceof Promise) {\n setNestedCache((c) => new Map(c).set(id, { status: \"loading\", data: [] }));\n result.then((rows) => {\n setNestedCache((c) => new Map(c).set(id, { status: \"loaded\", data: rows }));\n });\n } else {\n setNestedCache((c) => new Map(c).set(id, { status: \"loaded\", data: result }));\n }\n }\n }\n return next;\n });\n }\n\n const hasSearch = searchKeys.length > 0;\n const hasToolbar = hasSearch || !!actions;\n\n const filtered = useMemo(() => {\n if (!query.trim() || !hasSearch) return data;\n const lower = query.toLowerCase();\n return data.filter((item) =>\n searchKeys.some((k) =>\n String(item[k] ?? \"\")\n .toLowerCase()\n .includes(lower),\n ),\n );\n }, [data, query, searchKeys, hasSearch]);\n\n const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));\n const currentPage = Math.min(page, totalPages);\n const pageData = filtered.slice(\n (currentPage - 1) * pageSize,\n currentPage * pageSize,\n );\n\n function getCell(item: T, col: Column<T>): ReactNode {\n if (col.render) return col.render(item);\n return String((item as Record<string, unknown>)[col.key as string] ?? \"\");\n }\n\n return (\n <Flex direction=\"column\" gap=\"300\" className=\"data-table\">\n {hasToolbar && (\n <div className=\"data-table-toolbar\">\n {hasSearch && (\n <Search\n placeholder={searchPlaceholder}\n onSearch={(v) => {\n setQuery(v);\n setPage(1);\n }}\n className=\"data-table-search\"\n />\n )}\n {actions && <div className=\"data-table-actions\">{actions}</div>}\n </div>\n )}\n\n {isLoading ? (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label={loadingMessage}\n className=\"data-table-status\"\n >\n {loadingMessage}\n </div>\n ) : filtered.length === 0 ? (\n <div role=\"status\" className=\"data-table-status data-table-empty\">\n {emptyMessage}\n </div>\n ) : (\n <Table grid>\n <TableHead>\n {hasNested && <TableColumn className=\"data-table-expand-col\" />}\n {columns.map((col, idx) => (\n <TableColumn\n key={String(col.key)}\n align={col.align}\n isRowHeader={idx === 0}\n >\n {col.label}\n </TableColumn>\n ))}\n {hasRowActions && (\n <TableColumn align=\"right\" className=\"data-table-row-actions-col\">\n {rowActionsLabel}\n </TableColumn>\n )}\n </TableHead>\n <TableBody>\n {pageData.flatMap((item) => {\n const isExpanded = expanded.has(item.id);\n const cached = nestedCache.get(item.id);\n const rows: ReactNode[] = [\n <TableRow key={item.id} id={item.id}>\n {hasNested && (\n <TableCell className=\"data-table-expand-cell\">\n <button\n className=\"data-table-expand-btn\"\n aria-label={isExpanded ? \"Collapse row\" : \"Expand row\"}\n aria-expanded={isExpanded}\n onClick={() => toggleRow(item)}\n >\n {isExpanded ? (\n <IconChevronDown size=\"16\" />\n ) : (\n <IconChevronRight size=\"16\" />\n )}\n </button>\n </TableCell>\n )}\n {columns.map((col) => (\n <TableCell key={String(col.key)} align={col.align}>\n {getCell(item, col)}\n </TableCell>\n ))}\n {hasRowActions && (\n <TableCell align=\"right\" className=\"data-table-row-actions-cell\">\n <div className=\"data-table-row-actions\">\n {(typeof rowActions === \"function\"\n ? rowActions(item)\n : rowActions!\n ).map((action) => (\n <RowActionButton key={action.key} action={action} item={item} />\n ))}\n </div>\n </TableCell>\n )}\n </TableRow>,\n ];\n if (isExpanded) {\n rows.push(\n <TableRow key={`${item.id}-nested`} id={`${item.id}-nested`} className=\"data-table-nested-row\">\n <TableCell\n colSpan={columns.length + 1 + (hasRowActions ? 1 : 0)}\n className=\"data-table-nested-cell\"\n >\n <DataTable\n columns={nestedColumns!}\n data={cached?.data ?? []}\n isLoading={!cached || cached.status === \"loading\"}\n loadingMessage={nestedLoadingMessage}\n emptyMessage={nestedEmptyMessage}\n searchKeys={nestedSearchKeys}\n searchPlaceholder={nestedSearchPlaceholder}\n actions={nestedActions?.(item)}\n pageSize={nestedPageSize ?? pageSize}\n />\n </TableCell>\n </TableRow>,\n );\n }\n return rows;\n })}\n </TableBody>\n </Table>\n )}\n\n <Pagination\n page={currentPage}\n totalPages={totalPages}\n onPageChange={setPage}\n previousLabel={previousLabel}\n nextLabel={nextLabel}\n />\n </Flex>\n );\n}\n"],"names":["RowActionButton","action","item","allowed","btn","jsx","PermissionGate","DataTable","columns","data","actions","rowActions","rowActionsLabel","searchPlaceholder","searchKeys","isLoading","loadingMessage","emptyMessage","previousLabel","nextLabel","pageSize","nestedColumns","getNestedData","nestedLoadingMessage","nestedEmptyMessage","nestedSearchKeys","nestedSearchPlaceholder","nestedActions","nestedPageSize","query","setQuery","useState","page","setPage","expanded","setExpanded","nestedCache","setNestedCache","hasNested","hasRowActions","toggleRow","id","prev","next","result","rows","c","hasSearch","hasToolbar","filtered","useMemo","lower","k","totalPages","currentPage","pageData","getCell","col","Flex","jsxs","Search","v","Table","TableHead","TableColumn","idx","TableBody","isExpanded","cached","TableRow","TableCell","IconChevronDown","IconChevronRight","Pagination"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("../../../vendor/clsx/dist/clsx.cjs");;/* empty css */const r=require("../../icons/IconArrowLeft.cjs"),l=require("../../icons/IconArrowRight.cjs"),u=require("../../hooks/useMediaQuery.cjs"),s=require("../../utils/AnchorOrButton.cjs");function c({"aria-label":a="Page navigation",className:n,...i}){const t=o.clsx(n,"pagination");return e.jsx("nav",{"aria-label":a,...i,className:t})}function g({href:a=null,onPress:n,isDisabled:i=!1,children:t="Previous"}){return e.jsxs(s.AnchorOrButton,{...a!==null?{href:a}:{},onPress:n,isDisabled:i||a===null&&!n,className:o.clsx("pagination-btn","pagination-nav"),"aria-label":"Previous page",children:[e.jsx(r.IconArrowLeft,{size:"16"}),t]})}function P({href:a=null,onPress:n,isDisabled:i=!1,children:t="Next"}){return e.jsxs(s.AnchorOrButton,{...a!==null?{href:a}:{},onPress:n,isDisabled:i||a===null&&!n,className:o.clsx("pagination-btn","pagination-nav"),"aria-label":"Next page",children:[t,e.jsx(l.IconArrowRight,{size:"16"})]})}function p({children:a}){const{isTabletUp:n}=u.useMediaQuery();return n&&e.jsx("span",{className:"pagination-list",children:a})}function x({href:a,onPress:n,children:i,current:t=!1}){return e.jsx(s.AnchorOrButton,{...a?{href:a}:{},onPress:n,"aria-label":`Page ${i}`,"aria-current":t?"page":void 0,className:o.clsx("pagination-btn",t&&"pagination-btn-active"),children:i})}function b(){return e.jsx("div",{"aria-hidden":"true",className:"pagination-gap",children:"…"})}exports.Pagination=c;exports.PaginationGap=b;exports.PaginationList=p;exports.PaginationNext=P;exports.PaginationPage=x;exports.PaginationPrevious=g;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),l=require("../../../vendor/clsx/dist/clsx.cjs");;/* empty css */const h=require("../../icons/IconArrowLeft.cjs"),N=require("../../icons/IconArrowRight.cjs"),A=require("../../hooks/useMediaQuery.cjs"),c=require("../../utils/AnchorOrButton.cjs");function q(a){return"totalPages"in a}function L(a){if(q(a)){const{page:t,totalPages:r,onPageChange:u,previousLabel:m,nextLabel:p,className:f}=a;return r<=1?null:i.jsxs("nav",{"aria-label":"Page navigation",className:l.clsx(f,"pagination"),children:[i.jsx(g,{isDisabled:t<=1,onPress:()=>u(Math.max(1,t-1)),children:m}),i.jsx(x,{children:j(t,r).map((o,v)=>o==="..."?i.jsx(b,{},`gap-${v}`):i.jsx(d,{current:o===t,onPress:()=>u(o),children:String(o)},o))}),i.jsx(P,{isDisabled:t>=r,onPress:()=>u(Math.min(r,t+1)),children:p})]})}const{"aria-label":n="Page navigation",className:e,...s}=a;return i.jsx("nav",{"aria-label":n,...s,className:l.clsx(e,"pagination")})}function g({href:a=null,onPress:n,isDisabled:e=!1,children:s="Previous"}){return i.jsxs(c.AnchorOrButton,{...a!==null?{href:a}:{},onPress:n,isDisabled:e||a===null&&!n,className:l.clsx("pagination-btn","pagination-nav"),"aria-label":"Previous page",children:[i.jsx(h.IconArrowLeft,{size:"16"}),s]})}function P({href:a=null,onPress:n,isDisabled:e=!1,children:s="Next"}){return i.jsxs(c.AnchorOrButton,{...a!==null?{href:a}:{},onPress:n,isDisabled:e||a===null&&!n,className:l.clsx("pagination-btn","pagination-nav"),"aria-label":"Next page",children:[s,i.jsx(N.IconArrowRight,{size:"16"})]})}function x({children:a}){const{isTabletUp:n}=A.useMediaQuery();return n&&i.jsx("span",{className:"pagination-list",children:a})}function d({href:a,onPress:n,children:e,current:s=!1}){return i.jsx(c.AnchorOrButton,{...a?{href:a}:{},onPress:n,"aria-label":`Page ${e}`,"aria-current":s?"page":void 0,className:l.clsx("pagination-btn",s&&"pagination-btn-active"),children:e})}function b(){return i.jsx("div",{"aria-hidden":"true",className:"pagination-gap",children:"…"})}function j(a,n){if(n<=6)return Array.from({length:n},(t,r)=>r+1);const e=[1,2,3],s=[n-1,n];return a<=4?[...e,"...",...s]:a>=n-3?[1,2,"...",n-2,n-1,n]:[1,"...",a-1,a,a+1,"...",n]}exports.Pagination=L;exports.PaginationGap=b;exports.PaginationList=x;exports.PaginationNext=P;exports.PaginationPage=d;exports.PaginationPrevious=g;exports.buildPaginationPages=j;
2
2
  //# sourceMappingURL=Pagination.cjs.map