@apipass/design-system 5.3.0 → 5.5.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.
- package/dist/lib/embedded-styles.js +2 -2
- package/dist/lib/style.css +1 -1
- package/dist/lib/ui/components/DataTable/DataTable.cjs +1 -1
- package/dist/lib/ui/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/lib/ui/components/DataTable/DataTable.js +76 -75
- package/dist/lib/ui/components/DataTable/DataTable.js.map +1 -1
- package/dist/lib/ui/primitives/Table/Table.cjs +1 -1
- package/dist/lib/ui/primitives/Table/Table.cjs.map +1 -1
- package/dist/lib/ui/primitives/Table/Table.js +91 -53
- package/dist/lib/ui/primitives/Table/Table.js.map +1 -1
- package/dist/types/ui/components/DataTable/DataTable.d.ts +11 -3
- package/dist/types/ui/primitives/Table/Table.d.ts +11 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),h=require("react");;/* empty css */const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),h=require("react");;/* empty css */const ee=require("../../primitives/Search/Search.cjs"),t=require("../../primitives/Table/Table.cjs"),ae=require("../../icons/IconChevronDown.cjs"),se=require("../../icons/IconChevronRight.cjs"),te=require("../../primitives/Pagination/Pagination.cjs"),le=require("../../primitives/PermissionGate/PermissionGate.cjs"),ne=require("../../layout/Flex/Flex.cjs");function re({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(le.PermissionGate,{isAllowed:!1,noAccessLabel:n.noAccessLabel??"",children:d})}function k({columns:n,data:c,actions:o,rowActions:d,rowActionsLabel:L="",selectable:S=!1,selectionType:T="checkbox",selectedKeys:D,onSelectionChange:I,searchPlaceholder:E="Search...",searchKeys:g=[],isLoading:B=!1,loadingMessage:v="Loading...",emptyMessage:F="No records found",previousLabel:G="Previous",nextLabel:H="Next",pageSize:b=10,nestedColumns:P,getNestedData:M,nestedLoadingMessage:$="Loading...",nestedEmptyMessage:O="No records found",nestedSearchKeys:Q,nestedSearchPlaceholder:z,nestedActions:j,nestedPageSize:J}){const[p,U]=h.useState(""),[V,q]=h.useState(1),[W,X]=h.useState(new Set),[y,w]=h.useState(new Map),f=!!M&&!!P,m=!!d;function Y(a){const s=a.id;X(r=>{const i=new Set(r);if(i.has(s))i.delete(s);else if(i.add(s),!y.has(s)){const l=M(a);l instanceof Promise?(w(u=>new Map(u).set(s,{status:"loading",data:[]})),l.then(u=>{w(K=>new Map(K).set(s,{status:"loaded",data:u}))})):w(u=>new Map(u).set(s,{status:"loaded",data:l}))}return i})}const x=g.length>0,Z=x||!!o,C=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]),R=Math.max(1,Math.ceil(C.length/b)),N=Math.min(V,R),_=C.slice((N-1)*b,N*b);function A(a,s){return s.render?s.render(a):String(a[s.key]??"")}return e.jsxs(ne.Flex,{direction:"column",gap:"300",className:"data-table",children:[Z&&e.jsxs("div",{className:"data-table-toolbar",children:[x&&e.jsx(ee.Search,{placeholder:E,onSearch:a=>{U(a),q(1)},className:"data-table-search"}),o&&e.jsx("div",{className:"data-table-actions",children:o})]}),B?e.jsx("div",{role:"status","aria-live":"polite","aria-label":v,className:"data-table-status",children:v}):C.length===0?e.jsx("div",{role:"status",className:"data-table-status data-table-empty",children:F}):e.jsxs(t.Table,{selectionMode:S?T==="radio"?"single":"multiple":"none",selectionType:T,selectedKeys:D,onSelectionChange:I,children:[e.jsxs(t.TableHead,{children:[f&&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))),m&&e.jsx(t.TableColumn,{align:"right",className:"data-table-row-actions-col",children:L})]}),e.jsx(t.TableBody,{children:_.flatMap(a=>{const s=W.has(a.id),r=y.get(a.id),i=[e.jsxs(t.TableRow,{id:a.id,children:[f&&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:()=>Y(a),children:s?e.jsx(ae.IconChevronDown,{size:"16"}):e.jsx(se.IconChevronRight,{size:"16"})})}),n.map(l=>e.jsx(t.TableCell,{align:l.align,children:A(a,l)},String(l.key))),m&&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(re,{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+(f?1:0)+(S?1:0)+(m?1:0),className:"data-table-nested-cell",children:e.jsx(k,{columns:P,data:(r==null?void 0:r.data)??[],isLoading:!r||r.status==="loading",loadingMessage:$,emptyMessage:O,searchKeys:Q,searchPlaceholder:z,actions:j==null?void 0:j(a),pageSize:J??b})})},`${a.id}-nested`)),i})})]}),e.jsx(te.Pagination,{page:N,totalPages:R,onPageChange:q,previousLabel:G,nextLabel:H})]})}exports.DataTable=k;
|
|
2
2
|
//# sourceMappingURL=DataTable.cjs.map
|
|
@@ -1 +1 @@
|
|
|
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 type { Selection } from \"react-aria-components\";\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\n// O tipo da linha aninhada é independente de T (não há relação genérica entre linha pai e linhas\n// filhas), então \"any\" é usado deliberadamente como fronteira de erasure de tipo.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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 /**\n * When true, renders a checkbox column before the first data column — a per-row checkbox on\n * every row, plus a \"select all\" checkbox in the header. Off by default.\n */\n selectable?: boolean;\n /** Controlled selection state. Omit to let the table manage its own selection internally. */\n selectedKeys?: Selection;\n onSelectionChange?: (keys: Selection) => void;\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\n nestedColumns?: Column<any>[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\n getNestedData?: (item: T) => any[] | Promise<any[]>;\n nestedLoadingMessage?: string;\n nestedEmptyMessage?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\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 selectable = false,\n selectedKeys,\n onSelectionChange,\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\n grid\n selectionMode={selectable ? \"multiple\" : \"none\"}\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n >\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={\n columns.length +\n (hasNested ? 1 : 0) +\n (selectable ? 1 : 0) +\n (hasRowActions ? 1 : 0)\n }\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","selectable","selectedKeys","onSelectionChange","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":"2gBAwCA,SAASA,GAAmB,CAC1B,OAAAC,EACA,KAAAC,CACF,EAGG,CACD,MAAMC,EAAUF,EAAO,YAAc,GAC/BG,EACJC,EAAAA,IAAC,SAAA,CACC,UAAU,4BACV,aAAYJ,EAAO,MACnB,SAAU,CAACE,EACX,QAASA,EAAU,IAAMF,EAAO,QAAQC,CAAI,EAAI,OAE/C,SAAAD,EAAO,IAAA,CAAA,EAGZ,OAAIE,EAAgBC,EAElBC,MAACC,GAAAA,gBAAe,UAAW,GAAO,cAAeL,EAAO,eAAiB,GACtE,SAAAG,CAAA,CACH,CAEJ,CA4CO,SAASG,EAAoC,CAClD,QAAAC,EACA,KAAAC,EACA,QAAAC,EACA,WAAAC,EACA,gBAAAC,EAAkB,GAClB,WAAAC,EAAa,GACb,aAAAC,EACA,kBAAAC,EACA,kBAAAC,EAAoB,YACpB,WAAAC,EAAa,CAAA,EACb,UAAAC,EAAY,GACZ,eAAAC,EAAiB,aACjB,aAAAC,EAAe,mBACf,cAAAC,EAAgB,WAChB,UAAAC,EAAY,OACZ,SAAAC,EAAW,GACX,cAAAC,EACA,cAAAC,EACA,qBAAAC,EAAuB,aACvB,mBAAAC,EAAqB,mBACrB,iBAAAC,EACA,wBAAAC,EACA,cAAAC,EACA,eAAAC,CACF,EAAsB,CACpB,KAAM,CAACC,EAAOC,CAAQ,EAAIC,EAAAA,SAAS,EAAE,EAC/B,CAACC,EAAMC,CAAO,EAAIF,EAAAA,SAAS,CAAC,EAC5B,CAACG,EAAUC,CAAW,EAAIJ,EAAAA,SAAsB,IAAI,GAAK,EACzD,CAACK,EAAaC,CAAc,EAAIN,EAAAA,SAAoC,IAAI,GAAK,EAE7EO,EAAY,CAAC,CAAChB,GAAiB,CAAC,CAACD,EACjCkB,EAAgB,CAAC,CAAC/B,EAExB,SAASgC,EAAUzC,EAAS,CAC1B,MAAM0C,EAAK1C,EAAK,GAChBoC,EAAaO,GAAS,CACpB,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,GAAIC,EAAK,IAAIF,CAAE,EACbE,EAAK,OAAOF,CAAE,UAEdE,EAAK,IAAIF,CAAE,EACP,CAACL,EAAY,IAAIK,CAAE,EAAG,CACxB,MAAMG,EAAStB,EAAevB,CAAI,EAC9B6C,aAAkB,SACpBP,EAAgBQ,GAAM,IAAI,IAAIA,CAAC,EAAE,IAAIJ,EAAI,CAAE,OAAQ,UAAW,KAAM,CAAA,CAAC,CAAG,CAAC,EACzEG,EAAO,KAAME,GAAS,CACpBT,EAAgBQ,GAAM,IAAI,IAAIA,CAAC,EAAE,IAAIJ,EAAI,CAAE,OAAQ,SAAU,KAAMK,CAAA,CAAM,CAAC,CAC5E,CAAC,GAEDT,EAAgBQ,GAAM,IAAI,IAAIA,CAAC,EAAE,IAAIJ,EAAI,CAAE,OAAQ,SAAU,KAAMG,CAAA,CAAQ,CAAC,CAEhF,CAEF,OAAOD,CACT,CAAC,CACH,CAEA,MAAMI,EAAYjC,EAAW,OAAS,EAChCkC,EAAaD,GAAa,CAAC,CAACxC,EAE5B0C,EAAWC,EAAAA,QAAQ,IAAM,CAC7B,GAAI,CAACrB,EAAM,KAAA,GAAU,CAACkB,EAAW,OAAOzC,EACxC,MAAM6C,EAAQtB,EAAM,YAAA,EACpB,OAAOvB,EAAK,OAAQP,GAClBe,EAAW,KAAMsC,GACf,OAAOrD,EAAKqD,CAAC,GAAK,EAAE,EACjB,cACA,SAASD,CAAK,CAAA,CACnB,CAEJ,EAAG,CAAC7C,EAAMuB,EAAOf,EAAYiC,CAAS,CAAC,EAEjCM,EAAa,KAAK,IAAI,EAAG,KAAK,KAAKJ,EAAS,OAAS7B,CAAQ,CAAC,EAC9DkC,EAAc,KAAK,IAAItB,EAAMqB,CAAU,EACvCE,EAAWN,EAAS,OACvBK,EAAc,GAAKlC,EACpBkC,EAAclC,CAAA,EAGhB,SAASoC,EAAQzD,EAAS0D,EAA2B,CACnD,OAAIA,EAAI,OAAeA,EAAI,OAAO1D,CAAI,EAC/B,OAAQA,EAAiC0D,EAAI,GAAa,GAAK,EAAE,CAC1E,CAEA,cACGC,QAAA,CAAK,UAAU,SAAS,IAAI,MAAM,UAAU,aAC1C,SAAA,CAAAV,GACCW,EAAAA,KAAC,MAAA,CAAI,UAAU,qBACZ,SAAA,CAAAZ,GACC7C,EAAAA,IAAC0D,EAAAA,OAAA,CACC,YAAa/C,EACb,SAAWgD,GAAM,CACf/B,EAAS+B,CAAC,EACV5B,EAAQ,CAAC,CACX,EACA,UAAU,mBAAA,CAAA,EAGb1B,GAAWL,EAAAA,IAAC,MAAA,CAAI,UAAU,qBAAsB,SAAAK,CAAA,CAAQ,CAAA,EAC3D,EAGDQ,EACCb,EAAAA,IAAC,MAAA,CACC,KAAK,SACL,YAAU,SACV,aAAYc,EACZ,UAAU,oBAET,SAAAA,CAAA,CAAA,EAEDiC,EAAS,SAAW,EACtB/C,EAAAA,IAAC,MAAA,CAAI,KAAK,SAAS,UAAU,qCAC1B,SAAAe,CAAA,CACH,EAEA0C,EAAAA,KAACG,EAAAA,MAAA,CACC,KAAI,GACJ,cAAepD,EAAa,WAAa,OACzC,aAAAC,EACA,kBAAAC,EAEA,SAAA,CAAA+C,OAACI,EAAAA,UAAA,CACE,SAAA,CAAAzB,GAAapC,EAAAA,IAAC8D,EAAAA,YAAA,CAAY,UAAU,uBAAA,CAAwB,EAC5D3D,EAAQ,IAAI,CAACoD,EAAKQ,IACjB/D,EAAAA,IAAC8D,EAAAA,YAAA,CAEC,MAAOP,EAAI,MACX,YAAaQ,IAAQ,EAEpB,SAAAR,EAAI,KAAA,EAJA,OAAOA,EAAI,GAAG,CAAA,CAMtB,EACAlB,GACCrC,EAAAA,IAAC8D,EAAAA,YAAA,CAAY,MAAM,QAAQ,UAAU,6BAClC,SAAAvD,CAAA,CACH,CAAA,EAEJ,EACAP,EAAAA,IAACgE,EAAAA,UAAA,CACE,SAAAX,EAAS,QAASxD,GAAS,CAC1B,MAAMoE,EAAajC,EAAS,IAAInC,EAAK,EAAE,EACjCqE,EAAShC,EAAY,IAAIrC,EAAK,EAAE,EAChC+C,EAAoB,CACxBa,EAAAA,KAACU,EAAAA,SAAA,CAAuB,GAAItE,EAAK,GAC9B,SAAA,CAAAuC,GACCpC,EAAAA,IAACoE,EAAAA,UAAA,CAAU,UAAU,yBACnB,SAAApE,EAAAA,IAAC,SAAA,CACC,UAAU,wBACV,aAAYiE,EAAa,eAAiB,aAC1C,gBAAeA,EACf,QAAS,IAAM3B,EAAUzC,CAAI,EAE5B,SAAAoE,QACEI,GAAAA,gBAAA,CAAgB,KAAK,KAAK,EAE3BrE,EAAAA,IAACsE,GAAAA,iBAAA,CAAiB,KAAK,IAAA,CAAK,CAAA,CAAA,EAGlC,EAEDnE,EAAQ,IAAKoD,GACZvD,EAAAA,IAACoE,aAAgC,MAAOb,EAAI,MACzC,SAAAD,EAAQzD,EAAM0D,CAAG,CAAA,EADJ,OAAOA,EAAI,GAAG,CAE9B,CACD,EACAlB,GACCrC,EAAAA,IAACoE,EAAAA,UAAA,CAAU,MAAM,QAAQ,UAAU,8BACjC,SAAApE,EAAAA,IAAC,MAAA,CAAI,UAAU,yBACX,UAAA,OAAOM,GAAe,WACpBA,EAAWT,CAAI,EACfS,GACF,IAAKV,GACLI,EAAAA,IAACL,GAAA,CAAiC,OAAAC,EAAgB,KAAAC,CAAA,EAA5BD,EAAO,GAAiC,CAC/D,EACH,CAAA,CACF,CAAA,CAAA,EAhCWC,EAAK,EAkCpB,CAAA,EAEF,OAAIoE,GACFrB,EAAK,KACH5C,EAAAA,IAACmE,EAAAA,UAAmC,GAAI,GAAGtE,EAAK,EAAE,UAAW,UAAU,wBACrE,SAAAG,EAAAA,IAACoE,EAAAA,UAAA,CACC,QACEjE,EAAQ,QACPiC,EAAY,EAAI,IAChB5B,EAAa,EAAI,IACjB6B,EAAgB,EAAI,GAEvB,UAAU,yBAEV,SAAArC,EAAAA,IAACE,EAAA,CACC,QAASiB,EACT,MAAM+C,GAAA,YAAAA,EAAQ,OAAQ,CAAA,EACtB,UAAW,CAACA,GAAUA,EAAO,SAAW,UACxC,eAAgB7C,EAChB,aAAcC,EACd,WAAYC,EACZ,kBAAmBC,EACnB,QAASC,GAAA,YAAAA,EAAgB5B,GACzB,SAAU6B,GAAkBR,CAAA,CAAA,CAC9B,CAAA,CACF,EArBa,GAAGrB,EAAK,EAAE,SAsBzB,CAAA,EAGG+C,CACT,CAAC,CAAA,CACH,CAAA,CAAA,CAAA,EAIJ5C,EAAAA,IAACuE,GAAAA,WAAA,CACC,KAAMnB,EACN,WAAAD,EACA,aAAcpB,EACd,cAAAf,EACA,UAAAC,CAAA,CAAA,CACF,EACF,CAEJ"}
|
|
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 type { Selection } from \"react-aria-components\";\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\n// O tipo da linha aninhada é independente de T (não há relação genérica entre linha pai e linhas\n// filhas), então \"any\" é usado deliberadamente como fronteira de erasure de tipo.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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 /**\n * When true, renders a selection column before the first data column — a per-row control on\n * every row (see `selectionType`), plus a \"select all\" checkbox in the header when\n * `selectionType` is \"checkbox\". Off by default.\n */\n selectable?: boolean;\n /**\n * Visual style of the built-in selection control. \"checkbox\" (default) allows selecting\n * multiple rows and shows a \"select all\" in the header. \"radio\" restricts selection to a\n * single row (no \"select all\" — there is nothing to select all *to* with one choice) and\n * renders a round control instead of a checkbox.\n */\n selectionType?: \"checkbox\" | \"radio\";\n /** Controlled selection state. Omit to let the table manage its own selection internally. */\n selectedKeys?: Selection;\n onSelectionChange?: (keys: Selection) => void;\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\n nestedColumns?: Column<any>[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\n getNestedData?: (item: T) => any[] | Promise<any[]>;\n nestedLoadingMessage?: string;\n nestedEmptyMessage?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\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 selectable = false,\n selectionType = \"checkbox\",\n selectedKeys,\n onSelectionChange,\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\n selectionMode={selectable ? (selectionType === \"radio\" ? \"single\" : \"multiple\") : \"none\"}\n selectionType={selectionType}\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n >\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={\n columns.length +\n (hasNested ? 1 : 0) +\n (selectable ? 1 : 0) +\n (hasRowActions ? 1 : 0)\n }\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","selectable","selectionType","selectedKeys","onSelectionChange","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,14 +1,14 @@
|
|
|
1
1
|
import { jsxs as h, jsx as e } from "react/jsx-runtime";
|
|
2
|
-
import { useState as
|
|
2
|
+
import { useState as u, useMemo as ta } from "react";
|
|
3
3
|
/* empty css */
|
|
4
|
-
import { Search as
|
|
5
|
-
import { Table as
|
|
6
|
-
import { IconChevronDown as
|
|
7
|
-
import { IconChevronRight as
|
|
8
|
-
import { Pagination as
|
|
9
|
-
import { PermissionGate as
|
|
10
|
-
import { Flex as
|
|
11
|
-
function
|
|
4
|
+
import { Search as la } from "../../primitives/Search/Search.js";
|
|
5
|
+
import { Table as na, TableHead as sa, TableColumn as P, TableBody as ra, TableRow as B, TableCell as g } from "../../primitives/Table/Table.js";
|
|
6
|
+
import { IconChevronDown as oa } from "../../icons/IconChevronDown.js";
|
|
7
|
+
import { IconChevronRight as da } from "../../icons/IconChevronRight.js";
|
|
8
|
+
import { Pagination as ia } from "../../primitives/Pagination/Pagination.js";
|
|
9
|
+
import { PermissionGate as ca } from "../../primitives/PermissionGate/PermissionGate.js";
|
|
10
|
+
import { Flex as ha } from "../../layout/Flex/Flex.js";
|
|
11
|
+
function ba({
|
|
12
12
|
action: n,
|
|
13
13
|
item: i
|
|
14
14
|
}) {
|
|
@@ -22,97 +22,98 @@ function ha({
|
|
|
22
22
|
children: n.icon
|
|
23
23
|
}
|
|
24
24
|
);
|
|
25
|
-
return r ? o : /* @__PURE__ */ e(
|
|
25
|
+
return r ? o : /* @__PURE__ */ e(ca, { isAllowed: !1, noAccessLabel: n.noAccessLabel ?? "", children: o });
|
|
26
26
|
}
|
|
27
27
|
function pa({
|
|
28
28
|
columns: n,
|
|
29
29
|
data: i,
|
|
30
30
|
actions: r,
|
|
31
31
|
rowActions: o,
|
|
32
|
-
rowActionsLabel:
|
|
32
|
+
rowActionsLabel: D = "",
|
|
33
33
|
selectable: S = !1,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
selectionType: y = "checkbox",
|
|
35
|
+
selectedKeys: H,
|
|
36
|
+
onSelectionChange: I,
|
|
37
|
+
searchPlaceholder: $ = "Search...",
|
|
37
38
|
searchKeys: m = [],
|
|
38
|
-
isLoading:
|
|
39
|
-
loadingMessage:
|
|
40
|
-
emptyMessage:
|
|
41
|
-
previousLabel:
|
|
42
|
-
nextLabel:
|
|
43
|
-
pageSize:
|
|
44
|
-
nestedColumns:
|
|
45
|
-
getNestedData:
|
|
46
|
-
nestedLoadingMessage:
|
|
47
|
-
nestedEmptyMessage:
|
|
48
|
-
nestedSearchKeys:
|
|
49
|
-
nestedSearchPlaceholder:
|
|
39
|
+
isLoading: q = !1,
|
|
40
|
+
loadingMessage: k = "Loading...",
|
|
41
|
+
emptyMessage: F = "No records found",
|
|
42
|
+
previousLabel: G = "Previous",
|
|
43
|
+
nextLabel: Q = "Next",
|
|
44
|
+
pageSize: b = 10,
|
|
45
|
+
nestedColumns: L,
|
|
46
|
+
getNestedData: T,
|
|
47
|
+
nestedLoadingMessage: z = "Loading...",
|
|
48
|
+
nestedEmptyMessage: J = "No records found",
|
|
49
|
+
nestedSearchKeys: O,
|
|
50
|
+
nestedSearchPlaceholder: U,
|
|
50
51
|
nestedActions: f,
|
|
51
|
-
nestedPageSize:
|
|
52
|
+
nestedPageSize: V
|
|
52
53
|
}) {
|
|
53
|
-
const [w,
|
|
54
|
-
function
|
|
54
|
+
const [w, W] = u(""), [X, R] = u(1), [Y, Z] = u(/* @__PURE__ */ new Set()), [E, N] = u(/* @__PURE__ */ new Map()), x = !!T && !!L, C = !!o;
|
|
55
|
+
function _(a) {
|
|
55
56
|
const t = a.id;
|
|
56
|
-
|
|
57
|
+
Z((s) => {
|
|
57
58
|
const d = new Set(s);
|
|
58
59
|
if (d.has(t))
|
|
59
60
|
d.delete(t);
|
|
60
|
-
else if (d.add(t), !
|
|
61
|
-
const l =
|
|
61
|
+
else if (d.add(t), !E.has(t)) {
|
|
62
|
+
const l = T(a);
|
|
62
63
|
l instanceof Promise ? (N((c) => new Map(c).set(t, { status: "loading", data: [] })), l.then((c) => {
|
|
63
|
-
N((
|
|
64
|
+
N((ea) => new Map(ea).set(t, { status: "loaded", data: c }));
|
|
64
65
|
})) : N((c) => new Map(c).set(t, { status: "loaded", data: l }));
|
|
65
66
|
}
|
|
66
67
|
return d;
|
|
67
68
|
});
|
|
68
69
|
}
|
|
69
|
-
const
|
|
70
|
-
if (!w.trim() || !
|
|
70
|
+
const p = m.length > 0, A = p || !!r, M = ta(() => {
|
|
71
|
+
if (!w.trim() || !p) return i;
|
|
71
72
|
const a = w.toLowerCase();
|
|
72
73
|
return i.filter(
|
|
73
74
|
(t) => m.some(
|
|
74
75
|
(s) => String(t[s] ?? "").toLowerCase().includes(a)
|
|
75
76
|
)
|
|
76
77
|
);
|
|
77
|
-
}, [i, w, m,
|
|
78
|
-
(v - 1) *
|
|
79
|
-
v *
|
|
78
|
+
}, [i, w, m, p]), j = Math.max(1, Math.ceil(M.length / b)), v = Math.min(X, j), K = M.slice(
|
|
79
|
+
(v - 1) * b,
|
|
80
|
+
v * b
|
|
80
81
|
);
|
|
81
|
-
function
|
|
82
|
+
function aa(a, t) {
|
|
82
83
|
return t.render ? t.render(a) : String(a[t.key] ?? "");
|
|
83
84
|
}
|
|
84
|
-
return /* @__PURE__ */ h(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
return /* @__PURE__ */ h(ha, { direction: "column", gap: "300", className: "data-table", children: [
|
|
86
|
+
A && /* @__PURE__ */ h("div", { className: "data-table-toolbar", children: [
|
|
87
|
+
p && /* @__PURE__ */ e(
|
|
88
|
+
la,
|
|
88
89
|
{
|
|
89
|
-
placeholder:
|
|
90
|
+
placeholder: $,
|
|
90
91
|
onSearch: (a) => {
|
|
91
|
-
|
|
92
|
+
W(a), R(1);
|
|
92
93
|
},
|
|
93
94
|
className: "data-table-search"
|
|
94
95
|
}
|
|
95
96
|
),
|
|
96
97
|
r && /* @__PURE__ */ e("div", { className: "data-table-actions", children: r })
|
|
97
98
|
] }),
|
|
98
|
-
|
|
99
|
+
q ? /* @__PURE__ */ e(
|
|
99
100
|
"div",
|
|
100
101
|
{
|
|
101
102
|
role: "status",
|
|
102
103
|
"aria-live": "polite",
|
|
103
|
-
"aria-label":
|
|
104
|
+
"aria-label": k,
|
|
104
105
|
className: "data-table-status",
|
|
105
|
-
children:
|
|
106
|
+
children: k
|
|
106
107
|
}
|
|
107
|
-
) : M.length === 0 ? /* @__PURE__ */ e("div", { role: "status", className: "data-table-status data-table-empty", children:
|
|
108
|
-
|
|
108
|
+
) : M.length === 0 ? /* @__PURE__ */ e("div", { role: "status", className: "data-table-status data-table-empty", children: F }) : /* @__PURE__ */ h(
|
|
109
|
+
na,
|
|
109
110
|
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
selectedKeys:
|
|
113
|
-
onSelectionChange:
|
|
111
|
+
selectionMode: S ? y === "radio" ? "single" : "multiple" : "none",
|
|
112
|
+
selectionType: y,
|
|
113
|
+
selectedKeys: H,
|
|
114
|
+
onSelectionChange: I,
|
|
114
115
|
children: [
|
|
115
|
-
/* @__PURE__ */ h(
|
|
116
|
+
/* @__PURE__ */ h(sa, { children: [
|
|
116
117
|
x && /* @__PURE__ */ e(P, { className: "data-table-expand-col" }),
|
|
117
118
|
n.map((a, t) => /* @__PURE__ */ e(
|
|
118
119
|
P,
|
|
@@ -123,27 +124,27 @@ function pa({
|
|
|
123
124
|
},
|
|
124
125
|
String(a.key)
|
|
125
126
|
)),
|
|
126
|
-
C && /* @__PURE__ */ e(P, { align: "right", className: "data-table-row-actions-col", children:
|
|
127
|
+
C && /* @__PURE__ */ e(P, { align: "right", className: "data-table-row-actions-col", children: D })
|
|
127
128
|
] }),
|
|
128
|
-
/* @__PURE__ */ e(
|
|
129
|
-
const t =
|
|
130
|
-
/* @__PURE__ */ h(
|
|
129
|
+
/* @__PURE__ */ e(ra, { children: K.flatMap((a) => {
|
|
130
|
+
const t = Y.has(a.id), s = E.get(a.id), d = [
|
|
131
|
+
/* @__PURE__ */ h(B, { id: a.id, children: [
|
|
131
132
|
x && /* @__PURE__ */ e(g, { className: "data-table-expand-cell", children: /* @__PURE__ */ e(
|
|
132
133
|
"button",
|
|
133
134
|
{
|
|
134
135
|
className: "data-table-expand-btn",
|
|
135
136
|
"aria-label": t ? "Collapse row" : "Expand row",
|
|
136
137
|
"aria-expanded": t,
|
|
137
|
-
onClick: () =>
|
|
138
|
-
children: t ? /* @__PURE__ */ e(
|
|
138
|
+
onClick: () => _(a),
|
|
139
|
+
children: t ? /* @__PURE__ */ e(oa, { size: "16" }) : /* @__PURE__ */ e(da, { size: "16" })
|
|
139
140
|
}
|
|
140
141
|
) }),
|
|
141
|
-
n.map((l) => /* @__PURE__ */ e(g, { align: l.align, children:
|
|
142
|
-
C && /* @__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(
|
|
142
|
+
n.map((l) => /* @__PURE__ */ e(g, { align: l.align, children: aa(a, l) }, String(l.key))),
|
|
143
|
+
C && /* @__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(ba, { action: l, item: a }, l.key)) }) })
|
|
143
144
|
] }, a.id)
|
|
144
145
|
];
|
|
145
146
|
return t && d.push(
|
|
146
|
-
/* @__PURE__ */ e(
|
|
147
|
+
/* @__PURE__ */ e(B, { id: `${a.id}-nested`, className: "data-table-nested-row", children: /* @__PURE__ */ e(
|
|
147
148
|
g,
|
|
148
149
|
{
|
|
149
150
|
colSpan: n.length + (x ? 1 : 0) + (S ? 1 : 0) + (C ? 1 : 0),
|
|
@@ -151,15 +152,15 @@ function pa({
|
|
|
151
152
|
children: /* @__PURE__ */ e(
|
|
152
153
|
pa,
|
|
153
154
|
{
|
|
154
|
-
columns:
|
|
155
|
+
columns: L,
|
|
155
156
|
data: (s == null ? void 0 : s.data) ?? [],
|
|
156
157
|
isLoading: !s || s.status === "loading",
|
|
157
|
-
loadingMessage:
|
|
158
|
-
emptyMessage:
|
|
159
|
-
searchKeys:
|
|
160
|
-
searchPlaceholder:
|
|
158
|
+
loadingMessage: z,
|
|
159
|
+
emptyMessage: J,
|
|
160
|
+
searchKeys: O,
|
|
161
|
+
searchPlaceholder: U,
|
|
161
162
|
actions: f == null ? void 0 : f(a),
|
|
162
|
-
pageSize:
|
|
163
|
+
pageSize: V ?? b
|
|
163
164
|
}
|
|
164
165
|
)
|
|
165
166
|
}
|
|
@@ -170,13 +171,13 @@ function pa({
|
|
|
170
171
|
}
|
|
171
172
|
),
|
|
172
173
|
/* @__PURE__ */ e(
|
|
173
|
-
|
|
174
|
+
ia,
|
|
174
175
|
{
|
|
175
176
|
page: v,
|
|
176
|
-
totalPages:
|
|
177
|
-
onPageChange:
|
|
178
|
-
previousLabel:
|
|
179
|
-
nextLabel:
|
|
177
|
+
totalPages: j,
|
|
178
|
+
onPageChange: R,
|
|
179
|
+
previousLabel: G,
|
|
180
|
+
nextLabel: Q
|
|
180
181
|
}
|
|
181
182
|
)
|
|
182
183
|
] });
|
|
@@ -1 +1 @@
|
|
|
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 type { Selection } from \"react-aria-components\";\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\n// O tipo da linha aninhada é independente de T (não há relação genérica entre linha pai e linhas\n// filhas), então \"any\" é usado deliberadamente como fronteira de erasure de tipo.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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 /**\n * When true, renders a checkbox column before the first data column — a per-row checkbox on\n * every row, plus a \"select all\" checkbox in the header. Off by default.\n */\n selectable?: boolean;\n /** Controlled selection state. Omit to let the table manage its own selection internally. */\n selectedKeys?: Selection;\n onSelectionChange?: (keys: Selection) => void;\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\n nestedColumns?: Column<any>[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\n getNestedData?: (item: T) => any[] | Promise<any[]>;\n nestedLoadingMessage?: string;\n nestedEmptyMessage?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\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 selectable = false,\n selectedKeys,\n onSelectionChange,\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\n grid\n selectionMode={selectable ? \"multiple\" : \"none\"}\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n >\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={\n columns.length +\n (hasNested ? 1 : 0) +\n (selectable ? 1 : 0) +\n (hasRowActions ? 1 : 0)\n }\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","selectable","selectedKeys","onSelectionChange","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
|
+
{"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 type { Selection } from \"react-aria-components\";\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\n// O tipo da linha aninhada é independente de T (não há relação genérica entre linha pai e linhas\n// filhas), então \"any\" é usado deliberadamente como fronteira de erasure de tipo.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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 /**\n * When true, renders a selection column before the first data column — a per-row control on\n * every row (see `selectionType`), plus a \"select all\" checkbox in the header when\n * `selectionType` is \"checkbox\". Off by default.\n */\n selectable?: boolean;\n /**\n * Visual style of the built-in selection control. \"checkbox\" (default) allows selecting\n * multiple rows and shows a \"select all\" in the header. \"radio\" restricts selection to a\n * single row (no \"select all\" — there is nothing to select all *to* with one choice) and\n * renders a round control instead of a checkbox.\n */\n selectionType?: \"checkbox\" | \"radio\";\n /** Controlled selection state. Omit to let the table manage its own selection internally. */\n selectedKeys?: Selection;\n onSelectionChange?: (keys: Selection) => void;\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\n nestedColumns?: Column<any>[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\n getNestedData?: (item: T) => any[] | Promise<any[]>;\n nestedLoadingMessage?: string;\n nestedEmptyMessage?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- linha aninhada é de tipo independente de T\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 selectable = false,\n selectionType = \"checkbox\",\n selectedKeys,\n onSelectionChange,\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\n selectionMode={selectable ? (selectionType === \"radio\" ? \"single\" : \"multiple\") : \"none\"}\n selectionType={selectionType}\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n >\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={\n columns.length +\n (hasNested ? 1 : 0) +\n (selectable ? 1 : 0) +\n (hasRowActions ? 1 : 0)\n }\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","selectable","selectionType","selectedKeys","onSelectionChange","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"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("../../../vendor/clsx/dist/clsx.cjs"),m=require("react"),n=require("react-aria-components");;/* empty css */const g=require("../../icons/IconChevronDown.cjs"),f=require("../../icons/IconChevronUp.cjs"),j=require("../Checkbox/Checkbox.cjs"),p=require("../Radio/Radio.cjs"),h=m.createContext("checkbox");function v(s){const l=Number(s);return`${s}`.trim()!==""&&Number.isFinite(l)?`${l}px`:`${s}`}function y({bleed:s=!1,dense:l=!1,grid:t=!1,striped:o=!1,selectionType:i="checkbox",maxHeight:a,className:d,...r}){const b=a!==void 0,C=c.clsx(d,"table-container",s&&"table-container-bleed",b&&"table-container-scrollable"),N=b?{"--table-max-height":v(a)}:void 0,T=c.clsx("sds-table",s&&"table-bleed",l&&"table-dense",t&&"table-grid",o&&"sds-table-striped");return e.jsx("div",{className:C,style:N,children:e.jsx(h.Provider,{value:i,children:e.jsx(n.Table,{className:T,...r})})})}function x({align:s="start",className:l,...t}){const o=c.clsx(l,"table-column",`table-align-${s}`);return e.jsx(n.Column,{className:o,...t,children:({allowsSorting:i,sortDirection:a})=>e.jsx("div",{className:c.clsx("table-column-inner"),children:e.jsxs(e.Fragment,{children:[t.children,i&&e.jsx("span",{"aria-hidden":"true",className:c.clsx("sort-indicator",!a&&"sort-indicator-unsorted"),children:a==="descending"?e.jsx(g.IconChevronDown,{}):e.jsx(f.IconChevronUp,{})})]})})})}function k({className:s,...l}){return e.jsx(n.TableBody,{...l})}function q({className:s,columns:l,children:t,...o}){const{selectionBehavior:i,selectionMode:a,allowsDragging:d}=n.useTableOptions(),r=m.useContext(h),b=c.clsx(s,"table-head");return e.jsxs(n.TableHeader,{className:b,...o,children:[d&&e.jsx(x,{}),i==="toggle"&&e.jsx(x,{className:c.clsx("table-selection-col",r==="radio"&&"table-selection-col--radio"),children:a==="multiple"&&e.jsx(n.Checkbox,{slot:"selection",className:"table-selection-checkbox",children:e.jsx(j.Checkbox,{})})}),e.jsx(n.Collection,{items:l,children:t})]})}function w({id:s,columns:l,children:t,className:o,...i}){const{selectionBehavior:a,allowsDragging:d}=n.useTableOptions(),r=m.useContext(h),b=c.clsx(o,"table-row");return e.jsxs(n.Row,{id:s,...i,className:b,children:[d&&e.jsx(u,{children:e.jsx(n.Button,{slot:"drag",children:"≡"})}),a==="toggle"&&e.jsx(u,{className:c.clsx("table-selection-cell",r==="radio"&&"table-selection-cell--radio"),children:e.jsx(n.Checkbox,{slot:"selection",className:"table-selection-checkbox",children:r==="radio"?e.jsx(p.Radio,{}):e.jsx(j.Checkbox,{})})}),e.jsx(n.Collection,{items:l,children:t})]})}function u({align:s="start",className:l,...t}){const o=c.clsx(l,"table-cell",`table-align-${s}`);return e.jsx(n.Cell,{className:o,...t})}exports.Table=y;exports.TableBody=k;exports.TableCell=u;exports.TableColumn=x;exports.TableHead=q;exports.TableRow=w;
|
|
2
2
|
//# sourceMappingURL=Table.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.cjs","sources":["../../../../../src/ui/primitives/Table/Table.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport { IconChevronDown, IconChevronUp } from \"icons\";\nimport { Checkbox } from \"primitives\";\nimport {\n Button as RACButton,\n Cell as RACCell,\n Checkbox as RACSelectionCheckbox,\n Collection as RACCollection,\n Column as RACColumn,\n Row as RACRow,\n Table as RACTable,\n TableBody as RACTableBody,\n TableHeader as RACTableHeader,\n useTableOptions,\n type CellProps as RACCellProps,\n type ColumnProps as RACColumnProps,\n type RowProps as RACRowProps,\n type TableBodyProps as RACTableBodyProps,\n type TableHeaderProps as RACTableHeaderProps,\n type TableProps as RACTableProps,\n} from \"react-aria-components\";\nimport \"./table.css\";\n\ntype TableAlign = \"start\" | \"center\" | \"right\";\n\nexport type TableProps = RACTableProps & {\n bleed?: boolean;\n dense?: boolean;\n grid?: boolean;\n striped?: boolean;\n};\nexport function Table({\n bleed = false,\n dense = false,\n grid = false,\n striped = false,\n className,\n ...props\n}: TableProps) {\n const containerClassNames = clsx(\n className,\n \"table-container\",\n bleed && \"table-container-bleed\",\n );\n const tableClassNames = clsx(\n \"sds-table\",\n bleed && \"table-bleed\",\n dense && \"table-dense\",\n grid && \"table-grid\",\n striped && \"sds-table-striped\",\n );\n return (\n <div className={containerClassNames}>\n <RACTable className={tableClassNames} {...props} />\n </div>\n );\n}\n\nexport type TableColumnProps = RACColumnProps & {\n align?: TableAlign;\n};\nexport function TableColumn({\n align = \"start\",\n className,\n ...props\n}: TableColumnProps) {\n const classNames = clsx(className, \"table-column\", `table-align-${align}`);\n return (\n <RACColumn className={classNames} {...props}>\n {({ allowsSorting, sortDirection }) => (\n <div className={clsx(\"table-column-inner\")}>\n <>\n {props.children}\n {allowsSorting && (\n <span aria-hidden=\"true\" className=\"sort-indicator\">\n {sortDirection === \"ascending\" ? (\n <IconChevronUp />\n ) : (\n <IconChevronDown />\n )}\n </span>\n )}\n </>\n </div>\n )}\n </RACColumn>\n );\n}\n\nexport type TableBodyProps<T> = RACTableBodyProps<T>;\nexport function TableBody<T extends object>({\n className,\n ...props\n}: TableBodyProps<T>) {\n return <RACTableBody {...props} />;\n}\n\nexport type TableHeadProps<T> = RACTableHeaderProps<T>;\nexport function TableHead<T extends object>({\n className,\n columns,\n children,\n ...props\n}: TableHeadProps<T>) {\n const { selectionBehavior, selectionMode, allowsDragging } =\n useTableOptions();\n const classNames = clsx(className, \"table-head\");\n return (\n <RACTableHeader className={classNames} {...props}>\n {/* Add extra columns for drag and drop and selection. */}\n {allowsDragging && <TableColumn />}\n {selectionBehavior === \"toggle\" && (\n <TableColumn className=\"table-selection-col\">\n {selectionMode === \"multiple\" && (\n <RACSelectionCheckbox slot=\"selection\" className=\"table-selection-checkbox\">\n <Checkbox />\n </RACSelectionCheckbox>\n )}\n </TableColumn>\n )}\n <RACCollection items={columns}>{children}</RACCollection>\n </RACTableHeader>\n );\n}\n\nexport type TableRowProps<T> = RACRowProps<T>;\nexport function TableRow<T extends object>({\n id,\n columns,\n children,\n className,\n ...otherProps\n}: TableRowProps<T>) {\n const { selectionBehavior, allowsDragging } = useTableOptions();\n const classNames = clsx(className, \"table-row\");\n return (\n <RACRow id={id} {...otherProps} className={classNames}>\n {allowsDragging && (\n <TableCell>\n <RACButton slot=\"drag\">≡</RACButton>\n </TableCell>\n )}\n {selectionBehavior === \"toggle\" && (\n <TableCell className=\"table-selection-cell\">\n <RACSelectionCheckbox slot=\"selection\" className=\"table-selection-checkbox\">\n <Checkbox />\n </RACSelectionCheckbox>\n </TableCell>\n )}\n <RACCollection items={columns}>{children}</RACCollection>\n </RACRow>\n );\n}\n\nexport type TableCellProps = RACCellProps & { align?: TableAlign };\nexport function TableCell({\n align = \"start\",\n className,\n ...props\n}: TableCellProps) {\n const classNames = clsx(className, \"table-cell\", `table-align-${align}`);\n return <RACCell className={classNames} {...props} />;\n}\n"],"names":["Table","bleed","dense","grid","striped","className","props","containerClassNames","clsx","tableClassNames","jsx","RACTable","TableColumn","align","classNames","RACColumn","allowsSorting","sortDirection","jsxs","Fragment","IconChevronUp","IconChevronDown","TableBody","RACTableBody","TableHead","columns","children","selectionBehavior","selectionMode","allowsDragging","useTableOptions","RACTableHeader","RACSelectionCheckbox","Checkbox","RACCollection","TableRow","id","otherProps","RACRow","TableCell","RACButton","RACCell"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Table.cjs","sources":["../../../../../src/ui/primitives/Table/Table.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport { IconChevronDown, IconChevronUp } from \"icons\";\nimport { Checkbox, Radio } from \"primitives\";\nimport { createContext, useContext, type CSSProperties } from \"react\";\nimport {\n Button as RACButton,\n Cell as RACCell,\n Checkbox as RACSelectionCheckbox,\n Collection as RACCollection,\n Column as RACColumn,\n Row as RACRow,\n Table as RACTable,\n TableBody as RACTableBody,\n TableHeader as RACTableHeader,\n useTableOptions,\n type CellProps as RACCellProps,\n type ColumnProps as RACColumnProps,\n type RowProps as RACRowProps,\n type TableBodyProps as RACTableBodyProps,\n type TableHeaderProps as RACTableHeaderProps,\n type TableProps as RACTableProps,\n} from \"react-aria-components\";\nimport \"./table.css\";\n\ntype TableAlign = \"start\" | \"center\" | \"right\";\n\n/**\n * Visual style of the built-in selection control rendered in the selection\n * column (header \"select all\" + per-row toggle). \"radio\" is for\n * `selectionMode=\"single\"` tables where a round, single-choice control reads\n * better than a checkbox — the header never renders a control either way\n * (there is no \"select all\" for a single choice).\n */\ntype SelectionType = \"checkbox\" | \"radio\";\nconst SelectionTypeContext = createContext<SelectionType>(\"checkbox\");\n\nfunction toCssLength(value: number | string): string {\n const numericValue = Number(value);\n const isUnitlessNumber =\n `${value}`.trim() !== \"\" && Number.isFinite(numericValue);\n return isUnitlessNumber ? `${numericValue}px` : `${value}`;\n}\n\nexport type TableProps = RACTableProps & {\n bleed?: boolean;\n dense?: boolean;\n grid?: boolean;\n striped?: boolean;\n selectionType?: SelectionType;\n maxHeight?: number | string;\n};\nexport function Table({\n bleed = false,\n dense = false,\n grid = false,\n striped = false,\n selectionType = \"checkbox\",\n maxHeight,\n className,\n ...props\n}: TableProps) {\n const scrollsVertically = maxHeight !== undefined;\n const containerClassNames = clsx(\n className,\n \"table-container\",\n bleed && \"table-container-bleed\",\n scrollsVertically && \"table-container-scrollable\",\n );\n const containerStyle = scrollsVertically\n ? ({ \"--table-max-height\": toCssLength(maxHeight) } as CSSProperties)\n : undefined;\n const tableClassNames = clsx(\n \"sds-table\",\n bleed && \"table-bleed\",\n dense && \"table-dense\",\n grid && \"table-grid\",\n striped && \"sds-table-striped\",\n );\n return (\n <div className={containerClassNames} style={containerStyle}>\n <SelectionTypeContext.Provider value={selectionType}>\n <RACTable className={tableClassNames} {...props} />\n </SelectionTypeContext.Provider>\n </div>\n );\n}\n\nexport type TableColumnProps = RACColumnProps & {\n align?: TableAlign;\n};\nexport function TableColumn({\n align = \"start\",\n className,\n ...props\n}: TableColumnProps) {\n const classNames = clsx(className, \"table-column\", `table-align-${align}`);\n return (\n <RACColumn className={classNames} {...props}>\n {({ allowsSorting, sortDirection }) => (\n <div className={clsx(\"table-column-inner\")}>\n <>\n {props.children}\n {allowsSorting && (\n <span\n aria-hidden=\"true\"\n className={clsx(\n \"sort-indicator\",\n !sortDirection && \"sort-indicator-unsorted\",\n )}\n >\n {sortDirection === \"descending\" ? (\n <IconChevronDown />\n ) : (\n <IconChevronUp />\n )}\n </span>\n )}\n </>\n </div>\n )}\n </RACColumn>\n );\n}\n\nexport type TableBodyProps<T> = RACTableBodyProps<T>;\nexport function TableBody<T extends object>({\n className,\n ...props\n}: TableBodyProps<T>) {\n return <RACTableBody {...props} />;\n}\n\nexport type TableHeadProps<T> = RACTableHeaderProps<T>;\nexport function TableHead<T extends object>({\n className,\n columns,\n children,\n ...props\n}: TableHeadProps<T>) {\n const { selectionBehavior, selectionMode, allowsDragging } =\n useTableOptions();\n const selectionType = useContext(SelectionTypeContext);\n const classNames = clsx(className, \"table-head\");\n return (\n <RACTableHeader className={classNames} {...props}>\n {/* Add extra columns for drag and drop and selection. */}\n {allowsDragging && <TableColumn />}\n {selectionBehavior === \"toggle\" && (\n <TableColumn\n className={clsx(\n \"table-selection-col\",\n selectionType === \"radio\" && \"table-selection-col--radio\",\n )}\n >\n {selectionMode === \"multiple\" && (\n <RACSelectionCheckbox slot=\"selection\" className=\"table-selection-checkbox\">\n <Checkbox />\n </RACSelectionCheckbox>\n )}\n </TableColumn>\n )}\n <RACCollection items={columns}>{children}</RACCollection>\n </RACTableHeader>\n );\n}\n\nexport type TableRowProps<T> = RACRowProps<T>;\nexport function TableRow<T extends object>({\n id,\n columns,\n children,\n className,\n ...otherProps\n}: TableRowProps<T>) {\n const { selectionBehavior, allowsDragging } = useTableOptions();\n const selectionType = useContext(SelectionTypeContext);\n const classNames = clsx(className, \"table-row\");\n return (\n <RACRow id={id} {...otherProps} className={classNames}>\n {allowsDragging && (\n <TableCell>\n <RACButton slot=\"drag\">≡</RACButton>\n </TableCell>\n )}\n {selectionBehavior === \"toggle\" && (\n <TableCell\n className={clsx(\n \"table-selection-cell\",\n selectionType === \"radio\" && \"table-selection-cell--radio\",\n )}\n >\n <RACSelectionCheckbox slot=\"selection\" className=\"table-selection-checkbox\">\n {selectionType === \"radio\" ? <Radio /> : <Checkbox />}\n </RACSelectionCheckbox>\n </TableCell>\n )}\n <RACCollection items={columns}>{children}</RACCollection>\n </RACRow>\n );\n}\n\nexport type TableCellProps = RACCellProps & { align?: TableAlign };\nexport function TableCell({\n align = \"start\",\n className,\n ...props\n}: TableCellProps) {\n const classNames = clsx(className, \"table-cell\", `table-align-${align}`);\n return <RACCell className={classNames} {...props} />;\n}\n"],"names":["SelectionTypeContext","createContext","toCssLength","value","numericValue","Table","bleed","dense","grid","striped","selectionType","maxHeight","className","props","scrollsVertically","containerClassNames","clsx","containerStyle","tableClassNames","RACTable","TableColumn","align","classNames","RACColumn","allowsSorting","sortDirection","jsx","jsxs","Fragment","IconChevronDown","IconChevronUp","TableBody","RACTableBody","TableHead","columns","children","selectionBehavior","selectionMode","allowsDragging","useTableOptions","useContext","RACTableHeader","RACSelectionCheckbox","Checkbox","RACCollection","TableRow","id","otherProps","RACRow","TableCell","RACButton","Radio","RACCell"],"mappings":"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"}
|