@spark-ui/components 17.3.0 → 17.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);const e=require(`../icon-CRPcdgYp.js`),t=require(`../button-B-sMnDc_.js`),n=require(`../checkbox-DjwbAH09.js`);let r=require(`class-variance-authority`),i=require(`react`),a=require(`react/jsx-runtime`),o=require(`react-aria-components`),s=require(`@spark-ui/icons/ArrowUp`),c=require(`@spark-ui/icons/Sort`);var l=`button, [role="button"], [role="switch"], [role="checkbox"], [role="option"], input:not([type="hidden"]), select, textarea, [href]`,u=`[data-resizable-direction]`;function d(e){if(!e||!(e instanceof Element))return!1;let t=e;return t.matches(l)||t.closest(l)!==null}function f(e){return!e||!(e instanceof Element)?!1:e.closest(u)!==null}var p=(0,i.createContext)({isResizable:!1});function m(){return(0,i.useContext)(p)}var h=(0,i.createContext)({selectedCount:0,onClearSelection:()=>{}});function g(){return(0,i.useContext)(h)}function _({className:e,children:t,...n}){let s=(0,i.useRef)(null);return(0,i.useLayoutEffect)(()=>{let e=s.current;if(!e)return;let t=t=>{t.key!==` `&&t.key!==`Enter`||d(t.target)&&e.contains(t.target)&&(f(t.target)||(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),t.target.click()))};return e.addEventListener(`keydown`,t,!0),()=>e.removeEventListener(`keydown`,t,!0)},[]),(0,a.jsx)(p.Provider,{value:{isResizable:!0},children:(0,a.jsx)(o.ResizableTableContainer,{ref:s,"data-spark-component":`resizable-table-container`,className:(0,r.cx)(`relative w-full overflow-auto`,e),...n,children:t})})}_.displayName=`ResizableTableContainer`;function v({children:e,className:t,selectedKeys:n,onSelectionChange:i,totalCount:o,hasMultiplePages:s,onClearSelection:c,onSelectAll:l,allowsResizing:u=!0,maxHeight:d,onResizeStart:f,onResize:p,onResizeEnd:m,onKeyDownCapture:g,sortDescriptor:_,onSortChange:v,...y}){let b=0;n===`all`?b=o??0:n instanceof Set?b=n.size:n&&(b=new Set(n).size);let x=c??(()=>i?.(new Set)),S={...y,selectedKeys:n,onSelectionChange:i,totalCount:o,hasMultiplePages:s,onSelectAll:l,selectedCount:b,onClearSelection:x,allowsResizing:u,maxHeight:d,onResizeStart:f,onResize:p,onResizeEnd:m,onKeyDownCapture:g,sortDescriptor:_,onSortChange:v,className:t};return(0,a.jsx)(h.Provider,{value:S,children:(0,a.jsx)(`div`,{className:(0,r.cx)(`gap-md flex flex-col`,t),children:e})})}v.displayName=`Table`;var y=({className:e,onKeyDownCapture:t,...n})=>{let s=(0,i.useRef)(null);return(0,i.useLayoutEffect)(()=>{let e=s.current;if(!e)return;let t=t=>{t.key!==` `&&t.key!==`Enter`||d(t.target)&&e.contains(t.target)&&(f(t.target)||(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),t.target.click()))};return e.addEventListener(`keydown`,t,!0),()=>e.removeEventListener(`keydown`,t,!0)},[]),(0,a.jsx)(o.Table,{ref:s,"data-spark-component":`table`,className:(0,r.cx)(`default:w-full`,`border-separate border-spacing-y-0`,`bg-surface`,`outline-none`,`text-body-1`,`forced-color-adjust-none`,`data-focus-visible:u-outline-inset`,`has-[>[data-empty]]:h-full`,e),...t?{...n,onKeyDownCapture:t}:n})};y.displayName=`Table.Grid.Inner`;function b(e){return typeof e==`number`?`${e}px`:e}function x({"aria-label":e,"aria-labelledby":t,className:n,children:r}){let{allowsResizing:i=!0,maxHeight:o,onResizeStart:s,onResize:c,onResizeEnd:l,onKeyDownCapture:u,sortDescriptor:d,onSortChange:f,className:p,...m}=g(),h=o==null?void 0:{maxHeight:b(o)},v=n??p,x={...m,...e!=null&&{"aria-label":e},...t!=null&&{"aria-labelledby":t},sortDescriptor:d,onSortChange:f,onKeyDownCapture:u,className:v};return i?(0,a.jsx)(_,{className:v,style:h,onResizeStart:s,onResize:c,onResizeEnd:l,children:(0,a.jsx)(y,{...x,children:r})}):(0,a.jsx)(`div`,{className:`relative w-full overflow-auto`,style:h,children:(0,a.jsx)(y,{...x,children:r})})}x.displayName=`Table.Grid`;var S=(0,r.cva)([`h-sz-64 min-w-sz-64`,`relative group/column first:rounded-l-xl last:rounded-r-xl bg-neutral-container`,`px-lg py-sm text-left outline-none box-border`,`cursor-default`,`data-focus-visible:u-outline data-focus-visible:-outline-offset-2`],{variants:{},defaultVariants:{}});(0,r.cva)([`flex flex-1 justify-between items-center gap-md`,`font-inherit text-left text-inherit`,`whitespace-nowrap text-ellipsis`,`border-transparent`,`data-focus-visible:u-outline data-focus-visible:outline-offset-2`],{variants:{},defaultVariants:{}});var C=(0,r.cva)([`empty:italic empty:text-center empty:text-body-2 empty:py-lg`],{variants:{},defaultVariants:{}}),w=(0,r.cva)([`p-lg outline-none box-border default:overflow-hidden`,`border-b-sm border-outline [tr:last-child>&]:border-b-0`,`[-webkit-tap-highlight-color:transparent]`,`data-focus-visible:u-outline-inset data-focus-visible:outline-dashed`],{variants:{checkbox:{true:[`w-sz-64 py-sm px-0 align-middle`]}},defaultVariants:{checkbox:!1}});(0,r.cva)([`pointer-events-none`,`[&_td]:h-sz-16 [&_td]:p-0 [&_td]:border-0 [&_td]:border-b-0 [&_td]:bg-surface [&_td]:align-middle`],{variants:{},defaultVariants:{}});function T({className:e,renderEmptyState:t,...n}){let i=t==null?void 0:e=>(0,a.jsx)(`div`,{"data-spark-component":`table-empty`,className:`p-lg`,children:t(e)});return(0,a.jsx)(o.TableBody,{"data-spark-component":`table-body`,className:(0,r.cx)(C(),e),renderEmptyState:i,...n})}T.displayName=`Table.Body`;var E=(0,i.createContext)(null);function D(){let e=(0,i.useContext)(E);if(!e)throw Error(`Table.BulkBar subcomponents must be used within Table.BulkBar`);return e}function O({children:e,className:t}){let{selectedCount:n,totalCount:i,onClearSelection:o,onSelectAll:s,hasMultiplePages:c}=g(),l={selectedCount:n,totalCount:i,onClearSelection:o,onSelectAll:s,hasMultiplePages:c};return(0,a.jsx)(E.Provider,{value:l,children:(0,a.jsx)(`div`,{role:`toolbar`,"aria-label":`Table bulk actions`,"data-spark-component":`table-bulk-bar`,className:(0,r.cx)(`gap-lg min-h-sz-64 flex w-full flex-wrap items-center justify-between`,`rounded-lg`,`bg-basic-container text-on-basic-container p-lg`,t),children:e})})}function k({children:e}){return D(),(0,a.jsx)(`span`,{className:`text-body-1 font-bold`,children:e})}function A({className:e,children:n,...i}){let{selectedCount:o,onClearSelection:s,hasMultiplePages:c}=D();return c?(0,a.jsx)(t.t,{size:`sm`,design:`ghost`,intent:`support`,underline:!0,ariaDisabled:o===0,onClick:s,className:(0,r.cx)(`text-body-2`,e),...i,children:n}):null}function j({className:e,children:n,...i}){let{selectedCount:o,totalCount:s,onSelectAll:c,hasMultiplePages:l}=D();return l?(0,a.jsx)(t.t,{size:`sm`,design:`ghost`,intent:`support`,underline:!0,ariaDisabled:s==null||c==null||o>=s,onClick:c,className:(0,r.cx)(`text-body-2`,e),...i,children:n}):null}O.displayName=`Table.BulkBar`;var M=O;M.displayName=`Table.BulkBar`,k.displayName=`Table.BulkBarSelectedCount`,A.displayName=`Table.BulkBarClearButton`,j.displayName=`Table.BulkBarSelectAllButton`;function N({className:e,checkbox:t,onClick:n,onPointerDown:i,...s}){let c=e=>{d(e.target)&&e.stopPropagation()};return(0,a.jsx)(o.Cell,{"data-spark-component":`table-cell`,className:(0,r.cx)(w({checkbox:t}),e),onClick:e=>{c(e),n?.(e)},onPointerDown:e=>{c(e),i?.(e)},...s})}N.displayName=`Table.Cell`;function P({className:t,label:n,children:i,allowsResizing:l=!0,minWidth:u=120,...f}){let{isResizable:p}=m(),h=i;return(0,a.jsx)(o.Column,{"data-spark-component":`table-column`,className:(0,r.cx)(S(),t),minWidth:u,...f,children:(0,o.composeRenderProps)(h,(t,u)=>{let{allowsSorting:m,sortDirection:h}=u,g=e=>{d(e.target)&&e.stopPropagation()};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(o.Group,{role:`presentation`,tabIndex:-1,className:(0,r.cx)(`border-transparent`,`focus-visible:u-outline focus-visible:outline-offset-2`,`gap-sm box-border flex flex-1 items-center`),onClick:g,onPointerDown:g,children:[(0,a.jsxs)(`div`,{className:`gap-md flex min-w-0 shrink items-center`,children:[(0,a.jsx)(`p`,{className:`truncate`,children:n}),i&&(0,a.jsx)(`div`,{className:`inline-flex shrink-0 items-center`,children:typeof t==`function`?t({...u,defaultChildren:void 0}):t})]}),m&&(0,a.jsx)(`span`,{className:`size-sz-32 ml-auto inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full`,children:(0,a.jsx)(e.t,{size:`sm`,className:(0,r.cx)(h===`descending`&&`rotate-180`),children:h?(0,a.jsx)(s.ArrowUp,{}):(0,a.jsx)(c.Sort,{})})})]}),p&&l&&!f.width&&(0,a.jsx)(o.ColumnResizer,{className:(0,r.cx)(`z-raised absolute top-0 right-[-8px]`,`group-last/column:hidden`,`h-full w-[16px] touch-none`,`mx-0 cursor-col-resize`,`data-focus-visible:after:u-outline`,`data-resizing:after:bg-outline-high after:transition-transform after:duration-200 data-resizing:after:scale-125`,`after:h-sz-32 after:bg-outline after:absolute after:top-1/2 after:left-1/2 after:w-[2px] after:-translate-y-1/2`)})]})})})}P.displayName=`Table.Column`;var F=(0,i.forwardRef)(function(e,t){let[r,i]=(0,o.useContextProps)({...e,slot:`selection`},t,o.CheckboxContext),{isSelected:s,isIndeterminate:c,onChange:l,...u}=r;return(0,a.jsx)(`span`,{onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),className:`flex h-full min-h-full items-center justify-center`,children:(0,a.jsx)(n.n,{ref:i,checked:c===!0?`indeterminate`:!!s,onCheckedChange:l,...u})})});F.displayName=`Table.SelectionCheckbox`;function I(){let e=(0,i.useContext)(o.TableStateContext);if(!e)return(0,a.jsx)(F,{});let{collection:t,selectionManager:r}=e,s=r.selectedKeys,c=t,l=c.body,u=l==null?new Set(t.getKeys()):new Set([...c.getChildren(l.key)].map(e=>e.key)),d=s===`all`?u:s,f=[...u].filter(e=>d.has(e)).length,p=u.size;return(0,a.jsx)(`span`,{onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),className:`flex h-full min-h-full items-center justify-center`,children:(0,a.jsx)(n.n,{checked:f>0&&f<p?`indeterminate`:p>0&&f===p,onCheckedChange:()=>{r.toggleSelectAll()}})})}I.displayName=`Table.HeaderSelectionCheckbox`;function L({className:e,columns:t,children:n,sticky:i=!0,...s}){let{selectionBehavior:c,selectionMode:l,allowsDragging:u}=(0,o.useTableOptions)();return(0,a.jsxs)(o.TableHeader,{"data-spark-component":`table-header`,className:(0,r.cx)([i&&`z-raised sticky top-0`,`text-on-neutral-container text-body-1 font-semibold`,`after:pt-md after:block after:size-0`],e),columns:t,...s,children:[u&&(0,a.jsx)(o.Column,{width:20,minWidth:20,className:`w-sz-20 min-w-sz-20 box-border`}),c===`toggle`&&(0,a.jsx)(o.Column,{width:56,minWidth:56,className:(0,r.cx)(S()),children:l===`multiple`&&(0,a.jsx)(I,{})}),t==null?n:(0,a.jsx)(o.Collection,{items:t,children:n})]})}L.displayName=`Table.Header`;function R({id:e,columns:t,children:n,className:i,...s}){let{selectionBehavior:c,allowsDragging:l}=(0,o.useTableOptions)();return(0,a.jsxs)(o.Row,{id:e,"data-spark-component":`table-row`,className:(0,r.cx)(`group/row`,`h-sz-80`,`group/row text-on-surface relative cursor-default select-none`,`[-webkit-tap-highlight-color:transparent]`,`data-focus-visible:u-outline-inset outline-none data-focus-visible:outline-dashed`,`data-react-aria-pressable:hover:bg-surface-hovered data-react-aria-pressable:pressed:bg-surface-hovered`,`data-selected:bg-basic-container data-selected:text-on-basic-container`,`data-selected:hover:bg-basic-container-hovered data-selected:data-pressed:bg-basic-container-hovered`,`data-disabled:text-on-surface/dim-3`,`data-href:cursor-pointer`,i),columns:t,...s,children:[l&&(0,a.jsx)(N,{children:(0,a.jsx)(o.Button,{slot:`drag`,className:`w-sz-15 data-focus-visible:u-outline flex items-center justify-center text-center outline-none data-[focus-visible]:rounded-md`,children:`≡`})}),c===`toggle`&&(0,a.jsx)(N,{checkbox:!0,children:(0,a.jsx)(F,{})}),t==null?n:(0,a.jsx)(o.Collection,{items:t,children:n})]})}R.displayName=`Table.Row`;function z(e,t,n,r){let i=e[n],a=t[n];if(i===a)return 0;let o;return o=typeof i==`number`&&typeof a==`number`?i<a?-1:1:String(i).localeCompare(String(a)),r===`descending`?-o:o}function B(e,t={}){let{initialSort:n,compare:r}=t,[a,o]=(0,i.useState)(()=>n?{column:n.column,direction:n.direction}:{column:`id`,direction:`ascending`});return{sortDescriptor:a,onSortChange:o,setSortDescriptor:o,sortedItems:(0,i.useMemo)(()=>{let t=a.column;if(!t)return[...e];let n=r??z,i=a.direction??`ascending`;return[...e].sort((e,r)=>n(e,r,t,i))},[e,a.column,a.direction,r])}}function V(e,t){let{pageSize:n,initialPage:r=1,getId:a}=t,[o,s]=(0,i.useState)(r),[c,l]=(0,i.useState)(()=>new Set),u=e.length,d=Math.max(1,Math.ceil(u/n));(0,i.useEffect)(()=>{s(e=>e<1?1:e>d?d:e)},[d]);let f=o;f<1?f=1:f>d&&(f=d);let p=(0,i.useMemo)(()=>{let t=(f-1)*n,r=t+n;return e.slice(t,r)},[e,f,n]),m=(0,i.useMemo)(()=>{let t=a??(e=>{let t=e.id;if(t==null)throw Error("useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.");return t});return new Set(e.map(e=>t(e)))},[a,e]),h=(0,i.useMemo)(()=>{let e=a??(e=>{let t=e.id;if(t==null)throw Error("useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.");return t});return new Set(p.map(t=>e(t)))},[a,p]);return{page:f,setPage:s,pageItems:p,totalItems:u,totalPages:d,allKeys:m,selectedKeys:c,onSelectionChange:e=>{let t=e===`all`?new Set(h):new Set(e);l(e=>{let n=new Set(t);for(let t of e)h.has(t)||n.add(t);return n})},onPageChange:e=>{s(e.page)},clearSelection:()=>{l(()=>new Set)}}}var H=Object.assign(v,{Grid:x,Header:L,Column:P,Body:T,Row:R,Cell:N,BulkBar:M,BulkBarSelectedCount:k,BulkBarClearButton:A,BulkBarSelectAllButton:j});H.displayName=`Table`,L.displayName=`Table.Header`,P.displayName=`Table.Column`,T.displayName=`Table.Body`,R.displayName=`Table.Row`,N.displayName=`Table.Cell`,exports.Table=H,exports.TableWithSubcomponents=H,exports.useTablePagination=V,exports.useTableSort=B;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);const e=require(`../icon-CRPcdgYp.js`),t=require(`../button-B-sMnDc_.js`),n=require(`../checkbox-DjwbAH09.js`);let r=require(`class-variance-authority`),i=require(`react`),a=require(`react/jsx-runtime`),o=require(`react-aria-components`),s=require(`@spark-ui/icons/ArrowUp`),c=require(`@spark-ui/icons/Sort`);var l=`button, [role="button"], [role="switch"], [role="checkbox"], [role="option"], input:not([type="hidden"]), select, textarea, [href]`,u=`[data-resizable-direction]`;function d(e){if(!e||!(e instanceof Element))return!1;let t=e;return t.matches(l)||t.closest(l)!==null}function f(e){return!e||!(e instanceof Element)?!1:e.closest(u)!==null}var p=(0,i.createContext)({isResizable:!1});function m(){return(0,i.useContext)(p)}var h=(0,i.createContext)({selectedCount:0,onClearSelection:()=>{}});function g(){return(0,i.useContext)(h)}function _({className:e,children:t,...n}){let s=(0,i.useRef)(null);return(0,i.useLayoutEffect)(()=>{let e=s.current;if(!e)return;let t=t=>{t.key!==` `&&t.key!==`Enter`||d(t.target)&&e.contains(t.target)&&(f(t.target)||(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),t.target.click()))};return e.addEventListener(`keydown`,t,!0),()=>e.removeEventListener(`keydown`,t,!0)},[]),(0,a.jsx)(p.Provider,{value:{isResizable:!0},children:(0,a.jsx)(o.ResizableTableContainer,{ref:s,"data-spark-component":`resizable-table-container`,className:(0,r.cx)(`relative w-full overflow-auto`,e),...n,children:t})})}_.displayName=`ResizableTableContainer`;function v({children:e,className:t,selectedKeys:n,onSelectionChange:i,totalCount:o,hasMultiplePages:s,onClearSelection:c,onSelectAll:l,allowsResizing:u=!0,maxHeight:d,onResizeStart:f,onResize:p,onResizeEnd:m,onKeyDownCapture:g,sortDescriptor:_,onSortChange:v,...y}){let b=0;n===`all`?b=o??0:n instanceof Set?b=n.size:n&&(b=new Set(n).size);let x=c??(()=>i?.(new Set)),S={...y,selectedKeys:n,onSelectionChange:i,totalCount:o,hasMultiplePages:s,onSelectAll:l,selectedCount:b,onClearSelection:x,allowsResizing:u,maxHeight:d,onResizeStart:f,onResize:p,onResizeEnd:m,onKeyDownCapture:g,sortDescriptor:_,onSortChange:v,className:t};return(0,a.jsx)(h.Provider,{value:S,children:(0,a.jsx)(`div`,{className:(0,r.cx)(`gap-md flex flex-col`,t),children:e})})}v.displayName=`Table`;var y=({className:e,onKeyDownCapture:t,...n})=>{let s=(0,i.useRef)(null);return(0,i.useLayoutEffect)(()=>{let e=s.current;if(!e)return;let t=t=>{t.key!==` `&&t.key!==`Enter`||d(t.target)&&e.contains(t.target)&&(f(t.target)||(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),t.target.click()))};return e.addEventListener(`keydown`,t,!0),()=>e.removeEventListener(`keydown`,t,!0)},[]),(0,a.jsx)(o.Table,{ref:s,"data-spark-component":`table`,className:(0,r.cx)(`default:w-full`,`border-separate border-spacing-y-0`,`bg-surface`,`outline-none`,`text-body-1`,`forced-color-adjust-none`,`data-focus-visible:u-outline-inset`,`has-[>[data-empty]]:h-full`,e),...t?{...n,onKeyDownCapture:t}:n})};y.displayName=`Table.Grid.Inner`;function b(e){return typeof e==`number`?`${e}px`:e}function x({"aria-label":e,"aria-labelledby":t,className:n,children:r}){let{allowsResizing:i=!0,maxHeight:o,onResizeStart:s,onResize:c,onResizeEnd:l,onKeyDownCapture:u,sortDescriptor:d,onSortChange:f,className:p,...m}=g(),h=o==null?void 0:{maxHeight:b(o)},v=n??p,x={...m,...e!=null&&{"aria-label":e},...t!=null&&{"aria-labelledby":t},sortDescriptor:d,onSortChange:f,onKeyDownCapture:u,className:v};return i?(0,a.jsx)(_,{className:v,style:h,onResizeStart:s,onResize:c,onResizeEnd:l,children:(0,a.jsx)(y,{...x,children:r})}):(0,a.jsx)(`div`,{className:`relative w-full overflow-auto`,style:h,children:(0,a.jsx)(y,{...x,children:r})})}x.displayName=`Table.Grid`;var S=(0,r.cva)([`h-sz-64 min-w-sz-64`,`relative group/column first:rounded-l-xl last:rounded-r-xl bg-neutral-container`,`px-lg py-sm text-left outline-none box-border`,`cursor-default`,`data-focus-visible:u-outline data-focus-visible:-outline-offset-2`],{variants:{},defaultVariants:{}});(0,r.cva)([`flex flex-1 justify-between items-center gap-md`,`font-inherit text-left text-inherit`,`whitespace-nowrap text-ellipsis`,`border-transparent`,`data-focus-visible:u-outline data-focus-visible:outline-offset-2`],{variants:{},defaultVariants:{}});var C=(0,r.cva)([`empty:italic empty:text-center empty:text-body-2 empty:py-lg`],{variants:{},defaultVariants:{}}),w=(0,r.cva)([`p-lg outline-none box-border default:overflow-hidden`,`border-b-sm border-outline [tr:last-child>&]:border-b-0`,`[-webkit-tap-highlight-color:transparent]`,`data-focus-visible:u-outline-inset data-focus-visible:outline-dashed`],{variants:{checkbox:{true:[`w-sz-64 py-sm px-0 align-middle`]}},defaultVariants:{checkbox:!1}});(0,r.cva)([`pointer-events-none`,`[&_td]:h-sz-16 [&_td]:p-0 [&_td]:border-0 [&_td]:border-b-0 [&_td]:bg-surface [&_td]:align-middle`],{variants:{},defaultVariants:{}});function T({className:e,renderEmptyState:t,...n}){let i=t==null?void 0:e=>(0,a.jsx)(`div`,{"data-spark-component":`table-empty`,className:`p-lg`,children:t(e)});return(0,a.jsx)(o.TableBody,{"data-spark-component":`table-body`,className:(0,r.cx)(C(),e),renderEmptyState:i,...n})}T.displayName=`Table.Body`;var E=(0,i.createContext)(null);function D(){let e=(0,i.useContext)(E);if(!e)throw Error(`Table.BulkBar subcomponents must be used within Table.BulkBar`);return e}function O({children:e,className:t}){let{selectedCount:n,totalCount:i,onClearSelection:o,onSelectAll:s,hasMultiplePages:c}=g(),l={selectedCount:n,totalCount:i,onClearSelection:o,onSelectAll:s,hasMultiplePages:c};return(0,a.jsx)(E.Provider,{value:l,children:(0,a.jsx)(`div`,{role:`toolbar`,"aria-label":`Table bulk actions`,"data-spark-component":`table-bulk-bar`,className:(0,r.cx)(`gap-lg min-h-sz-64 flex w-full flex-wrap items-center justify-between`,`rounded-lg`,`bg-support-container text-on-support-container p-lg`,t),children:e})})}function k({children:e}){return D(),(0,a.jsx)(`span`,{className:`text-body-1 font-bold`,children:e})}function A({className:e,children:n,...i}){let{selectedCount:o,onClearSelection:s,hasMultiplePages:c}=D();return c?(0,a.jsx)(t.t,{size:`sm`,design:`ghost`,intent:`support`,underline:!0,ariaDisabled:o===0,onClick:s,className:(0,r.cx)(`text-body-2`,e),...i,children:n}):null}function j({className:e,children:n,...i}){let{selectedCount:o,totalCount:s,onSelectAll:c,hasMultiplePages:l}=D();return l?(0,a.jsx)(t.t,{size:`sm`,design:`ghost`,intent:`support`,underline:!0,ariaDisabled:s==null||c==null||o>=s,onClick:c,className:(0,r.cx)(`text-body-2`,e),...i,children:n}):null}O.displayName=`Table.BulkBar`;var M=O;M.displayName=`Table.BulkBar`,k.displayName=`Table.BulkBarSelectedCount`,A.displayName=`Table.BulkBarClearButton`,j.displayName=`Table.BulkBarSelectAllButton`;function N({className:e,checkbox:t,onClick:n,onPointerDown:i,...s}){let c=e=>{d(e.target)&&e.stopPropagation()};return(0,a.jsx)(o.Cell,{"data-spark-component":`table-cell`,className:(0,r.cx)(w({checkbox:t}),e),onClick:e=>{c(e),n?.(e)},onPointerDown:e=>{c(e),i?.(e)},...s})}N.displayName=`Table.Cell`;function P({className:t,label:n,children:i,allowsResizing:l=!0,minWidth:u=120,...f}){let{isResizable:p}=m(),h=i;return(0,a.jsx)(o.Column,{"data-spark-component":`table-column`,className:(0,r.cx)(S(),t),minWidth:u,...f,children:(0,o.composeRenderProps)(h,(t,u)=>{let{allowsSorting:m,sortDirection:h}=u,g=e=>{d(e.target)&&e.stopPropagation()};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(o.Group,{role:`presentation`,tabIndex:-1,className:(0,r.cx)(`border-transparent`,`focus-visible:u-outline focus-visible:outline-offset-2`,`gap-sm box-border flex flex-1 items-center`),onClick:g,onPointerDown:g,children:[(0,a.jsxs)(`div`,{className:`gap-md flex min-w-0 shrink items-center`,children:[(0,a.jsx)(`p`,{className:`truncate`,children:n}),i&&(0,a.jsx)(`div`,{className:`inline-flex shrink-0 items-center`,children:typeof t==`function`?t({...u,defaultChildren:void 0}):t})]}),m&&(0,a.jsx)(`span`,{className:`size-sz-32 ml-auto inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full`,children:(0,a.jsx)(e.t,{size:`sm`,className:(0,r.cx)(h===`descending`&&`rotate-180`),children:h?(0,a.jsx)(s.ArrowUp,{}):(0,a.jsx)(c.Sort,{})})})]}),p&&l&&!f.width&&(0,a.jsx)(o.ColumnResizer,{className:(0,r.cx)(`z-raised absolute top-0 right-[-8px]`,`group-last/column:hidden`,`h-full w-[16px] touch-none`,`mx-0 cursor-col-resize`,`data-focus-visible:after:u-outline`,`data-resizing:after:bg-outline-high after:transition-transform after:duration-200 data-resizing:after:scale-125`,`after:h-sz-32 after:bg-outline after:absolute after:top-1/2 after:left-1/2 after:w-[2px] after:-translate-y-1/2`)})]})})})}P.displayName=`Table.Column`;var F=(0,i.forwardRef)(function(e,t){let[r,i]=(0,o.useContextProps)({...e,slot:`selection`},t,o.CheckboxContext),{isSelected:s,isIndeterminate:c,onChange:l,...u}=r;return(0,a.jsx)(`span`,{onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),className:`flex h-full min-h-full items-center justify-center`,children:(0,a.jsx)(n.n,{ref:i,checked:c===!0?`indeterminate`:!!s,onCheckedChange:l,...u})})});F.displayName=`Table.SelectionCheckbox`;function I(){let e=(0,i.useContext)(o.TableStateContext);if(!e)return(0,a.jsx)(F,{});let{collection:t,selectionManager:r}=e,s=r.selectedKeys,c=t,l=c.body,u=l==null?new Set(t.getKeys()):new Set([...c.getChildren(l.key)].map(e=>e.key)),d=s===`all`?u:s,f=[...u].filter(e=>d.has(e)).length,p=u.size;return(0,a.jsx)(`span`,{onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),className:`flex h-full min-h-full items-center justify-center`,children:(0,a.jsx)(n.n,{checked:f>0&&f<p?`indeterminate`:p>0&&f===p,onCheckedChange:()=>{r.toggleSelectAll()}})})}I.displayName=`Table.HeaderSelectionCheckbox`;function L({className:e,columns:t,children:n,sticky:i=!0,...s}){let{selectionBehavior:c,selectionMode:l,allowsDragging:u}=(0,o.useTableOptions)();return(0,a.jsxs)(o.TableHeader,{"data-spark-component":`table-header`,className:(0,r.cx)([i&&`z-raised sticky top-0`,`text-on-neutral-container text-body-1 font-semibold`,`after:pt-md after:block after:size-0`],e),columns:t,...s,children:[u&&(0,a.jsx)(o.Column,{width:20,minWidth:20,className:`w-sz-20 min-w-sz-20 box-border`}),c===`toggle`&&(0,a.jsx)(o.Column,{width:56,minWidth:56,className:(0,r.cx)(S()),children:l===`multiple`&&(0,a.jsx)(I,{})}),t==null?n:(0,a.jsx)(o.Collection,{items:t,children:n})]})}L.displayName=`Table.Header`;function R({id:e,columns:t,children:n,className:i,...s}){let{selectionBehavior:c,allowsDragging:l}=(0,o.useTableOptions)();return(0,a.jsxs)(o.Row,{id:e,"data-spark-component":`table-row`,className:(0,r.cx)(`group/row`,`h-sz-80`,`group/row text-on-surface relative cursor-default select-none`,`[-webkit-tap-highlight-color:transparent]`,`data-focus-visible:u-outline-inset outline-none data-focus-visible:outline-dashed`,`data-react-aria-pressable:hover:bg-surface-hovered data-react-aria-pressable:pressed:bg-surface-hovered`,`data-selected:bg-support-container data-selected:text-on-support-container`,`data-selected:hover:bg-support-container-hovered data-selected:data-pressed:bg-support-container-hovered`,`data-disabled:text-on-surface/dim-3`,`data-href:cursor-pointer`,i),columns:t,...s,children:[l&&(0,a.jsx)(N,{children:(0,a.jsx)(o.Button,{slot:`drag`,className:`w-sz-15 data-focus-visible:u-outline flex items-center justify-center text-center outline-none data-[focus-visible]:rounded-md`,children:`≡`})}),c===`toggle`&&(0,a.jsx)(N,{checkbox:!0,children:(0,a.jsx)(F,{})}),t==null?n:(0,a.jsx)(o.Collection,{items:t,children:n})]})}R.displayName=`Table.Row`;function z(e,t,n,r){let i=e[n],a=t[n];if(i===a)return 0;let o;return o=typeof i==`number`&&typeof a==`number`?i<a?-1:1:String(i).localeCompare(String(a)),r===`descending`?-o:o}function B(e,t={}){let{initialSort:n,compare:r}=t,[a,o]=(0,i.useState)(()=>n?{column:n.column,direction:n.direction}:{column:`id`,direction:`ascending`});return{sortDescriptor:a,onSortChange:o,setSortDescriptor:o,sortedItems:(0,i.useMemo)(()=>{let t=a.column;if(!t)return[...e];let n=r??z,i=a.direction??`ascending`;return[...e].sort((e,r)=>n(e,r,t,i))},[e,a.column,a.direction,r])}}function V(e,t){let{pageSize:n,initialPage:r=1,getId:a}=t,[o,s]=(0,i.useState)(r),[c,l]=(0,i.useState)(()=>new Set),u=e.length,d=Math.max(1,Math.ceil(u/n));(0,i.useEffect)(()=>{s(e=>e<1?1:e>d?d:e)},[d]);let f=o;f<1?f=1:f>d&&(f=d);let p=(0,i.useMemo)(()=>{let t=(f-1)*n,r=t+n;return e.slice(t,r)},[e,f,n]),m=(0,i.useMemo)(()=>{let t=a??(e=>{let t=e.id;if(t==null)throw Error("useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.");return t});return new Set(e.map(e=>t(e)))},[a,e]),h=(0,i.useMemo)(()=>{let e=a??(e=>{let t=e.id;if(t==null)throw Error("useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.");return t});return new Set(p.map(t=>e(t)))},[a,p]);return{page:f,setPage:s,pageItems:p,totalItems:u,totalPages:d,allKeys:m,selectedKeys:c,onSelectionChange:e=>{let t=e===`all`?new Set(h):new Set(e);l(e=>{let n=new Set(t);for(let t of e)h.has(t)||n.add(t);return n})},onPageChange:e=>{s(e.page)},clearSelection:()=>{l(()=>new Set)}}}var H=Object.assign(v,{Grid:x,Header:L,Column:P,Body:T,Row:R,Cell:N,BulkBar:M,BulkBarSelectedCount:k,BulkBarClearButton:A,BulkBarSelectAllButton:j});H.displayName=`Table`,L.displayName=`Table.Header`,P.displayName=`Table.Column`,T.displayName=`Table.Body`,R.displayName=`Table.Row`,N.displayName=`Table.Cell`,exports.Table=H,exports.TableWithSubcomponents=H,exports.useTablePagination=V,exports.useTableSort=B;
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/table/table-utils.ts","../../src/table/TableContext.tsx","../../src/table/ResizableTableContainer.tsx","../../src/table/Table.tsx","../../src/table/Table.styles.tsx","../../src/table/TableBody.tsx","../../src/table/TableBulkBar.tsx","../../src/table/TableCell.tsx","../../src/table/TableColumn.tsx","../../src/table/TableSelectionCheckbox.tsx","../../src/table/TableHeaderSelectionCheckbox.tsx","../../src/table/TableHeader.tsx","../../src/table/TableRow.tsx","../../src/table/useTableSort.ts","../../src/table/useTablePagination.ts","../../src/table/index.ts"],"sourcesContent":["/**\n * Selector for elements that have their own Space/Enter behavior (buttons, switches, inputs, etc.).\n * Used to avoid table row selection capturing these keys when focus is on an interactive cell content.\n */\nconst INTERACTIVE_SELECTOR =\n 'button, [role=\"button\"], [role=\"switch\"], [role=\"checkbox\"], [role=\"option\"], input:not([type=\"hidden\"]), select, textarea, [href]'\n\n/** Column resizer uses a hidden focusable input for keyboard resize (Enter to toggle, ArrowLeft/Right). Don't convert Enter to click there. */\nconst COLUMN_RESIZER_SELECTOR = '[data-resizable-direction]'\n\nexport function isInteractiveElement(element: EventTarget | null): element is Element {\n if (!element || !(element instanceof Element)) return false\n const el = element as Element\n\n return el.matches(INTERACTIVE_SELECTOR) || el.closest(INTERACTIVE_SELECTOR) !== null\n}\n\nexport function isColumnResizerElement(element: EventTarget | null): element is Element {\n if (!element || !(element instanceof Element)) return false\n\n return (element as Element).closest(COLUMN_RESIZER_SELECTOR) !== null\n}\n","import { createContext, useContext } from 'react'\nimport type { Selection } from 'react-aria-components'\nimport type { SortDescriptor } from 'react-aria-components'\n\nimport type { ResizableTableContainerProps } from './ResizableTableContainer'\n\nexport interface TableResizableContextValue {\n isResizable: boolean\n}\n\nexport const TableResizableContext = createContext<TableResizableContextValue>({\n isResizable: false,\n})\n\nexport function useTableResizableContext() {\n return useContext(TableResizableContext)\n}\n\n/** Values provided by Table (root) and consumed by Table.Grid and Table.BulkBar. */\nexport interface TableContextValue\n extends Pick<ResizableTableContainerProps, 'onResizeStart' | 'onResize' | 'onResizeEnd'> {\n // Selection (optional when table has no selection)\n selectionMode?: 'none' | 'single' | 'multiple'\n selectionBehavior?: 'toggle' | 'replace'\n selectedKeys?: Selection\n onSelectionChange?: (keys: Selection) => void\n // BulkBar: optional when not using BulkBar\n totalCount?: number\n hasMultiplePages?: boolean\n onSelectAll?: () => void\n // Derived for BulkBar (from selectedKeys + onSelectionChange)\n selectedCount: number\n onClearSelection: () => void\n // Layout / grid\n allowsResizing?: boolean\n maxHeight?: number | string\n onKeyDownCapture?: React.KeyboardEventHandler<Element>\n sortDescriptor?: SortDescriptor\n onSortChange?: (descriptor: SortDescriptor) => void\n className?: string\n // Pass-through for AriaTable (aria-label, etc.)\n [key: string]: unknown\n}\n\nconst defaultTableContextValue: TableContextValue = {\n selectedCount: 0,\n onClearSelection: () => {},\n}\n\nexport const TableContext = createContext<TableContextValue>(defaultTableContextValue)\n\nexport function useTableContext(): TableContextValue {\n return useContext(TableContext)\n}\n","import { cx } from 'class-variance-authority'\nimport type { ComponentProps } from 'react'\nimport { useLayoutEffect, useRef } from 'react'\nimport { ResizableTableContainer as AriaResizableTableContainer } from 'react-aria-components'\n\nimport { isColumnResizerElement, isInteractiveElement } from './table-utils'\nimport { TableResizableContext } from './TableContext'\n\nexport interface ResizableTableContainerProps\n extends Omit<ComponentProps<typeof AriaResizableTableContainer>, 'className'> {\n className?: string\n}\n\nexport function ResizableTableContainer({\n className,\n children,\n ...props\n}: ResizableTableContainerProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n\n useLayoutEffect(() => {\n const el = containerRef.current\n if (!el) return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== ' ' && e.key !== 'Enter') return\n if (!isInteractiveElement(e.target)) return\n if (!el.contains(e.target as Node)) return\n // Column resizer uses Enter to toggle keyboard resize mode (ArrowLeft/Right to resize). Do not convert to click.\n if (isColumnResizerElement(e.target)) return\n\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n\n // Dispatch a click so the control (Switch, button, etc.) toggles/activates\n // as it would when Space/Enter is pressed natively (browser triggers click)\n const target = e.target as HTMLElement\n target.click()\n }\n\n el.addEventListener('keydown', handleKeyDown, true)\n\n return () => el.removeEventListener('keydown', handleKeyDown, true)\n }, [])\n\n return (\n <TableResizableContext.Provider value={{ isResizable: true }}>\n <AriaResizableTableContainer\n ref={containerRef}\n data-spark-component=\"resizable-table-container\"\n className={cx('relative w-full overflow-auto', className)}\n {...props}\n >\n {children}\n </AriaResizableTableContainer>\n </TableResizableContext.Provider>\n )\n}\n\nResizableTableContainer.displayName = 'ResizableTableContainer'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport { useLayoutEffect, useRef } from 'react'\nimport { Table as AriaTable, type TableProps as AriaTableProps } from 'react-aria-components'\n\nimport type { ResizableTableContainerProps } from './ResizableTableContainer'\nimport { ResizableTableContainer } from './ResizableTableContainer'\nimport { isColumnResizerElement, isInteractiveElement } from './table-utils'\nimport { TableContext, type TableContextValue, useTableContext } from './TableContext'\n\nexport interface TableProps\n extends Omit<AriaTableProps, 'className'>,\n Pick<ResizableTableContainerProps, 'onResizeStart' | 'onResize' | 'onResizeEnd'> {\n className?: string\n onKeyDownCapture?: React.KeyboardEventHandler<Element>\n /** When true (default), columns can be resized. Pass onResizeStart, onResize, onResizeEnd to react to resize events. */\n allowsResizing?: boolean\n /** Max height of the scroll container (number in px or CSS value). Applied so vertical and horizontal scrollbars share the same container. */\n maxHeight?: number | string\n /** For BulkBar: total number of items (e.g. for \"Select all X items\"). */\n totalCount?: number\n /** When true, BulkBar shows \"Clear all\" and \"Select all\" buttons. */\n hasMultiplePages?: boolean\n /**\n * Called when user clicks \"Clear all\" in BulkBar.\n * Useful with pagination selection models (e.g. `useTablePagination`) where clearing only the\n * current page would be incorrect.\n */\n onClearSelection?: () => void\n /** Called when user clicks \"Select all\" in BulkBar. */\n onSelectAll?: () => void\n}\n\nexport interface TableRootWrapperProps extends TableProps {\n children: ReactNode\n}\n\nexport function TableRootWrapper({\n children,\n className,\n selectedKeys,\n onSelectionChange,\n totalCount,\n hasMultiplePages,\n onClearSelection: onClearSelectionProp,\n onSelectAll,\n allowsResizing = true,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n ...restProps\n}: TableRootWrapperProps) {\n let selectedCount = 0\n\n if (selectedKeys === 'all') {\n selectedCount = totalCount ?? 0\n } else if (selectedKeys instanceof Set) {\n selectedCount = selectedKeys.size\n } else if (selectedKeys) {\n selectedCount = new Set(selectedKeys).size\n }\n const onClearSelection = onClearSelectionProp ?? (() => onSelectionChange?.(new Set()))\n\n const contextValue = {\n ...restProps,\n selectedKeys,\n onSelectionChange,\n totalCount,\n hasMultiplePages,\n onSelectAll,\n selectedCount,\n onClearSelection,\n allowsResizing,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n className,\n }\n\n return (\n <TableContext.Provider value={contextValue as TableContextValue}>\n <div className={cx('gap-md flex flex-col', className)}>{children}</div>\n </TableContext.Provider>\n )\n}\n\nTableRootWrapper.displayName = 'Table'\n\nexport const TableRoot = ({ className, onKeyDownCapture, ...props }: TableProps) => {\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // Native capture-phase listener so we run BEFORE react-aria's native listeners\n // (which handle row selection on Space/Enter). Synthetic onKeyDownCapture runs\n // too late. When focus is on an interactive element (switch, button, etc.),\n // we consume the event and trigger a click so the control activates without\n // the row being selected.\n useLayoutEffect(() => {\n const el = wrapperRef.current\n if (!el) return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== ' ' && e.key !== 'Enter') return\n if (!isInteractiveElement(e.target)) return\n if (!el.contains(e.target as Node)) return\n // Column resizer uses Enter to toggle keyboard resize mode (ArrowLeft/Right to resize). Do not convert to click.\n if (isColumnResizerElement(e.target)) return\n\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n ;(e.target as HTMLElement).click()\n }\n\n el.addEventListener('keydown', handleKeyDown, true)\n\n return () => el.removeEventListener('keydown', handleKeyDown, true)\n }, [])\n\n return (\n <AriaTable\n ref={wrapperRef}\n data-spark-component=\"table\"\n className={cx(\n 'default:w-full',\n 'border-separate border-spacing-y-0',\n 'bg-surface',\n 'outline-none',\n 'text-body-1',\n 'forced-color-adjust-none',\n 'data-focus-visible:u-outline-inset',\n 'has-[>[data-empty]]:h-full',\n className\n )}\n {...(onKeyDownCapture ? { ...props, onKeyDownCapture } : props)}\n />\n )\n}\n\nTableRoot.displayName = 'Table.Grid.Inner'\n\nfunction toMaxHeightStyle(value: number | string): React.CSSProperties['maxHeight'] {\n return typeof value === 'number' ? `${value}px` : value\n}\n\nexport interface TableGridProps {\n /** Required for accessibility. */\n 'aria-label'?: string\n 'aria-labelledby'?: string\n className?: string\n children?: ReactNode\n}\n\nexport function TableGrid({\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className: gridClassName,\n children,\n}: TableGridProps) {\n const ctx = useTableContext()\n const {\n allowsResizing = true,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n className: contextClassName,\n ...ariaTableProps\n } = ctx\n\n const scrollContainerStyle =\n maxHeight != null ? { maxHeight: toMaxHeightStyle(maxHeight) } : undefined\n const className = gridClassName ?? contextClassName\n\n const tableRootProps = {\n ...ariaTableProps,\n ...(ariaLabel != null && { 'aria-label': ariaLabel }),\n ...(ariaLabelledBy != null && { 'aria-labelledby': ariaLabelledBy }),\n sortDescriptor,\n onSortChange,\n onKeyDownCapture,\n className,\n }\n\n if (allowsResizing) {\n return (\n <ResizableTableContainer\n className={className}\n style={scrollContainerStyle}\n onResizeStart={onResizeStart}\n onResize={onResize}\n onResizeEnd={onResizeEnd}\n >\n <TableRoot {...tableRootProps}>{children}</TableRoot>\n </ResizableTableContainer>\n )\n }\n\n return (\n <div className=\"relative w-full overflow-auto\" style={scrollContainerStyle}>\n <TableRoot {...tableRootProps}>{children}</TableRoot>\n </div>\n )\n}\n\nTableGrid.displayName = 'Table.Grid'\n","import { cva, type VariantProps } from 'class-variance-authority'\n\nexport const columnStyles = cva(\n [\n 'h-sz-64 min-w-sz-64',\n 'relative group/column first:rounded-l-xl last:rounded-r-xl bg-neutral-container',\n 'px-lg py-sm text-left outline-none box-border',\n 'cursor-default',\n 'data-focus-visible:u-outline data-focus-visible:-outline-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const columnHeaderContentStyles = cva(\n [\n 'flex flex-1 justify-between items-center gap-md',\n 'font-inherit text-left text-inherit',\n 'whitespace-nowrap text-ellipsis',\n 'border-transparent',\n 'data-focus-visible:u-outline data-focus-visible:outline-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const tableBodyStyles = cva(\n ['empty:italic empty:text-center empty:text-body-2 empty:py-lg'],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const cellStyles = cva(\n [\n 'p-lg outline-none box-border default:overflow-hidden',\n 'border-b-sm border-outline [tr:last-child>&]:border-b-0',\n '[-webkit-tap-highlight-color:transparent]',\n 'data-focus-visible:u-outline-inset data-focus-visible:outline-dashed',\n ],\n {\n variants: {\n /** When true, matches width + padding of the TableSelectionCheckbox header column (w-sz-64, py-sm, no horizontal padding). Use cellCheckboxInnerStyles on the inner wrapper to fill height and center content. */\n checkbox: {\n true: ['w-sz-64 py-sm px-0 align-middle'],\n },\n },\n defaultVariants: {\n checkbox: false,\n },\n }\n)\n\n/** Spacer row: 16px (md) visual gap between header and first data row. Use as first child of tbody. */\nexport const tableBodySpacerRowStyles = cva(\n [\n 'pointer-events-none',\n '[&_td]:h-sz-16 [&_td]:p-0 [&_td]:border-0 [&_td]:border-b-0 [&_td]:bg-surface [&_td]:align-middle',\n ],\n { variants: {}, defaultVariants: {} }\n)\n\nexport type ColumnStylesProps = VariantProps<typeof columnStyles>\nexport type CellStylesProps = VariantProps<typeof cellStyles>\n","import { cx } from 'class-variance-authority'\nimport {\n TableBody as AriaTableBody,\n type TableBodyProps as AriaTableBodyProps,\n} from 'react-aria-components'\n\nimport { tableBodyStyles } from './Table.styles'\n\nexport interface TableBodyProps<T extends object = object>\n extends Omit<AriaTableBodyProps<T>, 'className'> {\n className?: string\n}\n\nexport function TableBody<T extends object>({\n className,\n renderEmptyState,\n ...props\n}: TableBodyProps<T>) {\n const wrappedRenderEmptyState: AriaTableBodyProps<T>['renderEmptyState'] =\n renderEmptyState != null\n ? renderProps => (\n <div data-spark-component=\"table-empty\" className=\"p-lg\">\n {renderEmptyState(renderProps)}\n </div>\n )\n : undefined\n\n return (\n <AriaTableBody\n data-spark-component=\"table-body\"\n className={cx(tableBodyStyles(), className)}\n renderEmptyState={wrappedRenderEmptyState}\n {...props}\n />\n )\n}\n\nTableBody.displayName = 'Table.Body'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport { createContext, useContext } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { useTableContext } from './TableContext'\n\ninterface TableBulkBarContextValue {\n selectedCount: number\n totalCount?: number\n onClearSelection: () => void\n onSelectAll?: () => void\n /** When true, \"Clear all\" and \"Select all\" are shown (subject to their own conditions). */\n hasMultiplePages?: boolean\n}\n\nconst TableBulkBarContext = createContext<TableBulkBarContextValue | null>(null)\n\nfunction useTableBulkBarContext() {\n const ctx = useContext(TableBulkBarContext)\n\n if (!ctx) {\n throw new Error('Table.BulkBar subcomponents must be used within Table.BulkBar')\n }\n\n return ctx\n}\n\nexport interface TableBulkBarProps {\n children: ReactNode\n className?: string\n}\n\nfunction TableBulkBarRoot({ children, className }: TableBulkBarProps) {\n const { selectedCount, totalCount, onClearSelection, onSelectAll, hasMultiplePages } =\n useTableContext()\n\n const contextValue: TableBulkBarContextValue = {\n selectedCount,\n totalCount,\n onClearSelection,\n onSelectAll,\n hasMultiplePages,\n }\n\n return (\n <TableBulkBarContext.Provider value={contextValue}>\n <div\n role=\"toolbar\"\n aria-label=\"Table bulk actions\"\n data-spark-component=\"table-bulk-bar\"\n className={cx(\n 'gap-lg min-h-sz-64 flex w-full flex-wrap items-center justify-between',\n 'rounded-lg',\n 'bg-basic-container text-on-basic-container p-lg',\n className\n )}\n >\n {children}\n </div>\n </TableBulkBarContext.Provider>\n )\n}\n\nfunction TableBulkBarSelectedCount({ children }: { children: ReactNode }) {\n useTableBulkBarContext() // enforce usage within BulkBar\n\n return <span className=\"text-body-1 font-bold\">{children}</span>\n}\n\ntype BulkBarButtonProps = Omit<ButtonProps, 'onClick'>\n\nfunction TableBulkBarClearButton({ className, children, ...props }: BulkBarButtonProps) {\n const { selectedCount, onClearSelection, hasMultiplePages } = useTableBulkBarContext()\n\n if (!hasMultiplePages) {\n return null\n }\n\n const ariaDisabled = selectedCount === 0\n\n return (\n <Button\n size=\"sm\"\n design=\"ghost\"\n intent=\"support\"\n underline\n ariaDisabled={ariaDisabled}\n onClick={onClearSelection}\n className={cx('text-body-2', className)}\n {...props}\n >\n {children}\n </Button>\n )\n}\n\nfunction TableBulkBarSelectAllButton({ className, children, ...props }: BulkBarButtonProps) {\n const { selectedCount, totalCount, onSelectAll, hasMultiplePages } = useTableBulkBarContext()\n\n if (!hasMultiplePages) {\n return null\n }\n\n const ariaDisabled = totalCount == null || onSelectAll == null || selectedCount >= totalCount\n\n return (\n <Button\n size=\"sm\"\n design=\"ghost\"\n intent=\"support\"\n underline\n ariaDisabled={ariaDisabled}\n onClick={onSelectAll}\n className={cx('text-body-2', className)}\n {...props}\n >\n {children}\n </Button>\n )\n}\n\nTableBulkBarRoot.displayName = 'Table.BulkBar'\n\nexport const TableBulkBar = TableBulkBarRoot\nTableBulkBar.displayName = 'Table.BulkBar'\n\nexport { TableBulkBarSelectedCount, TableBulkBarClearButton, TableBulkBarSelectAllButton }\nTableBulkBarSelectedCount.displayName = 'Table.BulkBarSelectedCount'\nTableBulkBarClearButton.displayName = 'Table.BulkBarClearButton'\nTableBulkBarSelectAllButton.displayName = 'Table.BulkBarSelectAllButton'\n","import { cx } from 'class-variance-authority'\nimport { Cell as AriaCell, type CellProps as AriaCellProps } from 'react-aria-components'\n\nimport { cellStyles } from './Table.styles'\nimport { isInteractiveElement } from './table-utils'\n\nexport interface CellProps extends Omit<AriaCellProps, 'className'> {\n className?: string\n /** When true, cell uses same width + padding as the TableSelectionCheckbox header column. */\n checkbox?: boolean\n}\n\nexport function Cell({ className, checkbox, onClick, onPointerDown, ...props }: CellProps) {\n const stopIfInteractive = (e: React.MouseEvent | React.PointerEvent) => {\n if (isInteractiveElement(e.target)) e.stopPropagation()\n }\n\n return (\n <AriaCell\n data-spark-component=\"table-cell\"\n className={cx(cellStyles({ checkbox }), className)}\n onClick={e => {\n stopIfInteractive(e)\n onClick?.(e)\n }}\n onPointerDown={e => {\n stopIfInteractive(e)\n onPointerDown?.(e)\n }}\n {...props}\n />\n )\n}\n\nCell.displayName = 'Table.Cell'\n","import { Icon } from '@spark-ui/components/icon'\nimport { ArrowUp } from '@spark-ui/icons/ArrowUp'\nimport { Sort } from '@spark-ui/icons/Sort'\nimport { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Column as AriaColumn,\n type ColumnProps as AriaColumnProps,\n type ColumnRenderProps,\n ColumnResizer,\n composeRenderProps,\n Group,\n} from 'react-aria-components'\n\nimport { columnStyles } from './Table.styles'\nimport { isInteractiveElement } from './table-utils'\nimport { useTableResizableContext } from './TableContext'\n\nexport interface ColumnProps extends Omit<AriaColumnProps, 'className'> {\n className?: string\n children?: AriaColumnProps['children']\n label: string\n /** When false, the column cannot be resized. When true or omitted, the column can be resized when the Table has allowsResizing. */\n allowsResizing?: boolean\n}\n\nexport function Column({\n className,\n label,\n children,\n allowsResizing = true,\n minWidth = 120,\n ...props\n}: ColumnProps) {\n const { isResizable } = useTableResizableContext()\n\n const childrenOrRenderFn = children as\n | ReactNode\n | ((renderProps: ColumnRenderProps & { defaultChildren?: ReactNode }) => ReactNode)\n\n return (\n <AriaColumn\n data-spark-component=\"table-column\"\n className={cx(columnStyles(), className)}\n minWidth={minWidth} // necessary to avoid resizing overlapping visual elements\n {...props}\n >\n {composeRenderProps(childrenOrRenderFn, (content, renderProps) => {\n const { allowsSorting, sortDirection } = renderProps\n\n const stopIfInteractive = (e: React.MouseEvent | React.PointerEvent) => {\n if (isInteractiveElement(e.target)) e.stopPropagation()\n }\n\n return (\n <>\n <Group\n role=\"presentation\"\n tabIndex={-1}\n className={cx(\n 'border-transparent',\n 'focus-visible:u-outline focus-visible:outline-offset-2',\n 'gap-sm box-border flex flex-1 items-center'\n )}\n onClick={stopIfInteractive}\n onPointerDown={stopIfInteractive}\n >\n <div className=\"gap-md flex min-w-0 shrink items-center\">\n <p className=\"truncate\">{label}</p>\n\n {children && (\n <div className=\"inline-flex shrink-0 items-center\">\n {typeof content === 'function'\n ? (\n content as (\n props: ColumnRenderProps & { defaultChildren?: ReactNode }\n ) => ReactNode\n )({ ...renderProps, defaultChildren: undefined })\n : content}\n </div>\n )}\n </div>\n\n {allowsSorting && (\n <span className=\"size-sz-32 ml-auto inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full\">\n <Icon size=\"sm\" className={cx(sortDirection === 'descending' && 'rotate-180')}>\n {sortDirection ? <ArrowUp /> : <Sort />}\n </Icon>\n </span>\n )}\n </Group>\n\n {isResizable && allowsResizing && !props.width && (\n <ColumnResizer\n className={cx(\n 'z-raised absolute top-0 right-[-8px]',\n 'group-last/column:hidden',\n 'h-full w-[16px] touch-none',\n 'mx-0 cursor-col-resize',\n 'data-focus-visible:after:u-outline',\n 'data-resizing:after:bg-outline-high after:transition-transform after:duration-200 data-resizing:after:scale-125',\n 'after:h-sz-32 after:bg-outline after:absolute after:top-1/2 after:left-1/2 after:w-[2px] after:-translate-y-1/2'\n )}\n />\n )}\n </>\n )\n })}\n </AriaColumn>\n )\n}\n\nColumn.displayName = 'Table.Column'\n","import { forwardRef } from 'react'\nimport { CheckboxContext, useContextProps } from 'react-aria-components'\n\nimport { Checkbox } from '../checkbox'\n\n/**\n * Adapter that receives table selection state from React Aria's CheckboxContext\n * and renders Spark Checkbox. Used for row selection and \"select all\" in table header.\n */\nexport const TableSelectionCheckbox = forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof Checkbox>\n>(function TableSelectionCheckbox(props, ref) {\n // Aria's CheckboxContext is typed for HTMLLabelElement; we render Spark Checkbox (button).\n // We only consume context props (isSelected, isIndeterminate, onChange), ref comes from our forwardRef.\n const [mergedProps, mergedRef] = useContextProps(\n { ...props, slot: 'selection' as const },\n ref,\n CheckboxContext as any\n )\n\n const { isSelected, isIndeterminate, onChange, ...rest } = mergedProps as typeof props & {\n isSelected?: boolean\n isIndeterminate?: boolean\n onChange?: (checked: boolean) => void\n }\n\n const checked = isIndeterminate === true ? 'indeterminate' : Boolean(isSelected)\n\n return (\n <span\n onClick={e => e.stopPropagation()}\n onPointerDown={e => e.stopPropagation()}\n className=\"flex h-full min-h-full items-center justify-center\"\n >\n <Checkbox\n ref={mergedRef as React.Ref<HTMLButtonElement>}\n checked={checked}\n onCheckedChange={onChange}\n {...rest}\n />\n </span>\n )\n})\n\nTableSelectionCheckbox.displayName = 'Table.SelectionCheckbox'\n","import type { Key } from '@react-types/shared'\nimport { useContext } from 'react'\nimport { TableStateContext } from 'react-aria-components'\n\nimport { Checkbox } from '../checkbox'\nimport { TableSelectionCheckbox } from './TableSelectionCheckbox'\n\n/**\n * Header \"select all\" checkbox that bases its checked/indeterminate state only\n * on the currently visible (rendered) rows. So when the user changes page in a\n * paginated table, the header shows unchecked instead of indeterminate when no\n * visible row is selected.\n *\n * Renders the Checkbox directly and calls selectionManager.toggleSelectAll() so\n * we fully control the displayed state instead of overriding React Aria's context.\n */\nexport function TableHeaderSelectionCheckbox() {\n const tableState = useContext(TableStateContext)\n\n if (!tableState) {\n return <TableSelectionCheckbox />\n }\n\n const { collection, selectionManager } = tableState\n const selectedKeys = selectionManager.selectedKeys\n\n // Visible row keys: only the body row keys (currently rendered rows).\n // TableCollection has a body node whose children are the rows.\n const collectionWithBody = collection as unknown as {\n body?: { key: Key }\n getChildren: (key: Key) => Iterable<{ key: Key }>\n getKeys: () => IterableIterator<Key>\n }\n const bodyNode = collectionWithBody.body\n const visibleRowKeys =\n bodyNode != null\n ? new Set<Key>([...collectionWithBody.getChildren(bodyNode.key)].map(node => node.key))\n : new Set<Key>(collection.getKeys())\n\n const keysSet = (selectedKeys as unknown) === 'all' ? visibleRowKeys : (selectedKeys as Set<Key>)\n const selectedVisibleCount = [...visibleRowKeys].filter(key => keysSet.has(key)).length\n const visibleCount = visibleRowKeys.size\n\n const isAllSelected = visibleCount > 0 && selectedVisibleCount === visibleCount\n const isIndeterminate = selectedVisibleCount > 0 && selectedVisibleCount < visibleCount\n\n const checked = isIndeterminate ? 'indeterminate' : isAllSelected\n\n return (\n <span\n onClick={e => e.stopPropagation()}\n onPointerDown={e => e.stopPropagation()}\n className=\"flex h-full min-h-full items-center justify-center\"\n >\n <Checkbox\n checked={checked}\n onCheckedChange={() => {\n selectionManager.toggleSelectAll()\n }}\n />\n </span>\n )\n}\n\nTableHeaderSelectionCheckbox.displayName = 'Table.HeaderSelectionCheckbox'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Collection,\n Column as AriaColumn,\n TableHeader as AriaTableHeader,\n type TableHeaderProps as AriaTableHeaderProps,\n useTableOptions,\n} from 'react-aria-components'\n\nimport { columnStyles } from './Table.styles'\nimport { TableHeaderSelectionCheckbox } from './TableHeaderSelectionCheckbox'\n\nexport interface TableHeaderProps<T extends object = object>\n extends Omit<AriaTableHeaderProps<T>, 'className'> {\n className?: string\n /** When true (default), the header row is sticky with z-raised and top-0. */\n sticky?: boolean\n}\n\nexport function TableHeader<T extends object>({\n className,\n columns,\n children,\n sticky = true,\n ...props\n}: TableHeaderProps<T>) {\n const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions()\n\n return (\n <AriaTableHeader\n data-spark-component=\"table-header\"\n className={cx(\n [\n sticky && 'z-raised sticky top-0',\n 'text-on-neutral-container text-body-1 font-semibold',\n 'after:pt-md after:block after:size-0',\n ],\n className\n )}\n columns={columns}\n {...props}\n >\n {allowsDragging && (\n <AriaColumn width={20} minWidth={20} className=\"w-sz-20 min-w-sz-20 box-border\" />\n )}\n {selectionBehavior === 'toggle' && (\n <AriaColumn width={56} minWidth={56} className={cx(columnStyles())}>\n {selectionMode === 'multiple' && <TableHeaderSelectionCheckbox />}\n </AriaColumn>\n )}\n {columns != null ? (\n <Collection items={columns}>{children}</Collection>\n ) : (\n (children as ReactNode)\n )}\n </AriaTableHeader>\n )\n}\n\nTableHeader.displayName = 'Table.Header'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Button,\n Collection,\n Row as AriaRow,\n type RowProps as AriaRowProps,\n useTableOptions,\n} from 'react-aria-components'\n\nimport { Cell } from './TableCell'\nimport { TableSelectionCheckbox } from './TableSelectionCheckbox'\n\nexport interface RowProps<T extends object = object> extends Omit<AriaRowProps<T>, 'className'> {\n className?: string\n}\n\nexport function Row<T extends object>({ id, columns, children, className, ...props }: RowProps<T>) {\n const { selectionBehavior, allowsDragging } = useTableOptions()\n\n return (\n <AriaRow\n id={id}\n data-spark-component=\"table-row\"\n className={cx(\n 'group/row',\n 'h-sz-80', // first row: 96px so 16px gap (border-t) + 80px content\n 'group/row text-on-surface relative cursor-default select-none',\n '[-webkit-tap-highlight-color:transparent]',\n 'data-focus-visible:u-outline-inset outline-none data-focus-visible:outline-dashed',\n 'data-react-aria-pressable:hover:bg-surface-hovered data-react-aria-pressable:pressed:bg-surface-hovered',\n // Selected row styles\n 'data-selected:bg-basic-container data-selected:text-on-basic-container',\n 'data-selected:hover:bg-basic-container-hovered data-selected:data-pressed:bg-basic-container-hovered',\n // Disabled row styles\n 'data-disabled:text-on-surface/dim-3',\n // Href row styles\n 'data-href:cursor-pointer',\n className\n )}\n columns={columns}\n {...props}\n >\n {allowsDragging && (\n <Cell>\n <Button\n slot=\"drag\"\n className=\"w-sz-15 data-focus-visible:u-outline flex items-center justify-center text-center outline-none data-[focus-visible]:rounded-md\"\n >\n ≡\n </Button>\n </Cell>\n )}\n {selectionBehavior === 'toggle' && (\n <Cell checkbox>\n <TableSelectionCheckbox />\n </Cell>\n )}\n {columns != null ? (\n <Collection items={columns}>{children}</Collection>\n ) : (\n (children as ReactNode)\n )}\n </AriaRow>\n )\n}\n\nRow.displayName = 'Table.Row'\n","import { useMemo, useState } from 'react'\nimport type { SortDescriptor } from 'react-aria-components'\n\nexport interface UseTableSortOptions<T extends object> {\n /** Initial sort column and direction. */\n initialSort?: {\n column: keyof T\n direction: 'ascending' | 'descending'\n }\n /**\n * Custom compare function. If not provided, a default comparator is used:\n * - numbers: numeric comparison\n * - other: localeCompare on string representation\n */\n compare?: (a: T, b: T, column: keyof T, direction: 'ascending' | 'descending') => number\n}\n\nfunction defaultCompare<T extends object>(\n a: T,\n b: T,\n column: keyof T,\n direction: 'ascending' | 'descending'\n): number {\n const aVal = a[column]\n const bVal = b[column]\n\n if (aVal === bVal) return 0\n\n let comparisonResult: number\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparisonResult = aVal < bVal ? -1 : 1\n } else {\n comparisonResult = String(aVal).localeCompare(String(bVal))\n }\n\n return direction === 'descending' ? -comparisonResult : comparisonResult\n}\n\n/**\n * Hook to manage table sort state and derive sorted items from a list.\n * Use with Table's sortDescriptor and onSortChange props.\n *\n * @example\n * const { sortDescriptor, onSortChange, setSortDescriptor, sortedItems } = useTableSort(rows, {\n * initialSort: { column: 'name', direction: 'ascending' },\n * })\n * return (\n * <>\n * <Button onClick={() => setSortDescriptor({ column: 'name', direction: 'ascending' })}>Reset sort</Button>\n * <Table sortDescriptor={sortDescriptor} onSortChange={onSortChange}>\n * ...\n * </Table>\n * </>\n * )\n */\nexport function useTableSort<T extends object>(\n items: T[],\n options: UseTableSortOptions<T> = {}\n): {\n sortDescriptor: SortDescriptor\n onSortChange: (descriptor: SortDescriptor) => void\n /** Set sort from outside the table (e.g. a \"Reset sort\" button). */\n setSortDescriptor: (descriptor: SortDescriptor) => void\n sortedItems: T[]\n} {\n const { initialSort, compare } = options\n\n const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>(() =>\n initialSort\n ? { column: initialSort.column as string, direction: initialSort.direction }\n : { column: 'id', direction: 'ascending' }\n )\n\n const sortedItems = useMemo(() => {\n const column = sortDescriptor.column as keyof T\n if (!column) return [...items]\n\n const compareFn = compare ?? defaultCompare\n const direction = sortDescriptor.direction ?? 'ascending'\n\n return [...items].sort((a, b) => compareFn(a, b, column, direction))\n }, [items, sortDescriptor.column, sortDescriptor.direction, compare])\n\n return {\n sortDescriptor,\n onSortChange: setSortDescriptor,\n setSortDescriptor,\n sortedItems,\n }\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { Key, Selection } from 'react-aria-components'\n\nexport interface UseTablePaginationOptions<T> {\n /** Number of items per page. */\n pageSize: number\n /** Initial page index (1-based). Defaults to 1. */\n initialPage?: number\n /**\n * Function to extract a stable key from each item.\n * Defaults to `item.id` if present.\n */\n getId?: (item: T) => Key\n}\n\nexport interface UseTablePaginationResult<T> {\n /** Current page (1-based). */\n page: number\n /** Update the current page manually. */\n setPage: (page: number) => void\n /** Items sliced to the current page. */\n pageItems: T[]\n /** Total number of items. */\n totalItems: number\n /** Total number of pages (at least 1). */\n totalPages: number\n /** All item keys across all pages. */\n allKeys: Set<Key>\n /**\n * Selection state across all pages.\n * Pass to Table (root) as `selectedKeys`.\n */\n selectedKeys: Set<Key>\n /**\n * Selection change handler that keeps selection across pages.\n * Pass to Table (root) as `onSelectionChange`.\n */\n onSelectionChange: (keys: Selection) => void\n /**\n * Convenience handler matching Pagination's `onPageChange` signature:\n * `onPageChange={({ page }) => ...}`.\n */\n onPageChange: (details: { page: number }) => void\n /** Clear selection across all pages. */\n clearSelection: () => void\n}\n\n/**\n * Hook to manage simple client-side pagination and multi-page selection for Table.\n * It slices the full item list to the current page, tracks page state, and merges\n * selection across pages so that rows selected on previous pages remain selected.\n *\n * @example\n * const { page, pageItems, totalItems, allKeys, selectedKeys, onSelectionChange, onPageChange } =\n * useTablePagination(allItems, { pageSize: 10 })\n *\n * return (\n * <Table\n * selectionMode=\"multiple\"\n * selectedKeys={selectedKeys}\n * onSelectionChange={onSelectionChange}\n * totalCount={totalItems}\n * hasMultiplePages={totalItems > 10}\n * onSelectAll={() => onSelectionChange(allKeys)}\n * >\n * <Table.BulkBar>...</Table.BulkBar>\n * <Table.Grid aria-label=\"Items\">\n * <Table.Body>\n * {pageItems.map(item => (\n * <Table.Row key={item.id} id={item.id}>...</Table.Row>\n * ))}\n * </Table.Body>\n * </Table.Grid>\n * <Pagination page={page} pageSize={10} count={totalItems} onPageChange={onPageChange} />\n * </Table>\n * )\n */\nexport function useTablePagination<T>(\n items: T[],\n options: UseTablePaginationOptions<T>\n): UseTablePaginationResult<T> {\n const { pageSize, initialPage = 1, getId } = options\n\n const [page, setPage] = useState(initialPage)\n const [selectedKeys, setSelectedKeys] = useState<Set<Key>>(() => new Set())\n\n const totalItems = items.length\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize))\n\n // Clamp current page when the total page count changes (e.g. items length shrinks).\n useEffect(() => {\n setPage(current => {\n if (current < 1) return 1\n if (current > totalPages) return totalPages\n\n return current\n })\n }, [totalPages])\n\n let effectivePage = page\n if (effectivePage < 1) {\n effectivePage = 1\n } else if (effectivePage > totalPages) {\n effectivePage = totalPages\n }\n\n const pageItems = useMemo(() => {\n const start = (effectivePage - 1) * pageSize\n const end = start + pageSize\n\n return items.slice(start, end)\n }, [items, effectivePage, pageSize])\n\n const allKeys = useMemo(() => {\n const resolveId =\n getId ??\n ((item: T) => {\n const candidate = (item as unknown as { id?: Key }).id\n\n if (candidate == null) {\n throw new Error(\n 'useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.'\n )\n }\n\n return candidate\n })\n\n return new Set<Key>(items.map(item => resolveId(item)))\n }, [getId, items])\n\n const pageIds = useMemo(() => {\n const resolveId =\n getId ??\n ((item: T) => {\n const candidate = (item as unknown as { id?: Key }).id\n\n if (candidate == null) {\n throw new Error(\n 'useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.'\n )\n }\n\n return candidate\n })\n\n return new Set<Key>(pageItems.map(item => resolveId(item)))\n }, [getId, pageItems])\n\n const handleSelectionChange = (keys: Selection) => {\n // React Aria uses \"all\" to represent \"select all\" in the current context.\n // For the table header checkbox, interpret \"all\" as \"all items on the current page\".\n const newPageSelection = keys === 'all' ? new Set<Key>(pageIds) : new Set(keys as Set<Key>)\n\n setSelectedKeys(prev => {\n const next = new Set<Key>(newPageSelection)\n\n // Keep selections from other pages.\n for (const key of prev) {\n if (!pageIds.has(key)) {\n next.add(key)\n }\n }\n\n return next\n })\n }\n\n const handlePageChange = (details: { page: number }) => {\n setPage(details.page)\n }\n\n const clearSelection = () => {\n setSelectedKeys(() => new Set())\n }\n\n return {\n page: effectivePage,\n setPage,\n pageItems,\n totalItems,\n totalPages,\n allKeys,\n selectedKeys,\n onSelectionChange: handleSelectionChange,\n onPageChange: handlePageChange,\n clearSelection,\n }\n}\n","import { TableGrid, TableRootWrapper } from './Table'\nimport { TableBody } from './TableBody'\nimport {\n TableBulkBar,\n TableBulkBarClearButton,\n TableBulkBarSelectAllButton,\n TableBulkBarSelectedCount,\n} from './TableBulkBar'\nimport { Cell } from './TableCell'\nimport { Column } from './TableColumn'\nimport { TableHeader } from './TableHeader'\nimport { Row } from './TableRow'\n\nexport const TableWithSubcomponents: typeof TableRootWrapper & {\n Grid: typeof TableGrid\n Header: typeof TableHeader\n Column: typeof Column\n Body: typeof TableBody\n Row: typeof Row\n Cell: typeof Cell\n BulkBar: typeof TableBulkBar\n BulkBarSelectedCount: typeof TableBulkBarSelectedCount\n BulkBarClearButton: typeof TableBulkBarClearButton\n BulkBarSelectAllButton: typeof TableBulkBarSelectAllButton\n} = Object.assign(TableRootWrapper, {\n Grid: TableGrid,\n Header: TableHeader,\n Column,\n Body: TableBody,\n Row,\n Cell,\n BulkBar: TableBulkBar,\n BulkBarSelectedCount: TableBulkBarSelectedCount,\n BulkBarClearButton: TableBulkBarClearButton,\n BulkBarSelectAllButton: TableBulkBarSelectAllButton,\n})\n\nTableWithSubcomponents.displayName = 'Table'\nTableHeader.displayName = 'Table.Header'\nColumn.displayName = 'Table.Column'\nTableBody.displayName = 'Table.Body'\nRow.displayName = 'Table.Row'\nCell.displayName = 'Table.Cell'\n\nexport { TableWithSubcomponents as Table }\n\nexport { useTableSort } from './useTableSort'\nexport { useTablePagination } from './useTablePagination'\nexport type { SortDescriptor } from 'react-aria-components'\nexport type { UseTableSortOptions } from './useTableSort'\nexport type { UseTablePaginationOptions, UseTablePaginationResult } from './useTablePagination'\nexport { type TableGridProps, type TableProps, type TableRootWrapperProps } from './Table'\nexport { type TableHeaderProps } from './TableHeader'\nexport { type ColumnProps } from './TableColumn'\nexport { type TableBodyProps } from './TableBody'\nexport { type RowProps } from './TableRow'\nexport { type CellProps } from './TableCell'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/table/table-utils.ts","../../src/table/TableContext.tsx","../../src/table/ResizableTableContainer.tsx","../../src/table/Table.tsx","../../src/table/Table.styles.tsx","../../src/table/TableBody.tsx","../../src/table/TableBulkBar.tsx","../../src/table/TableCell.tsx","../../src/table/TableColumn.tsx","../../src/table/TableSelectionCheckbox.tsx","../../src/table/TableHeaderSelectionCheckbox.tsx","../../src/table/TableHeader.tsx","../../src/table/TableRow.tsx","../../src/table/useTableSort.ts","../../src/table/useTablePagination.ts","../../src/table/index.ts"],"sourcesContent":["/**\n * Selector for elements that have their own Space/Enter behavior (buttons, switches, inputs, etc.).\n * Used to avoid table row selection capturing these keys when focus is on an interactive cell content.\n */\nconst INTERACTIVE_SELECTOR =\n 'button, [role=\"button\"], [role=\"switch\"], [role=\"checkbox\"], [role=\"option\"], input:not([type=\"hidden\"]), select, textarea, [href]'\n\n/** Column resizer uses a hidden focusable input for keyboard resize (Enter to toggle, ArrowLeft/Right). Don't convert Enter to click there. */\nconst COLUMN_RESIZER_SELECTOR = '[data-resizable-direction]'\n\nexport function isInteractiveElement(element: EventTarget | null): element is Element {\n if (!element || !(element instanceof Element)) return false\n const el = element as Element\n\n return el.matches(INTERACTIVE_SELECTOR) || el.closest(INTERACTIVE_SELECTOR) !== null\n}\n\nexport function isColumnResizerElement(element: EventTarget | null): element is Element {\n if (!element || !(element instanceof Element)) return false\n\n return (element as Element).closest(COLUMN_RESIZER_SELECTOR) !== null\n}\n","import { createContext, useContext } from 'react'\nimport type { Selection } from 'react-aria-components'\nimport type { SortDescriptor } from 'react-aria-components'\n\nimport type { ResizableTableContainerProps } from './ResizableTableContainer'\n\nexport interface TableResizableContextValue {\n isResizable: boolean\n}\n\nexport const TableResizableContext = createContext<TableResizableContextValue>({\n isResizable: false,\n})\n\nexport function useTableResizableContext() {\n return useContext(TableResizableContext)\n}\n\n/** Values provided by Table (root) and consumed by Table.Grid and Table.BulkBar. */\nexport interface TableContextValue\n extends Pick<ResizableTableContainerProps, 'onResizeStart' | 'onResize' | 'onResizeEnd'> {\n // Selection (optional when table has no selection)\n selectionMode?: 'none' | 'single' | 'multiple'\n selectionBehavior?: 'toggle' | 'replace'\n selectedKeys?: Selection\n onSelectionChange?: (keys: Selection) => void\n // BulkBar: optional when not using BulkBar\n totalCount?: number\n hasMultiplePages?: boolean\n onSelectAll?: () => void\n // Derived for BulkBar (from selectedKeys + onSelectionChange)\n selectedCount: number\n onClearSelection: () => void\n // Layout / grid\n allowsResizing?: boolean\n maxHeight?: number | string\n onKeyDownCapture?: React.KeyboardEventHandler<Element>\n sortDescriptor?: SortDescriptor\n onSortChange?: (descriptor: SortDescriptor) => void\n className?: string\n // Pass-through for AriaTable (aria-label, etc.)\n [key: string]: unknown\n}\n\nconst defaultTableContextValue: TableContextValue = {\n selectedCount: 0,\n onClearSelection: () => {},\n}\n\nexport const TableContext = createContext<TableContextValue>(defaultTableContextValue)\n\nexport function useTableContext(): TableContextValue {\n return useContext(TableContext)\n}\n","import { cx } from 'class-variance-authority'\nimport type { ComponentProps } from 'react'\nimport { useLayoutEffect, useRef } from 'react'\nimport { ResizableTableContainer as AriaResizableTableContainer } from 'react-aria-components'\n\nimport { isColumnResizerElement, isInteractiveElement } from './table-utils'\nimport { TableResizableContext } from './TableContext'\n\nexport interface ResizableTableContainerProps\n extends Omit<ComponentProps<typeof AriaResizableTableContainer>, 'className'> {\n className?: string\n}\n\nexport function ResizableTableContainer({\n className,\n children,\n ...props\n}: ResizableTableContainerProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n\n useLayoutEffect(() => {\n const el = containerRef.current\n if (!el) return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== ' ' && e.key !== 'Enter') return\n if (!isInteractiveElement(e.target)) return\n if (!el.contains(e.target as Node)) return\n // Column resizer uses Enter to toggle keyboard resize mode (ArrowLeft/Right to resize). Do not convert to click.\n if (isColumnResizerElement(e.target)) return\n\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n\n // Dispatch a click so the control (Switch, button, etc.) toggles/activates\n // as it would when Space/Enter is pressed natively (browser triggers click)\n const target = e.target as HTMLElement\n target.click()\n }\n\n el.addEventListener('keydown', handleKeyDown, true)\n\n return () => el.removeEventListener('keydown', handleKeyDown, true)\n }, [])\n\n return (\n <TableResizableContext.Provider value={{ isResizable: true }}>\n <AriaResizableTableContainer\n ref={containerRef}\n data-spark-component=\"resizable-table-container\"\n className={cx('relative w-full overflow-auto', className)}\n {...props}\n >\n {children}\n </AriaResizableTableContainer>\n </TableResizableContext.Provider>\n )\n}\n\nResizableTableContainer.displayName = 'ResizableTableContainer'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport { useLayoutEffect, useRef } from 'react'\nimport { Table as AriaTable, type TableProps as AriaTableProps } from 'react-aria-components'\n\nimport type { ResizableTableContainerProps } from './ResizableTableContainer'\nimport { ResizableTableContainer } from './ResizableTableContainer'\nimport { isColumnResizerElement, isInteractiveElement } from './table-utils'\nimport { TableContext, type TableContextValue, useTableContext } from './TableContext'\n\nexport interface TableProps\n extends Omit<AriaTableProps, 'className'>,\n Pick<ResizableTableContainerProps, 'onResizeStart' | 'onResize' | 'onResizeEnd'> {\n className?: string\n onKeyDownCapture?: React.KeyboardEventHandler<Element>\n /** When true (default), columns can be resized. Pass onResizeStart, onResize, onResizeEnd to react to resize events. */\n allowsResizing?: boolean\n /** Max height of the scroll container (number in px or CSS value). Applied so vertical and horizontal scrollbars share the same container. */\n maxHeight?: number | string\n /** For BulkBar: total number of items (e.g. for \"Select all X items\"). */\n totalCount?: number\n /** When true, BulkBar shows \"Clear all\" and \"Select all\" buttons. */\n hasMultiplePages?: boolean\n /**\n * Called when user clicks \"Clear all\" in BulkBar.\n * Useful with pagination selection models (e.g. `useTablePagination`) where clearing only the\n * current page would be incorrect.\n */\n onClearSelection?: () => void\n /** Called when user clicks \"Select all\" in BulkBar. */\n onSelectAll?: () => void\n}\n\nexport interface TableRootWrapperProps extends TableProps {\n children: ReactNode\n}\n\nexport function TableRootWrapper({\n children,\n className,\n selectedKeys,\n onSelectionChange,\n totalCount,\n hasMultiplePages,\n onClearSelection: onClearSelectionProp,\n onSelectAll,\n allowsResizing = true,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n ...restProps\n}: TableRootWrapperProps) {\n let selectedCount = 0\n\n if (selectedKeys === 'all') {\n selectedCount = totalCount ?? 0\n } else if (selectedKeys instanceof Set) {\n selectedCount = selectedKeys.size\n } else if (selectedKeys) {\n selectedCount = new Set(selectedKeys).size\n }\n const onClearSelection = onClearSelectionProp ?? (() => onSelectionChange?.(new Set()))\n\n const contextValue = {\n ...restProps,\n selectedKeys,\n onSelectionChange,\n totalCount,\n hasMultiplePages,\n onSelectAll,\n selectedCount,\n onClearSelection,\n allowsResizing,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n className,\n }\n\n return (\n <TableContext.Provider value={contextValue as TableContextValue}>\n <div className={cx('gap-md flex flex-col', className)}>{children}</div>\n </TableContext.Provider>\n )\n}\n\nTableRootWrapper.displayName = 'Table'\n\nexport const TableRoot = ({ className, onKeyDownCapture, ...props }: TableProps) => {\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // Native capture-phase listener so we run BEFORE react-aria's native listeners\n // (which handle row selection on Space/Enter). Synthetic onKeyDownCapture runs\n // too late. When focus is on an interactive element (switch, button, etc.),\n // we consume the event and trigger a click so the control activates without\n // the row being selected.\n useLayoutEffect(() => {\n const el = wrapperRef.current\n if (!el) return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== ' ' && e.key !== 'Enter') return\n if (!isInteractiveElement(e.target)) return\n if (!el.contains(e.target as Node)) return\n // Column resizer uses Enter to toggle keyboard resize mode (ArrowLeft/Right to resize). Do not convert to click.\n if (isColumnResizerElement(e.target)) return\n\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n ;(e.target as HTMLElement).click()\n }\n\n el.addEventListener('keydown', handleKeyDown, true)\n\n return () => el.removeEventListener('keydown', handleKeyDown, true)\n }, [])\n\n return (\n <AriaTable\n ref={wrapperRef}\n data-spark-component=\"table\"\n className={cx(\n 'default:w-full',\n 'border-separate border-spacing-y-0',\n 'bg-surface',\n 'outline-none',\n 'text-body-1',\n 'forced-color-adjust-none',\n 'data-focus-visible:u-outline-inset',\n 'has-[>[data-empty]]:h-full',\n className\n )}\n {...(onKeyDownCapture ? { ...props, onKeyDownCapture } : props)}\n />\n )\n}\n\nTableRoot.displayName = 'Table.Grid.Inner'\n\nfunction toMaxHeightStyle(value: number | string): React.CSSProperties['maxHeight'] {\n return typeof value === 'number' ? `${value}px` : value\n}\n\nexport interface TableGridProps {\n /** Required for accessibility. */\n 'aria-label'?: string\n 'aria-labelledby'?: string\n className?: string\n children?: ReactNode\n}\n\nexport function TableGrid({\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className: gridClassName,\n children,\n}: TableGridProps) {\n const ctx = useTableContext()\n const {\n allowsResizing = true,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n className: contextClassName,\n ...ariaTableProps\n } = ctx\n\n const scrollContainerStyle =\n maxHeight != null ? { maxHeight: toMaxHeightStyle(maxHeight) } : undefined\n const className = gridClassName ?? contextClassName\n\n const tableRootProps = {\n ...ariaTableProps,\n ...(ariaLabel != null && { 'aria-label': ariaLabel }),\n ...(ariaLabelledBy != null && { 'aria-labelledby': ariaLabelledBy }),\n sortDescriptor,\n onSortChange,\n onKeyDownCapture,\n className,\n }\n\n if (allowsResizing) {\n return (\n <ResizableTableContainer\n className={className}\n style={scrollContainerStyle}\n onResizeStart={onResizeStart}\n onResize={onResize}\n onResizeEnd={onResizeEnd}\n >\n <TableRoot {...tableRootProps}>{children}</TableRoot>\n </ResizableTableContainer>\n )\n }\n\n return (\n <div className=\"relative w-full overflow-auto\" style={scrollContainerStyle}>\n <TableRoot {...tableRootProps}>{children}</TableRoot>\n </div>\n )\n}\n\nTableGrid.displayName = 'Table.Grid'\n","import { cva, type VariantProps } from 'class-variance-authority'\n\nexport const columnStyles = cva(\n [\n 'h-sz-64 min-w-sz-64',\n 'relative group/column first:rounded-l-xl last:rounded-r-xl bg-neutral-container',\n 'px-lg py-sm text-left outline-none box-border',\n 'cursor-default',\n 'data-focus-visible:u-outline data-focus-visible:-outline-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const columnHeaderContentStyles = cva(\n [\n 'flex flex-1 justify-between items-center gap-md',\n 'font-inherit text-left text-inherit',\n 'whitespace-nowrap text-ellipsis',\n 'border-transparent',\n 'data-focus-visible:u-outline data-focus-visible:outline-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const tableBodyStyles = cva(\n ['empty:italic empty:text-center empty:text-body-2 empty:py-lg'],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const cellStyles = cva(\n [\n 'p-lg outline-none box-border default:overflow-hidden',\n 'border-b-sm border-outline [tr:last-child>&]:border-b-0',\n '[-webkit-tap-highlight-color:transparent]',\n 'data-focus-visible:u-outline-inset data-focus-visible:outline-dashed',\n ],\n {\n variants: {\n /** When true, matches width + padding of the TableSelectionCheckbox header column (w-sz-64, py-sm, no horizontal padding). Use cellCheckboxInnerStyles on the inner wrapper to fill height and center content. */\n checkbox: {\n true: ['w-sz-64 py-sm px-0 align-middle'],\n },\n },\n defaultVariants: {\n checkbox: false,\n },\n }\n)\n\n/** Spacer row: 16px (md) visual gap between header and first data row. Use as first child of tbody. */\nexport const tableBodySpacerRowStyles = cva(\n [\n 'pointer-events-none',\n '[&_td]:h-sz-16 [&_td]:p-0 [&_td]:border-0 [&_td]:border-b-0 [&_td]:bg-surface [&_td]:align-middle',\n ],\n { variants: {}, defaultVariants: {} }\n)\n\nexport type ColumnStylesProps = VariantProps<typeof columnStyles>\nexport type CellStylesProps = VariantProps<typeof cellStyles>\n","import { cx } from 'class-variance-authority'\nimport {\n TableBody as AriaTableBody,\n type TableBodyProps as AriaTableBodyProps,\n} from 'react-aria-components'\n\nimport { tableBodyStyles } from './Table.styles'\n\nexport interface TableBodyProps<T extends object = object>\n extends Omit<AriaTableBodyProps<T>, 'className'> {\n className?: string\n}\n\nexport function TableBody<T extends object>({\n className,\n renderEmptyState,\n ...props\n}: TableBodyProps<T>) {\n const wrappedRenderEmptyState: AriaTableBodyProps<T>['renderEmptyState'] =\n renderEmptyState != null\n ? renderProps => (\n <div data-spark-component=\"table-empty\" className=\"p-lg\">\n {renderEmptyState(renderProps)}\n </div>\n )\n : undefined\n\n return (\n <AriaTableBody\n data-spark-component=\"table-body\"\n className={cx(tableBodyStyles(), className)}\n renderEmptyState={wrappedRenderEmptyState}\n {...props}\n />\n )\n}\n\nTableBody.displayName = 'Table.Body'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport { createContext, useContext } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { useTableContext } from './TableContext'\n\ninterface TableBulkBarContextValue {\n selectedCount: number\n totalCount?: number\n onClearSelection: () => void\n onSelectAll?: () => void\n /** When true, \"Clear all\" and \"Select all\" are shown (subject to their own conditions). */\n hasMultiplePages?: boolean\n}\n\nconst TableBulkBarContext = createContext<TableBulkBarContextValue | null>(null)\n\nfunction useTableBulkBarContext() {\n const ctx = useContext(TableBulkBarContext)\n\n if (!ctx) {\n throw new Error('Table.BulkBar subcomponents must be used within Table.BulkBar')\n }\n\n return ctx\n}\n\nexport interface TableBulkBarProps {\n children: ReactNode\n className?: string\n}\n\nfunction TableBulkBarRoot({ children, className }: TableBulkBarProps) {\n const { selectedCount, totalCount, onClearSelection, onSelectAll, hasMultiplePages } =\n useTableContext()\n\n const contextValue: TableBulkBarContextValue = {\n selectedCount,\n totalCount,\n onClearSelection,\n onSelectAll,\n hasMultiplePages,\n }\n\n return (\n <TableBulkBarContext.Provider value={contextValue}>\n <div\n role=\"toolbar\"\n aria-label=\"Table bulk actions\"\n data-spark-component=\"table-bulk-bar\"\n className={cx(\n 'gap-lg min-h-sz-64 flex w-full flex-wrap items-center justify-between',\n 'rounded-lg',\n 'bg-support-container text-on-support-container p-lg',\n className\n )}\n >\n {children}\n </div>\n </TableBulkBarContext.Provider>\n )\n}\n\nfunction TableBulkBarSelectedCount({ children }: { children: ReactNode }) {\n useTableBulkBarContext() // enforce usage within BulkBar\n\n return <span className=\"text-body-1 font-bold\">{children}</span>\n}\n\ntype BulkBarButtonProps = Omit<ButtonProps, 'onClick'>\n\nfunction TableBulkBarClearButton({ className, children, ...props }: BulkBarButtonProps) {\n const { selectedCount, onClearSelection, hasMultiplePages } = useTableBulkBarContext()\n\n if (!hasMultiplePages) {\n return null\n }\n\n const ariaDisabled = selectedCount === 0\n\n return (\n <Button\n size=\"sm\"\n design=\"ghost\"\n intent=\"support\"\n underline\n ariaDisabled={ariaDisabled}\n onClick={onClearSelection}\n className={cx('text-body-2', className)}\n {...props}\n >\n {children}\n </Button>\n )\n}\n\nfunction TableBulkBarSelectAllButton({ className, children, ...props }: BulkBarButtonProps) {\n const { selectedCount, totalCount, onSelectAll, hasMultiplePages } = useTableBulkBarContext()\n\n if (!hasMultiplePages) {\n return null\n }\n\n const ariaDisabled = totalCount == null || onSelectAll == null || selectedCount >= totalCount\n\n return (\n <Button\n size=\"sm\"\n design=\"ghost\"\n intent=\"support\"\n underline\n ariaDisabled={ariaDisabled}\n onClick={onSelectAll}\n className={cx('text-body-2', className)}\n {...props}\n >\n {children}\n </Button>\n )\n}\n\nTableBulkBarRoot.displayName = 'Table.BulkBar'\n\nexport const TableBulkBar = TableBulkBarRoot\nTableBulkBar.displayName = 'Table.BulkBar'\n\nexport { TableBulkBarSelectedCount, TableBulkBarClearButton, TableBulkBarSelectAllButton }\nTableBulkBarSelectedCount.displayName = 'Table.BulkBarSelectedCount'\nTableBulkBarClearButton.displayName = 'Table.BulkBarClearButton'\nTableBulkBarSelectAllButton.displayName = 'Table.BulkBarSelectAllButton'\n","import { cx } from 'class-variance-authority'\nimport { Cell as AriaCell, type CellProps as AriaCellProps } from 'react-aria-components'\n\nimport { cellStyles } from './Table.styles'\nimport { isInteractiveElement } from './table-utils'\n\nexport interface CellProps extends Omit<AriaCellProps, 'className'> {\n className?: string\n /** When true, cell uses same width + padding as the TableSelectionCheckbox header column. */\n checkbox?: boolean\n}\n\nexport function Cell({ className, checkbox, onClick, onPointerDown, ...props }: CellProps) {\n const stopIfInteractive = (e: React.MouseEvent | React.PointerEvent) => {\n if (isInteractiveElement(e.target)) e.stopPropagation()\n }\n\n return (\n <AriaCell\n data-spark-component=\"table-cell\"\n className={cx(cellStyles({ checkbox }), className)}\n onClick={e => {\n stopIfInteractive(e)\n onClick?.(e)\n }}\n onPointerDown={e => {\n stopIfInteractive(e)\n onPointerDown?.(e)\n }}\n {...props}\n />\n )\n}\n\nCell.displayName = 'Table.Cell'\n","import { Icon } from '@spark-ui/components/icon'\nimport { ArrowUp } from '@spark-ui/icons/ArrowUp'\nimport { Sort } from '@spark-ui/icons/Sort'\nimport { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Column as AriaColumn,\n type ColumnProps as AriaColumnProps,\n type ColumnRenderProps,\n ColumnResizer,\n composeRenderProps,\n Group,\n} from 'react-aria-components'\n\nimport { columnStyles } from './Table.styles'\nimport { isInteractiveElement } from './table-utils'\nimport { useTableResizableContext } from './TableContext'\n\nexport interface ColumnProps extends Omit<AriaColumnProps, 'className'> {\n className?: string\n children?: AriaColumnProps['children']\n label: string\n /** When false, the column cannot be resized. When true or omitted, the column can be resized when the Table has allowsResizing. */\n allowsResizing?: boolean\n}\n\nexport function Column({\n className,\n label,\n children,\n allowsResizing = true,\n minWidth = 120,\n ...props\n}: ColumnProps) {\n const { isResizable } = useTableResizableContext()\n\n const childrenOrRenderFn = children as\n | ReactNode\n | ((renderProps: ColumnRenderProps & { defaultChildren?: ReactNode }) => ReactNode)\n\n return (\n <AriaColumn\n data-spark-component=\"table-column\"\n className={cx(columnStyles(), className)}\n minWidth={minWidth} // necessary to avoid resizing overlapping visual elements\n {...props}\n >\n {composeRenderProps(childrenOrRenderFn, (content, renderProps) => {\n const { allowsSorting, sortDirection } = renderProps\n\n const stopIfInteractive = (e: React.MouseEvent | React.PointerEvent) => {\n if (isInteractiveElement(e.target)) e.stopPropagation()\n }\n\n return (\n <>\n <Group\n role=\"presentation\"\n tabIndex={-1}\n className={cx(\n 'border-transparent',\n 'focus-visible:u-outline focus-visible:outline-offset-2',\n 'gap-sm box-border flex flex-1 items-center'\n )}\n onClick={stopIfInteractive}\n onPointerDown={stopIfInteractive}\n >\n <div className=\"gap-md flex min-w-0 shrink items-center\">\n <p className=\"truncate\">{label}</p>\n\n {children && (\n <div className=\"inline-flex shrink-0 items-center\">\n {typeof content === 'function'\n ? (\n content as (\n props: ColumnRenderProps & { defaultChildren?: ReactNode }\n ) => ReactNode\n )({ ...renderProps, defaultChildren: undefined })\n : content}\n </div>\n )}\n </div>\n\n {allowsSorting && (\n <span className=\"size-sz-32 ml-auto inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full\">\n <Icon size=\"sm\" className={cx(sortDirection === 'descending' && 'rotate-180')}>\n {sortDirection ? <ArrowUp /> : <Sort />}\n </Icon>\n </span>\n )}\n </Group>\n\n {isResizable && allowsResizing && !props.width && (\n <ColumnResizer\n className={cx(\n 'z-raised absolute top-0 right-[-8px]',\n 'group-last/column:hidden',\n 'h-full w-[16px] touch-none',\n 'mx-0 cursor-col-resize',\n 'data-focus-visible:after:u-outline',\n 'data-resizing:after:bg-outline-high after:transition-transform after:duration-200 data-resizing:after:scale-125',\n 'after:h-sz-32 after:bg-outline after:absolute after:top-1/2 after:left-1/2 after:w-[2px] after:-translate-y-1/2'\n )}\n />\n )}\n </>\n )\n })}\n </AriaColumn>\n )\n}\n\nColumn.displayName = 'Table.Column'\n","import { forwardRef } from 'react'\nimport { CheckboxContext, useContextProps } from 'react-aria-components'\n\nimport { Checkbox } from '../checkbox'\n\n/**\n * Adapter that receives table selection state from React Aria's CheckboxContext\n * and renders Spark Checkbox. Used for row selection and \"select all\" in table header.\n */\nexport const TableSelectionCheckbox = forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof Checkbox>\n>(function TableSelectionCheckbox(props, ref) {\n // Aria's CheckboxContext is typed for HTMLLabelElement; we render Spark Checkbox (button).\n // We only consume context props (isSelected, isIndeterminate, onChange), ref comes from our forwardRef.\n const [mergedProps, mergedRef] = useContextProps(\n { ...props, slot: 'selection' as const },\n ref,\n CheckboxContext as any\n )\n\n const { isSelected, isIndeterminate, onChange, ...rest } = mergedProps as typeof props & {\n isSelected?: boolean\n isIndeterminate?: boolean\n onChange?: (checked: boolean) => void\n }\n\n const checked = isIndeterminate === true ? 'indeterminate' : Boolean(isSelected)\n\n return (\n <span\n onClick={e => e.stopPropagation()}\n onPointerDown={e => e.stopPropagation()}\n className=\"flex h-full min-h-full items-center justify-center\"\n >\n <Checkbox\n ref={mergedRef as React.Ref<HTMLButtonElement>}\n checked={checked}\n onCheckedChange={onChange}\n {...rest}\n />\n </span>\n )\n})\n\nTableSelectionCheckbox.displayName = 'Table.SelectionCheckbox'\n","import type { Key } from '@react-types/shared'\nimport { useContext } from 'react'\nimport { TableStateContext } from 'react-aria-components'\n\nimport { Checkbox } from '../checkbox'\nimport { TableSelectionCheckbox } from './TableSelectionCheckbox'\n\n/**\n * Header \"select all\" checkbox that bases its checked/indeterminate state only\n * on the currently visible (rendered) rows. So when the user changes page in a\n * paginated table, the header shows unchecked instead of indeterminate when no\n * visible row is selected.\n *\n * Renders the Checkbox directly and calls selectionManager.toggleSelectAll() so\n * we fully control the displayed state instead of overriding React Aria's context.\n */\nexport function TableHeaderSelectionCheckbox() {\n const tableState = useContext(TableStateContext)\n\n if (!tableState) {\n return <TableSelectionCheckbox />\n }\n\n const { collection, selectionManager } = tableState\n const selectedKeys = selectionManager.selectedKeys\n\n // Visible row keys: only the body row keys (currently rendered rows).\n // TableCollection has a body node whose children are the rows.\n const collectionWithBody = collection as unknown as {\n body?: { key: Key }\n getChildren: (key: Key) => Iterable<{ key: Key }>\n getKeys: () => IterableIterator<Key>\n }\n const bodyNode = collectionWithBody.body\n const visibleRowKeys =\n bodyNode != null\n ? new Set<Key>([...collectionWithBody.getChildren(bodyNode.key)].map(node => node.key))\n : new Set<Key>(collection.getKeys())\n\n const keysSet = (selectedKeys as unknown) === 'all' ? visibleRowKeys : (selectedKeys as Set<Key>)\n const selectedVisibleCount = [...visibleRowKeys].filter(key => keysSet.has(key)).length\n const visibleCount = visibleRowKeys.size\n\n const isAllSelected = visibleCount > 0 && selectedVisibleCount === visibleCount\n const isIndeterminate = selectedVisibleCount > 0 && selectedVisibleCount < visibleCount\n\n const checked = isIndeterminate ? 'indeterminate' : isAllSelected\n\n return (\n <span\n onClick={e => e.stopPropagation()}\n onPointerDown={e => e.stopPropagation()}\n className=\"flex h-full min-h-full items-center justify-center\"\n >\n <Checkbox\n checked={checked}\n onCheckedChange={() => {\n selectionManager.toggleSelectAll()\n }}\n />\n </span>\n )\n}\n\nTableHeaderSelectionCheckbox.displayName = 'Table.HeaderSelectionCheckbox'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Collection,\n Column as AriaColumn,\n TableHeader as AriaTableHeader,\n type TableHeaderProps as AriaTableHeaderProps,\n useTableOptions,\n} from 'react-aria-components'\n\nimport { columnStyles } from './Table.styles'\nimport { TableHeaderSelectionCheckbox } from './TableHeaderSelectionCheckbox'\n\nexport interface TableHeaderProps<T extends object = object>\n extends Omit<AriaTableHeaderProps<T>, 'className'> {\n className?: string\n /** When true (default), the header row is sticky with z-raised and top-0. */\n sticky?: boolean\n}\n\nexport function TableHeader<T extends object>({\n className,\n columns,\n children,\n sticky = true,\n ...props\n}: TableHeaderProps<T>) {\n const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions()\n\n return (\n <AriaTableHeader\n data-spark-component=\"table-header\"\n className={cx(\n [\n sticky && 'z-raised sticky top-0',\n 'text-on-neutral-container text-body-1 font-semibold',\n 'after:pt-md after:block after:size-0',\n ],\n className\n )}\n columns={columns}\n {...props}\n >\n {allowsDragging && (\n <AriaColumn width={20} minWidth={20} className=\"w-sz-20 min-w-sz-20 box-border\" />\n )}\n {selectionBehavior === 'toggle' && (\n <AriaColumn width={56} minWidth={56} className={cx(columnStyles())}>\n {selectionMode === 'multiple' && <TableHeaderSelectionCheckbox />}\n </AriaColumn>\n )}\n {columns != null ? (\n <Collection items={columns}>{children}</Collection>\n ) : (\n (children as ReactNode)\n )}\n </AriaTableHeader>\n )\n}\n\nTableHeader.displayName = 'Table.Header'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Button,\n Collection,\n Row as AriaRow,\n type RowProps as AriaRowProps,\n useTableOptions,\n} from 'react-aria-components'\n\nimport { Cell } from './TableCell'\nimport { TableSelectionCheckbox } from './TableSelectionCheckbox'\n\nexport interface RowProps<T extends object = object> extends Omit<AriaRowProps<T>, 'className'> {\n className?: string\n}\n\nexport function Row<T extends object>({ id, columns, children, className, ...props }: RowProps<T>) {\n const { selectionBehavior, allowsDragging } = useTableOptions()\n\n return (\n <AriaRow\n id={id}\n data-spark-component=\"table-row\"\n className={cx(\n 'group/row',\n 'h-sz-80', // first row: 96px so 16px gap (border-t) + 80px content\n 'group/row text-on-surface relative cursor-default select-none',\n '[-webkit-tap-highlight-color:transparent]',\n 'data-focus-visible:u-outline-inset outline-none data-focus-visible:outline-dashed',\n 'data-react-aria-pressable:hover:bg-surface-hovered data-react-aria-pressable:pressed:bg-surface-hovered',\n // Selected row styles\n 'data-selected:bg-support-container data-selected:text-on-support-container',\n 'data-selected:hover:bg-support-container-hovered data-selected:data-pressed:bg-support-container-hovered',\n // Disabled row styles\n 'data-disabled:text-on-surface/dim-3',\n // Href row styles\n 'data-href:cursor-pointer',\n className\n )}\n columns={columns}\n {...props}\n >\n {allowsDragging && (\n <Cell>\n <Button\n slot=\"drag\"\n className=\"w-sz-15 data-focus-visible:u-outline flex items-center justify-center text-center outline-none data-[focus-visible]:rounded-md\"\n >\n ≡\n </Button>\n </Cell>\n )}\n {selectionBehavior === 'toggle' && (\n <Cell checkbox>\n <TableSelectionCheckbox />\n </Cell>\n )}\n {columns != null ? (\n <Collection items={columns}>{children}</Collection>\n ) : (\n (children as ReactNode)\n )}\n </AriaRow>\n )\n}\n\nRow.displayName = 'Table.Row'\n","import { useMemo, useState } from 'react'\nimport type { SortDescriptor } from 'react-aria-components'\n\nexport interface UseTableSortOptions<T extends object> {\n /** Initial sort column and direction. */\n initialSort?: {\n column: keyof T\n direction: 'ascending' | 'descending'\n }\n /**\n * Custom compare function. If not provided, a default comparator is used:\n * - numbers: numeric comparison\n * - other: localeCompare on string representation\n */\n compare?: (a: T, b: T, column: keyof T, direction: 'ascending' | 'descending') => number\n}\n\nfunction defaultCompare<T extends object>(\n a: T,\n b: T,\n column: keyof T,\n direction: 'ascending' | 'descending'\n): number {\n const aVal = a[column]\n const bVal = b[column]\n\n if (aVal === bVal) return 0\n\n let comparisonResult: number\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparisonResult = aVal < bVal ? -1 : 1\n } else {\n comparisonResult = String(aVal).localeCompare(String(bVal))\n }\n\n return direction === 'descending' ? -comparisonResult : comparisonResult\n}\n\n/**\n * Hook to manage table sort state and derive sorted items from a list.\n * Use with Table's sortDescriptor and onSortChange props.\n *\n * @example\n * const { sortDescriptor, onSortChange, setSortDescriptor, sortedItems } = useTableSort(rows, {\n * initialSort: { column: 'name', direction: 'ascending' },\n * })\n * return (\n * <>\n * <Button onClick={() => setSortDescriptor({ column: 'name', direction: 'ascending' })}>Reset sort</Button>\n * <Table sortDescriptor={sortDescriptor} onSortChange={onSortChange}>\n * ...\n * </Table>\n * </>\n * )\n */\nexport function useTableSort<T extends object>(\n items: T[],\n options: UseTableSortOptions<T> = {}\n): {\n sortDescriptor: SortDescriptor\n onSortChange: (descriptor: SortDescriptor) => void\n /** Set sort from outside the table (e.g. a \"Reset sort\" button). */\n setSortDescriptor: (descriptor: SortDescriptor) => void\n sortedItems: T[]\n} {\n const { initialSort, compare } = options\n\n const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>(() =>\n initialSort\n ? { column: initialSort.column as string, direction: initialSort.direction }\n : { column: 'id', direction: 'ascending' }\n )\n\n const sortedItems = useMemo(() => {\n const column = sortDescriptor.column as keyof T\n if (!column) return [...items]\n\n const compareFn = compare ?? defaultCompare\n const direction = sortDescriptor.direction ?? 'ascending'\n\n return [...items].sort((a, b) => compareFn(a, b, column, direction))\n }, [items, sortDescriptor.column, sortDescriptor.direction, compare])\n\n return {\n sortDescriptor,\n onSortChange: setSortDescriptor,\n setSortDescriptor,\n sortedItems,\n }\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { Key, Selection } from 'react-aria-components'\n\nexport interface UseTablePaginationOptions<T> {\n /** Number of items per page. */\n pageSize: number\n /** Initial page index (1-based). Defaults to 1. */\n initialPage?: number\n /**\n * Function to extract a stable key from each item.\n * Defaults to `item.id` if present.\n */\n getId?: (item: T) => Key\n}\n\nexport interface UseTablePaginationResult<T> {\n /** Current page (1-based). */\n page: number\n /** Update the current page manually. */\n setPage: (page: number) => void\n /** Items sliced to the current page. */\n pageItems: T[]\n /** Total number of items. */\n totalItems: number\n /** Total number of pages (at least 1). */\n totalPages: number\n /** All item keys across all pages. */\n allKeys: Set<Key>\n /**\n * Selection state across all pages.\n * Pass to Table (root) as `selectedKeys`.\n */\n selectedKeys: Set<Key>\n /**\n * Selection change handler that keeps selection across pages.\n * Pass to Table (root) as `onSelectionChange`.\n */\n onSelectionChange: (keys: Selection) => void\n /**\n * Convenience handler matching Pagination's `onPageChange` signature:\n * `onPageChange={({ page }) => ...}`.\n */\n onPageChange: (details: { page: number }) => void\n /** Clear selection across all pages. */\n clearSelection: () => void\n}\n\n/**\n * Hook to manage simple client-side pagination and multi-page selection for Table.\n * It slices the full item list to the current page, tracks page state, and merges\n * selection across pages so that rows selected on previous pages remain selected.\n *\n * @example\n * const { page, pageItems, totalItems, allKeys, selectedKeys, onSelectionChange, onPageChange } =\n * useTablePagination(allItems, { pageSize: 10 })\n *\n * return (\n * <Table\n * selectionMode=\"multiple\"\n * selectedKeys={selectedKeys}\n * onSelectionChange={onSelectionChange}\n * totalCount={totalItems}\n * hasMultiplePages={totalItems > 10}\n * onSelectAll={() => onSelectionChange(allKeys)}\n * >\n * <Table.BulkBar>...</Table.BulkBar>\n * <Table.Grid aria-label=\"Items\">\n * <Table.Body>\n * {pageItems.map(item => (\n * <Table.Row key={item.id} id={item.id}>...</Table.Row>\n * ))}\n * </Table.Body>\n * </Table.Grid>\n * <Pagination page={page} pageSize={10} count={totalItems} onPageChange={onPageChange} />\n * </Table>\n * )\n */\nexport function useTablePagination<T>(\n items: T[],\n options: UseTablePaginationOptions<T>\n): UseTablePaginationResult<T> {\n const { pageSize, initialPage = 1, getId } = options\n\n const [page, setPage] = useState(initialPage)\n const [selectedKeys, setSelectedKeys] = useState<Set<Key>>(() => new Set())\n\n const totalItems = items.length\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize))\n\n // Clamp current page when the total page count changes (e.g. items length shrinks).\n useEffect(() => {\n setPage(current => {\n if (current < 1) return 1\n if (current > totalPages) return totalPages\n\n return current\n })\n }, [totalPages])\n\n let effectivePage = page\n if (effectivePage < 1) {\n effectivePage = 1\n } else if (effectivePage > totalPages) {\n effectivePage = totalPages\n }\n\n const pageItems = useMemo(() => {\n const start = (effectivePage - 1) * pageSize\n const end = start + pageSize\n\n return items.slice(start, end)\n }, [items, effectivePage, pageSize])\n\n const allKeys = useMemo(() => {\n const resolveId =\n getId ??\n ((item: T) => {\n const candidate = (item as unknown as { id?: Key }).id\n\n if (candidate == null) {\n throw new Error(\n 'useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.'\n )\n }\n\n return candidate\n })\n\n return new Set<Key>(items.map(item => resolveId(item)))\n }, [getId, items])\n\n const pageIds = useMemo(() => {\n const resolveId =\n getId ??\n ((item: T) => {\n const candidate = (item as unknown as { id?: Key }).id\n\n if (candidate == null) {\n throw new Error(\n 'useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.'\n )\n }\n\n return candidate\n })\n\n return new Set<Key>(pageItems.map(item => resolveId(item)))\n }, [getId, pageItems])\n\n const handleSelectionChange = (keys: Selection) => {\n // React Aria uses \"all\" to represent \"select all\" in the current context.\n // For the table header checkbox, interpret \"all\" as \"all items on the current page\".\n const newPageSelection = keys === 'all' ? new Set<Key>(pageIds) : new Set(keys as Set<Key>)\n\n setSelectedKeys(prev => {\n const next = new Set<Key>(newPageSelection)\n\n // Keep selections from other pages.\n for (const key of prev) {\n if (!pageIds.has(key)) {\n next.add(key)\n }\n }\n\n return next\n })\n }\n\n const handlePageChange = (details: { page: number }) => {\n setPage(details.page)\n }\n\n const clearSelection = () => {\n setSelectedKeys(() => new Set())\n }\n\n return {\n page: effectivePage,\n setPage,\n pageItems,\n totalItems,\n totalPages,\n allKeys,\n selectedKeys,\n onSelectionChange: handleSelectionChange,\n onPageChange: handlePageChange,\n clearSelection,\n }\n}\n","import { TableGrid, TableRootWrapper } from './Table'\nimport { TableBody } from './TableBody'\nimport {\n TableBulkBar,\n TableBulkBarClearButton,\n TableBulkBarSelectAllButton,\n TableBulkBarSelectedCount,\n} from './TableBulkBar'\nimport { Cell } from './TableCell'\nimport { Column } from './TableColumn'\nimport { TableHeader } from './TableHeader'\nimport { Row } from './TableRow'\n\nexport const TableWithSubcomponents: typeof TableRootWrapper & {\n Grid: typeof TableGrid\n Header: typeof TableHeader\n Column: typeof Column\n Body: typeof TableBody\n Row: typeof Row\n Cell: typeof Cell\n BulkBar: typeof TableBulkBar\n BulkBarSelectedCount: typeof TableBulkBarSelectedCount\n BulkBarClearButton: typeof TableBulkBarClearButton\n BulkBarSelectAllButton: typeof TableBulkBarSelectAllButton\n} = Object.assign(TableRootWrapper, {\n Grid: TableGrid,\n Header: TableHeader,\n Column,\n Body: TableBody,\n Row,\n Cell,\n BulkBar: TableBulkBar,\n BulkBarSelectedCount: TableBulkBarSelectedCount,\n BulkBarClearButton: TableBulkBarClearButton,\n BulkBarSelectAllButton: TableBulkBarSelectAllButton,\n})\n\nTableWithSubcomponents.displayName = 'Table'\nTableHeader.displayName = 'Table.Header'\nColumn.displayName = 'Table.Column'\nTableBody.displayName = 'Table.Body'\nRow.displayName = 'Table.Row'\nCell.displayName = 'Table.Cell'\n\nexport { TableWithSubcomponents as Table }\n\nexport { useTableSort } from './useTableSort'\nexport { useTablePagination } from './useTablePagination'\nexport type { SortDescriptor } from 'react-aria-components'\nexport type { UseTableSortOptions } from './useTableSort'\nexport type { UseTablePaginationOptions, UseTablePaginationResult } from './useTablePagination'\nexport { type TableGridProps, type TableProps, type TableRootWrapperProps } from './Table'\nexport { type TableHeaderProps } from './TableHeader'\nexport { type ColumnProps } from './TableColumn'\nexport { type TableBodyProps } from './TableBody'\nexport { type RowProps } from './TableRow'\nexport { type CellProps } from './TableCell'\n"],"mappings":"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"}
@@ -215,7 +215,7 @@ function H({ children: e, className: t }) {
215
215
  role: "toolbar",
216
216
  "aria-label": "Table bulk actions",
217
217
  "data-spark-component": "table-bulk-bar",
218
- className: i("gap-lg min-h-sz-64 flex w-full flex-wrap items-center justify-between", "rounded-lg", "bg-basic-container text-on-basic-container p-lg", t),
218
+ className: i("gap-lg min-h-sz-64 flex w-full flex-wrap items-center justify-between", "rounded-lg", "bg-support-container text-on-support-container p-lg", t),
219
219
  children: e
220
220
  })
221
221
  });
@@ -399,7 +399,7 @@ function Q({ id: e, columns: t, children: n, className: r, ...a }) {
399
399
  return /* @__PURE__ */ h(te, {
400
400
  id: e,
401
401
  "data-spark-component": "table-row",
402
- className: i("group/row", "h-sz-80", "group/row text-on-surface relative cursor-default select-none", "[-webkit-tap-highlight-color:transparent]", "data-focus-visible:u-outline-inset outline-none data-focus-visible:outline-dashed", "data-react-aria-pressable:hover:bg-surface-hovered data-react-aria-pressable:pressed:bg-surface-hovered", "data-selected:bg-basic-container data-selected:text-on-basic-container", "data-selected:hover:bg-basic-container-hovered data-selected:data-pressed:bg-basic-container-hovered", "data-disabled:text-on-surface/dim-3", "data-href:cursor-pointer", r),
402
+ className: i("group/row", "h-sz-80", "group/row text-on-surface relative cursor-default select-none", "[-webkit-tap-highlight-color:transparent]", "data-focus-visible:u-outline-inset outline-none data-focus-visible:outline-dashed", "data-react-aria-pressable:hover:bg-surface-hovered data-react-aria-pressable:pressed:bg-surface-hovered", "data-selected:bg-support-container data-selected:text-on-support-container", "data-selected:hover:bg-support-container-hovered data-selected:data-pressed:bg-support-container-hovered", "data-disabled:text-on-surface/dim-3", "data-href:cursor-pointer", r),
403
403
  columns: t,
404
404
  ...a,
405
405
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/table/table-utils.ts","../../src/table/TableContext.tsx","../../src/table/ResizableTableContainer.tsx","../../src/table/Table.tsx","../../src/table/Table.styles.tsx","../../src/table/TableBody.tsx","../../src/table/TableBulkBar.tsx","../../src/table/TableCell.tsx","../../src/table/TableColumn.tsx","../../src/table/TableSelectionCheckbox.tsx","../../src/table/TableHeaderSelectionCheckbox.tsx","../../src/table/TableHeader.tsx","../../src/table/TableRow.tsx","../../src/table/useTableSort.ts","../../src/table/useTablePagination.ts","../../src/table/index.ts"],"sourcesContent":["/**\n * Selector for elements that have their own Space/Enter behavior (buttons, switches, inputs, etc.).\n * Used to avoid table row selection capturing these keys when focus is on an interactive cell content.\n */\nconst INTERACTIVE_SELECTOR =\n 'button, [role=\"button\"], [role=\"switch\"], [role=\"checkbox\"], [role=\"option\"], input:not([type=\"hidden\"]), select, textarea, [href]'\n\n/** Column resizer uses a hidden focusable input for keyboard resize (Enter to toggle, ArrowLeft/Right). Don't convert Enter to click there. */\nconst COLUMN_RESIZER_SELECTOR = '[data-resizable-direction]'\n\nexport function isInteractiveElement(element: EventTarget | null): element is Element {\n if (!element || !(element instanceof Element)) return false\n const el = element as Element\n\n return el.matches(INTERACTIVE_SELECTOR) || el.closest(INTERACTIVE_SELECTOR) !== null\n}\n\nexport function isColumnResizerElement(element: EventTarget | null): element is Element {\n if (!element || !(element instanceof Element)) return false\n\n return (element as Element).closest(COLUMN_RESIZER_SELECTOR) !== null\n}\n","import { createContext, useContext } from 'react'\nimport type { Selection } from 'react-aria-components'\nimport type { SortDescriptor } from 'react-aria-components'\n\nimport type { ResizableTableContainerProps } from './ResizableTableContainer'\n\nexport interface TableResizableContextValue {\n isResizable: boolean\n}\n\nexport const TableResizableContext = createContext<TableResizableContextValue>({\n isResizable: false,\n})\n\nexport function useTableResizableContext() {\n return useContext(TableResizableContext)\n}\n\n/** Values provided by Table (root) and consumed by Table.Grid and Table.BulkBar. */\nexport interface TableContextValue\n extends Pick<ResizableTableContainerProps, 'onResizeStart' | 'onResize' | 'onResizeEnd'> {\n // Selection (optional when table has no selection)\n selectionMode?: 'none' | 'single' | 'multiple'\n selectionBehavior?: 'toggle' | 'replace'\n selectedKeys?: Selection\n onSelectionChange?: (keys: Selection) => void\n // BulkBar: optional when not using BulkBar\n totalCount?: number\n hasMultiplePages?: boolean\n onSelectAll?: () => void\n // Derived for BulkBar (from selectedKeys + onSelectionChange)\n selectedCount: number\n onClearSelection: () => void\n // Layout / grid\n allowsResizing?: boolean\n maxHeight?: number | string\n onKeyDownCapture?: React.KeyboardEventHandler<Element>\n sortDescriptor?: SortDescriptor\n onSortChange?: (descriptor: SortDescriptor) => void\n className?: string\n // Pass-through for AriaTable (aria-label, etc.)\n [key: string]: unknown\n}\n\nconst defaultTableContextValue: TableContextValue = {\n selectedCount: 0,\n onClearSelection: () => {},\n}\n\nexport const TableContext = createContext<TableContextValue>(defaultTableContextValue)\n\nexport function useTableContext(): TableContextValue {\n return useContext(TableContext)\n}\n","import { cx } from 'class-variance-authority'\nimport type { ComponentProps } from 'react'\nimport { useLayoutEffect, useRef } from 'react'\nimport { ResizableTableContainer as AriaResizableTableContainer } from 'react-aria-components'\n\nimport { isColumnResizerElement, isInteractiveElement } from './table-utils'\nimport { TableResizableContext } from './TableContext'\n\nexport interface ResizableTableContainerProps\n extends Omit<ComponentProps<typeof AriaResizableTableContainer>, 'className'> {\n className?: string\n}\n\nexport function ResizableTableContainer({\n className,\n children,\n ...props\n}: ResizableTableContainerProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n\n useLayoutEffect(() => {\n const el = containerRef.current\n if (!el) return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== ' ' && e.key !== 'Enter') return\n if (!isInteractiveElement(e.target)) return\n if (!el.contains(e.target as Node)) return\n // Column resizer uses Enter to toggle keyboard resize mode (ArrowLeft/Right to resize). Do not convert to click.\n if (isColumnResizerElement(e.target)) return\n\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n\n // Dispatch a click so the control (Switch, button, etc.) toggles/activates\n // as it would when Space/Enter is pressed natively (browser triggers click)\n const target = e.target as HTMLElement\n target.click()\n }\n\n el.addEventListener('keydown', handleKeyDown, true)\n\n return () => el.removeEventListener('keydown', handleKeyDown, true)\n }, [])\n\n return (\n <TableResizableContext.Provider value={{ isResizable: true }}>\n <AriaResizableTableContainer\n ref={containerRef}\n data-spark-component=\"resizable-table-container\"\n className={cx('relative w-full overflow-auto', className)}\n {...props}\n >\n {children}\n </AriaResizableTableContainer>\n </TableResizableContext.Provider>\n )\n}\n\nResizableTableContainer.displayName = 'ResizableTableContainer'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport { useLayoutEffect, useRef } from 'react'\nimport { Table as AriaTable, type TableProps as AriaTableProps } from 'react-aria-components'\n\nimport type { ResizableTableContainerProps } from './ResizableTableContainer'\nimport { ResizableTableContainer } from './ResizableTableContainer'\nimport { isColumnResizerElement, isInteractiveElement } from './table-utils'\nimport { TableContext, type TableContextValue, useTableContext } from './TableContext'\n\nexport interface TableProps\n extends Omit<AriaTableProps, 'className'>,\n Pick<ResizableTableContainerProps, 'onResizeStart' | 'onResize' | 'onResizeEnd'> {\n className?: string\n onKeyDownCapture?: React.KeyboardEventHandler<Element>\n /** When true (default), columns can be resized. Pass onResizeStart, onResize, onResizeEnd to react to resize events. */\n allowsResizing?: boolean\n /** Max height of the scroll container (number in px or CSS value). Applied so vertical and horizontal scrollbars share the same container. */\n maxHeight?: number | string\n /** For BulkBar: total number of items (e.g. for \"Select all X items\"). */\n totalCount?: number\n /** When true, BulkBar shows \"Clear all\" and \"Select all\" buttons. */\n hasMultiplePages?: boolean\n /**\n * Called when user clicks \"Clear all\" in BulkBar.\n * Useful with pagination selection models (e.g. `useTablePagination`) where clearing only the\n * current page would be incorrect.\n */\n onClearSelection?: () => void\n /** Called when user clicks \"Select all\" in BulkBar. */\n onSelectAll?: () => void\n}\n\nexport interface TableRootWrapperProps extends TableProps {\n children: ReactNode\n}\n\nexport function TableRootWrapper({\n children,\n className,\n selectedKeys,\n onSelectionChange,\n totalCount,\n hasMultiplePages,\n onClearSelection: onClearSelectionProp,\n onSelectAll,\n allowsResizing = true,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n ...restProps\n}: TableRootWrapperProps) {\n let selectedCount = 0\n\n if (selectedKeys === 'all') {\n selectedCount = totalCount ?? 0\n } else if (selectedKeys instanceof Set) {\n selectedCount = selectedKeys.size\n } else if (selectedKeys) {\n selectedCount = new Set(selectedKeys).size\n }\n const onClearSelection = onClearSelectionProp ?? (() => onSelectionChange?.(new Set()))\n\n const contextValue = {\n ...restProps,\n selectedKeys,\n onSelectionChange,\n totalCount,\n hasMultiplePages,\n onSelectAll,\n selectedCount,\n onClearSelection,\n allowsResizing,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n className,\n }\n\n return (\n <TableContext.Provider value={contextValue as TableContextValue}>\n <div className={cx('gap-md flex flex-col', className)}>{children}</div>\n </TableContext.Provider>\n )\n}\n\nTableRootWrapper.displayName = 'Table'\n\nexport const TableRoot = ({ className, onKeyDownCapture, ...props }: TableProps) => {\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // Native capture-phase listener so we run BEFORE react-aria's native listeners\n // (which handle row selection on Space/Enter). Synthetic onKeyDownCapture runs\n // too late. When focus is on an interactive element (switch, button, etc.),\n // we consume the event and trigger a click so the control activates without\n // the row being selected.\n useLayoutEffect(() => {\n const el = wrapperRef.current\n if (!el) return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== ' ' && e.key !== 'Enter') return\n if (!isInteractiveElement(e.target)) return\n if (!el.contains(e.target as Node)) return\n // Column resizer uses Enter to toggle keyboard resize mode (ArrowLeft/Right to resize). Do not convert to click.\n if (isColumnResizerElement(e.target)) return\n\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n ;(e.target as HTMLElement).click()\n }\n\n el.addEventListener('keydown', handleKeyDown, true)\n\n return () => el.removeEventListener('keydown', handleKeyDown, true)\n }, [])\n\n return (\n <AriaTable\n ref={wrapperRef}\n data-spark-component=\"table\"\n className={cx(\n 'default:w-full',\n 'border-separate border-spacing-y-0',\n 'bg-surface',\n 'outline-none',\n 'text-body-1',\n 'forced-color-adjust-none',\n 'data-focus-visible:u-outline-inset',\n 'has-[>[data-empty]]:h-full',\n className\n )}\n {...(onKeyDownCapture ? { ...props, onKeyDownCapture } : props)}\n />\n )\n}\n\nTableRoot.displayName = 'Table.Grid.Inner'\n\nfunction toMaxHeightStyle(value: number | string): React.CSSProperties['maxHeight'] {\n return typeof value === 'number' ? `${value}px` : value\n}\n\nexport interface TableGridProps {\n /** Required for accessibility. */\n 'aria-label'?: string\n 'aria-labelledby'?: string\n className?: string\n children?: ReactNode\n}\n\nexport function TableGrid({\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className: gridClassName,\n children,\n}: TableGridProps) {\n const ctx = useTableContext()\n const {\n allowsResizing = true,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n className: contextClassName,\n ...ariaTableProps\n } = ctx\n\n const scrollContainerStyle =\n maxHeight != null ? { maxHeight: toMaxHeightStyle(maxHeight) } : undefined\n const className = gridClassName ?? contextClassName\n\n const tableRootProps = {\n ...ariaTableProps,\n ...(ariaLabel != null && { 'aria-label': ariaLabel }),\n ...(ariaLabelledBy != null && { 'aria-labelledby': ariaLabelledBy }),\n sortDescriptor,\n onSortChange,\n onKeyDownCapture,\n className,\n }\n\n if (allowsResizing) {\n return (\n <ResizableTableContainer\n className={className}\n style={scrollContainerStyle}\n onResizeStart={onResizeStart}\n onResize={onResize}\n onResizeEnd={onResizeEnd}\n >\n <TableRoot {...tableRootProps}>{children}</TableRoot>\n </ResizableTableContainer>\n )\n }\n\n return (\n <div className=\"relative w-full overflow-auto\" style={scrollContainerStyle}>\n <TableRoot {...tableRootProps}>{children}</TableRoot>\n </div>\n )\n}\n\nTableGrid.displayName = 'Table.Grid'\n","import { cva, type VariantProps } from 'class-variance-authority'\n\nexport const columnStyles = cva(\n [\n 'h-sz-64 min-w-sz-64',\n 'relative group/column first:rounded-l-xl last:rounded-r-xl bg-neutral-container',\n 'px-lg py-sm text-left outline-none box-border',\n 'cursor-default',\n 'data-focus-visible:u-outline data-focus-visible:-outline-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const columnHeaderContentStyles = cva(\n [\n 'flex flex-1 justify-between items-center gap-md',\n 'font-inherit text-left text-inherit',\n 'whitespace-nowrap text-ellipsis',\n 'border-transparent',\n 'data-focus-visible:u-outline data-focus-visible:outline-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const tableBodyStyles = cva(\n ['empty:italic empty:text-center empty:text-body-2 empty:py-lg'],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const cellStyles = cva(\n [\n 'p-lg outline-none box-border default:overflow-hidden',\n 'border-b-sm border-outline [tr:last-child>&]:border-b-0',\n '[-webkit-tap-highlight-color:transparent]',\n 'data-focus-visible:u-outline-inset data-focus-visible:outline-dashed',\n ],\n {\n variants: {\n /** When true, matches width + padding of the TableSelectionCheckbox header column (w-sz-64, py-sm, no horizontal padding). Use cellCheckboxInnerStyles on the inner wrapper to fill height and center content. */\n checkbox: {\n true: ['w-sz-64 py-sm px-0 align-middle'],\n },\n },\n defaultVariants: {\n checkbox: false,\n },\n }\n)\n\n/** Spacer row: 16px (md) visual gap between header and first data row. Use as first child of tbody. */\nexport const tableBodySpacerRowStyles = cva(\n [\n 'pointer-events-none',\n '[&_td]:h-sz-16 [&_td]:p-0 [&_td]:border-0 [&_td]:border-b-0 [&_td]:bg-surface [&_td]:align-middle',\n ],\n { variants: {}, defaultVariants: {} }\n)\n\nexport type ColumnStylesProps = VariantProps<typeof columnStyles>\nexport type CellStylesProps = VariantProps<typeof cellStyles>\n","import { cx } from 'class-variance-authority'\nimport {\n TableBody as AriaTableBody,\n type TableBodyProps as AriaTableBodyProps,\n} from 'react-aria-components'\n\nimport { tableBodyStyles } from './Table.styles'\n\nexport interface TableBodyProps<T extends object = object>\n extends Omit<AriaTableBodyProps<T>, 'className'> {\n className?: string\n}\n\nexport function TableBody<T extends object>({\n className,\n renderEmptyState,\n ...props\n}: TableBodyProps<T>) {\n const wrappedRenderEmptyState: AriaTableBodyProps<T>['renderEmptyState'] =\n renderEmptyState != null\n ? renderProps => (\n <div data-spark-component=\"table-empty\" className=\"p-lg\">\n {renderEmptyState(renderProps)}\n </div>\n )\n : undefined\n\n return (\n <AriaTableBody\n data-spark-component=\"table-body\"\n className={cx(tableBodyStyles(), className)}\n renderEmptyState={wrappedRenderEmptyState}\n {...props}\n />\n )\n}\n\nTableBody.displayName = 'Table.Body'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport { createContext, useContext } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { useTableContext } from './TableContext'\n\ninterface TableBulkBarContextValue {\n selectedCount: number\n totalCount?: number\n onClearSelection: () => void\n onSelectAll?: () => void\n /** When true, \"Clear all\" and \"Select all\" are shown (subject to their own conditions). */\n hasMultiplePages?: boolean\n}\n\nconst TableBulkBarContext = createContext<TableBulkBarContextValue | null>(null)\n\nfunction useTableBulkBarContext() {\n const ctx = useContext(TableBulkBarContext)\n\n if (!ctx) {\n throw new Error('Table.BulkBar subcomponents must be used within Table.BulkBar')\n }\n\n return ctx\n}\n\nexport interface TableBulkBarProps {\n children: ReactNode\n className?: string\n}\n\nfunction TableBulkBarRoot({ children, className }: TableBulkBarProps) {\n const { selectedCount, totalCount, onClearSelection, onSelectAll, hasMultiplePages } =\n useTableContext()\n\n const contextValue: TableBulkBarContextValue = {\n selectedCount,\n totalCount,\n onClearSelection,\n onSelectAll,\n hasMultiplePages,\n }\n\n return (\n <TableBulkBarContext.Provider value={contextValue}>\n <div\n role=\"toolbar\"\n aria-label=\"Table bulk actions\"\n data-spark-component=\"table-bulk-bar\"\n className={cx(\n 'gap-lg min-h-sz-64 flex w-full flex-wrap items-center justify-between',\n 'rounded-lg',\n 'bg-basic-container text-on-basic-container p-lg',\n className\n )}\n >\n {children}\n </div>\n </TableBulkBarContext.Provider>\n )\n}\n\nfunction TableBulkBarSelectedCount({ children }: { children: ReactNode }) {\n useTableBulkBarContext() // enforce usage within BulkBar\n\n return <span className=\"text-body-1 font-bold\">{children}</span>\n}\n\ntype BulkBarButtonProps = Omit<ButtonProps, 'onClick'>\n\nfunction TableBulkBarClearButton({ className, children, ...props }: BulkBarButtonProps) {\n const { selectedCount, onClearSelection, hasMultiplePages } = useTableBulkBarContext()\n\n if (!hasMultiplePages) {\n return null\n }\n\n const ariaDisabled = selectedCount === 0\n\n return (\n <Button\n size=\"sm\"\n design=\"ghost\"\n intent=\"support\"\n underline\n ariaDisabled={ariaDisabled}\n onClick={onClearSelection}\n className={cx('text-body-2', className)}\n {...props}\n >\n {children}\n </Button>\n )\n}\n\nfunction TableBulkBarSelectAllButton({ className, children, ...props }: BulkBarButtonProps) {\n const { selectedCount, totalCount, onSelectAll, hasMultiplePages } = useTableBulkBarContext()\n\n if (!hasMultiplePages) {\n return null\n }\n\n const ariaDisabled = totalCount == null || onSelectAll == null || selectedCount >= totalCount\n\n return (\n <Button\n size=\"sm\"\n design=\"ghost\"\n intent=\"support\"\n underline\n ariaDisabled={ariaDisabled}\n onClick={onSelectAll}\n className={cx('text-body-2', className)}\n {...props}\n >\n {children}\n </Button>\n )\n}\n\nTableBulkBarRoot.displayName = 'Table.BulkBar'\n\nexport const TableBulkBar = TableBulkBarRoot\nTableBulkBar.displayName = 'Table.BulkBar'\n\nexport { TableBulkBarSelectedCount, TableBulkBarClearButton, TableBulkBarSelectAllButton }\nTableBulkBarSelectedCount.displayName = 'Table.BulkBarSelectedCount'\nTableBulkBarClearButton.displayName = 'Table.BulkBarClearButton'\nTableBulkBarSelectAllButton.displayName = 'Table.BulkBarSelectAllButton'\n","import { cx } from 'class-variance-authority'\nimport { Cell as AriaCell, type CellProps as AriaCellProps } from 'react-aria-components'\n\nimport { cellStyles } from './Table.styles'\nimport { isInteractiveElement } from './table-utils'\n\nexport interface CellProps extends Omit<AriaCellProps, 'className'> {\n className?: string\n /** When true, cell uses same width + padding as the TableSelectionCheckbox header column. */\n checkbox?: boolean\n}\n\nexport function Cell({ className, checkbox, onClick, onPointerDown, ...props }: CellProps) {\n const stopIfInteractive = (e: React.MouseEvent | React.PointerEvent) => {\n if (isInteractiveElement(e.target)) e.stopPropagation()\n }\n\n return (\n <AriaCell\n data-spark-component=\"table-cell\"\n className={cx(cellStyles({ checkbox }), className)}\n onClick={e => {\n stopIfInteractive(e)\n onClick?.(e)\n }}\n onPointerDown={e => {\n stopIfInteractive(e)\n onPointerDown?.(e)\n }}\n {...props}\n />\n )\n}\n\nCell.displayName = 'Table.Cell'\n","import { Icon } from '@spark-ui/components/icon'\nimport { ArrowUp } from '@spark-ui/icons/ArrowUp'\nimport { Sort } from '@spark-ui/icons/Sort'\nimport { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Column as AriaColumn,\n type ColumnProps as AriaColumnProps,\n type ColumnRenderProps,\n ColumnResizer,\n composeRenderProps,\n Group,\n} from 'react-aria-components'\n\nimport { columnStyles } from './Table.styles'\nimport { isInteractiveElement } from './table-utils'\nimport { useTableResizableContext } from './TableContext'\n\nexport interface ColumnProps extends Omit<AriaColumnProps, 'className'> {\n className?: string\n children?: AriaColumnProps['children']\n label: string\n /** When false, the column cannot be resized. When true or omitted, the column can be resized when the Table has allowsResizing. */\n allowsResizing?: boolean\n}\n\nexport function Column({\n className,\n label,\n children,\n allowsResizing = true,\n minWidth = 120,\n ...props\n}: ColumnProps) {\n const { isResizable } = useTableResizableContext()\n\n const childrenOrRenderFn = children as\n | ReactNode\n | ((renderProps: ColumnRenderProps & { defaultChildren?: ReactNode }) => ReactNode)\n\n return (\n <AriaColumn\n data-spark-component=\"table-column\"\n className={cx(columnStyles(), className)}\n minWidth={minWidth} // necessary to avoid resizing overlapping visual elements\n {...props}\n >\n {composeRenderProps(childrenOrRenderFn, (content, renderProps) => {\n const { allowsSorting, sortDirection } = renderProps\n\n const stopIfInteractive = (e: React.MouseEvent | React.PointerEvent) => {\n if (isInteractiveElement(e.target)) e.stopPropagation()\n }\n\n return (\n <>\n <Group\n role=\"presentation\"\n tabIndex={-1}\n className={cx(\n 'border-transparent',\n 'focus-visible:u-outline focus-visible:outline-offset-2',\n 'gap-sm box-border flex flex-1 items-center'\n )}\n onClick={stopIfInteractive}\n onPointerDown={stopIfInteractive}\n >\n <div className=\"gap-md flex min-w-0 shrink items-center\">\n <p className=\"truncate\">{label}</p>\n\n {children && (\n <div className=\"inline-flex shrink-0 items-center\">\n {typeof content === 'function'\n ? (\n content as (\n props: ColumnRenderProps & { defaultChildren?: ReactNode }\n ) => ReactNode\n )({ ...renderProps, defaultChildren: undefined })\n : content}\n </div>\n )}\n </div>\n\n {allowsSorting && (\n <span className=\"size-sz-32 ml-auto inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full\">\n <Icon size=\"sm\" className={cx(sortDirection === 'descending' && 'rotate-180')}>\n {sortDirection ? <ArrowUp /> : <Sort />}\n </Icon>\n </span>\n )}\n </Group>\n\n {isResizable && allowsResizing && !props.width && (\n <ColumnResizer\n className={cx(\n 'z-raised absolute top-0 right-[-8px]',\n 'group-last/column:hidden',\n 'h-full w-[16px] touch-none',\n 'mx-0 cursor-col-resize',\n 'data-focus-visible:after:u-outline',\n 'data-resizing:after:bg-outline-high after:transition-transform after:duration-200 data-resizing:after:scale-125',\n 'after:h-sz-32 after:bg-outline after:absolute after:top-1/2 after:left-1/2 after:w-[2px] after:-translate-y-1/2'\n )}\n />\n )}\n </>\n )\n })}\n </AriaColumn>\n )\n}\n\nColumn.displayName = 'Table.Column'\n","import { forwardRef } from 'react'\nimport { CheckboxContext, useContextProps } from 'react-aria-components'\n\nimport { Checkbox } from '../checkbox'\n\n/**\n * Adapter that receives table selection state from React Aria's CheckboxContext\n * and renders Spark Checkbox. Used for row selection and \"select all\" in table header.\n */\nexport const TableSelectionCheckbox = forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof Checkbox>\n>(function TableSelectionCheckbox(props, ref) {\n // Aria's CheckboxContext is typed for HTMLLabelElement; we render Spark Checkbox (button).\n // We only consume context props (isSelected, isIndeterminate, onChange), ref comes from our forwardRef.\n const [mergedProps, mergedRef] = useContextProps(\n { ...props, slot: 'selection' as const },\n ref,\n CheckboxContext as any\n )\n\n const { isSelected, isIndeterminate, onChange, ...rest } = mergedProps as typeof props & {\n isSelected?: boolean\n isIndeterminate?: boolean\n onChange?: (checked: boolean) => void\n }\n\n const checked = isIndeterminate === true ? 'indeterminate' : Boolean(isSelected)\n\n return (\n <span\n onClick={e => e.stopPropagation()}\n onPointerDown={e => e.stopPropagation()}\n className=\"flex h-full min-h-full items-center justify-center\"\n >\n <Checkbox\n ref={mergedRef as React.Ref<HTMLButtonElement>}\n checked={checked}\n onCheckedChange={onChange}\n {...rest}\n />\n </span>\n )\n})\n\nTableSelectionCheckbox.displayName = 'Table.SelectionCheckbox'\n","import type { Key } from '@react-types/shared'\nimport { useContext } from 'react'\nimport { TableStateContext } from 'react-aria-components'\n\nimport { Checkbox } from '../checkbox'\nimport { TableSelectionCheckbox } from './TableSelectionCheckbox'\n\n/**\n * Header \"select all\" checkbox that bases its checked/indeterminate state only\n * on the currently visible (rendered) rows. So when the user changes page in a\n * paginated table, the header shows unchecked instead of indeterminate when no\n * visible row is selected.\n *\n * Renders the Checkbox directly and calls selectionManager.toggleSelectAll() so\n * we fully control the displayed state instead of overriding React Aria's context.\n */\nexport function TableHeaderSelectionCheckbox() {\n const tableState = useContext(TableStateContext)\n\n if (!tableState) {\n return <TableSelectionCheckbox />\n }\n\n const { collection, selectionManager } = tableState\n const selectedKeys = selectionManager.selectedKeys\n\n // Visible row keys: only the body row keys (currently rendered rows).\n // TableCollection has a body node whose children are the rows.\n const collectionWithBody = collection as unknown as {\n body?: { key: Key }\n getChildren: (key: Key) => Iterable<{ key: Key }>\n getKeys: () => IterableIterator<Key>\n }\n const bodyNode = collectionWithBody.body\n const visibleRowKeys =\n bodyNode != null\n ? new Set<Key>([...collectionWithBody.getChildren(bodyNode.key)].map(node => node.key))\n : new Set<Key>(collection.getKeys())\n\n const keysSet = (selectedKeys as unknown) === 'all' ? visibleRowKeys : (selectedKeys as Set<Key>)\n const selectedVisibleCount = [...visibleRowKeys].filter(key => keysSet.has(key)).length\n const visibleCount = visibleRowKeys.size\n\n const isAllSelected = visibleCount > 0 && selectedVisibleCount === visibleCount\n const isIndeterminate = selectedVisibleCount > 0 && selectedVisibleCount < visibleCount\n\n const checked = isIndeterminate ? 'indeterminate' : isAllSelected\n\n return (\n <span\n onClick={e => e.stopPropagation()}\n onPointerDown={e => e.stopPropagation()}\n className=\"flex h-full min-h-full items-center justify-center\"\n >\n <Checkbox\n checked={checked}\n onCheckedChange={() => {\n selectionManager.toggleSelectAll()\n }}\n />\n </span>\n )\n}\n\nTableHeaderSelectionCheckbox.displayName = 'Table.HeaderSelectionCheckbox'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Collection,\n Column as AriaColumn,\n TableHeader as AriaTableHeader,\n type TableHeaderProps as AriaTableHeaderProps,\n useTableOptions,\n} from 'react-aria-components'\n\nimport { columnStyles } from './Table.styles'\nimport { TableHeaderSelectionCheckbox } from './TableHeaderSelectionCheckbox'\n\nexport interface TableHeaderProps<T extends object = object>\n extends Omit<AriaTableHeaderProps<T>, 'className'> {\n className?: string\n /** When true (default), the header row is sticky with z-raised and top-0. */\n sticky?: boolean\n}\n\nexport function TableHeader<T extends object>({\n className,\n columns,\n children,\n sticky = true,\n ...props\n}: TableHeaderProps<T>) {\n const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions()\n\n return (\n <AriaTableHeader\n data-spark-component=\"table-header\"\n className={cx(\n [\n sticky && 'z-raised sticky top-0',\n 'text-on-neutral-container text-body-1 font-semibold',\n 'after:pt-md after:block after:size-0',\n ],\n className\n )}\n columns={columns}\n {...props}\n >\n {allowsDragging && (\n <AriaColumn width={20} minWidth={20} className=\"w-sz-20 min-w-sz-20 box-border\" />\n )}\n {selectionBehavior === 'toggle' && (\n <AriaColumn width={56} minWidth={56} className={cx(columnStyles())}>\n {selectionMode === 'multiple' && <TableHeaderSelectionCheckbox />}\n </AriaColumn>\n )}\n {columns != null ? (\n <Collection items={columns}>{children}</Collection>\n ) : (\n (children as ReactNode)\n )}\n </AriaTableHeader>\n )\n}\n\nTableHeader.displayName = 'Table.Header'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Button,\n Collection,\n Row as AriaRow,\n type RowProps as AriaRowProps,\n useTableOptions,\n} from 'react-aria-components'\n\nimport { Cell } from './TableCell'\nimport { TableSelectionCheckbox } from './TableSelectionCheckbox'\n\nexport interface RowProps<T extends object = object> extends Omit<AriaRowProps<T>, 'className'> {\n className?: string\n}\n\nexport function Row<T extends object>({ id, columns, children, className, ...props }: RowProps<T>) {\n const { selectionBehavior, allowsDragging } = useTableOptions()\n\n return (\n <AriaRow\n id={id}\n data-spark-component=\"table-row\"\n className={cx(\n 'group/row',\n 'h-sz-80', // first row: 96px so 16px gap (border-t) + 80px content\n 'group/row text-on-surface relative cursor-default select-none',\n '[-webkit-tap-highlight-color:transparent]',\n 'data-focus-visible:u-outline-inset outline-none data-focus-visible:outline-dashed',\n 'data-react-aria-pressable:hover:bg-surface-hovered data-react-aria-pressable:pressed:bg-surface-hovered',\n // Selected row styles\n 'data-selected:bg-basic-container data-selected:text-on-basic-container',\n 'data-selected:hover:bg-basic-container-hovered data-selected:data-pressed:bg-basic-container-hovered',\n // Disabled row styles\n 'data-disabled:text-on-surface/dim-3',\n // Href row styles\n 'data-href:cursor-pointer',\n className\n )}\n columns={columns}\n {...props}\n >\n {allowsDragging && (\n <Cell>\n <Button\n slot=\"drag\"\n className=\"w-sz-15 data-focus-visible:u-outline flex items-center justify-center text-center outline-none data-[focus-visible]:rounded-md\"\n >\n ≡\n </Button>\n </Cell>\n )}\n {selectionBehavior === 'toggle' && (\n <Cell checkbox>\n <TableSelectionCheckbox />\n </Cell>\n )}\n {columns != null ? (\n <Collection items={columns}>{children}</Collection>\n ) : (\n (children as ReactNode)\n )}\n </AriaRow>\n )\n}\n\nRow.displayName = 'Table.Row'\n","import { useMemo, useState } from 'react'\nimport type { SortDescriptor } from 'react-aria-components'\n\nexport interface UseTableSortOptions<T extends object> {\n /** Initial sort column and direction. */\n initialSort?: {\n column: keyof T\n direction: 'ascending' | 'descending'\n }\n /**\n * Custom compare function. If not provided, a default comparator is used:\n * - numbers: numeric comparison\n * - other: localeCompare on string representation\n */\n compare?: (a: T, b: T, column: keyof T, direction: 'ascending' | 'descending') => number\n}\n\nfunction defaultCompare<T extends object>(\n a: T,\n b: T,\n column: keyof T,\n direction: 'ascending' | 'descending'\n): number {\n const aVal = a[column]\n const bVal = b[column]\n\n if (aVal === bVal) return 0\n\n let comparisonResult: number\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparisonResult = aVal < bVal ? -1 : 1\n } else {\n comparisonResult = String(aVal).localeCompare(String(bVal))\n }\n\n return direction === 'descending' ? -comparisonResult : comparisonResult\n}\n\n/**\n * Hook to manage table sort state and derive sorted items from a list.\n * Use with Table's sortDescriptor and onSortChange props.\n *\n * @example\n * const { sortDescriptor, onSortChange, setSortDescriptor, sortedItems } = useTableSort(rows, {\n * initialSort: { column: 'name', direction: 'ascending' },\n * })\n * return (\n * <>\n * <Button onClick={() => setSortDescriptor({ column: 'name', direction: 'ascending' })}>Reset sort</Button>\n * <Table sortDescriptor={sortDescriptor} onSortChange={onSortChange}>\n * ...\n * </Table>\n * </>\n * )\n */\nexport function useTableSort<T extends object>(\n items: T[],\n options: UseTableSortOptions<T> = {}\n): {\n sortDescriptor: SortDescriptor\n onSortChange: (descriptor: SortDescriptor) => void\n /** Set sort from outside the table (e.g. a \"Reset sort\" button). */\n setSortDescriptor: (descriptor: SortDescriptor) => void\n sortedItems: T[]\n} {\n const { initialSort, compare } = options\n\n const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>(() =>\n initialSort\n ? { column: initialSort.column as string, direction: initialSort.direction }\n : { column: 'id', direction: 'ascending' }\n )\n\n const sortedItems = useMemo(() => {\n const column = sortDescriptor.column as keyof T\n if (!column) return [...items]\n\n const compareFn = compare ?? defaultCompare\n const direction = sortDescriptor.direction ?? 'ascending'\n\n return [...items].sort((a, b) => compareFn(a, b, column, direction))\n }, [items, sortDescriptor.column, sortDescriptor.direction, compare])\n\n return {\n sortDescriptor,\n onSortChange: setSortDescriptor,\n setSortDescriptor,\n sortedItems,\n }\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { Key, Selection } from 'react-aria-components'\n\nexport interface UseTablePaginationOptions<T> {\n /** Number of items per page. */\n pageSize: number\n /** Initial page index (1-based). Defaults to 1. */\n initialPage?: number\n /**\n * Function to extract a stable key from each item.\n * Defaults to `item.id` if present.\n */\n getId?: (item: T) => Key\n}\n\nexport interface UseTablePaginationResult<T> {\n /** Current page (1-based). */\n page: number\n /** Update the current page manually. */\n setPage: (page: number) => void\n /** Items sliced to the current page. */\n pageItems: T[]\n /** Total number of items. */\n totalItems: number\n /** Total number of pages (at least 1). */\n totalPages: number\n /** All item keys across all pages. */\n allKeys: Set<Key>\n /**\n * Selection state across all pages.\n * Pass to Table (root) as `selectedKeys`.\n */\n selectedKeys: Set<Key>\n /**\n * Selection change handler that keeps selection across pages.\n * Pass to Table (root) as `onSelectionChange`.\n */\n onSelectionChange: (keys: Selection) => void\n /**\n * Convenience handler matching Pagination's `onPageChange` signature:\n * `onPageChange={({ page }) => ...}`.\n */\n onPageChange: (details: { page: number }) => void\n /** Clear selection across all pages. */\n clearSelection: () => void\n}\n\n/**\n * Hook to manage simple client-side pagination and multi-page selection for Table.\n * It slices the full item list to the current page, tracks page state, and merges\n * selection across pages so that rows selected on previous pages remain selected.\n *\n * @example\n * const { page, pageItems, totalItems, allKeys, selectedKeys, onSelectionChange, onPageChange } =\n * useTablePagination(allItems, { pageSize: 10 })\n *\n * return (\n * <Table\n * selectionMode=\"multiple\"\n * selectedKeys={selectedKeys}\n * onSelectionChange={onSelectionChange}\n * totalCount={totalItems}\n * hasMultiplePages={totalItems > 10}\n * onSelectAll={() => onSelectionChange(allKeys)}\n * >\n * <Table.BulkBar>...</Table.BulkBar>\n * <Table.Grid aria-label=\"Items\">\n * <Table.Body>\n * {pageItems.map(item => (\n * <Table.Row key={item.id} id={item.id}>...</Table.Row>\n * ))}\n * </Table.Body>\n * </Table.Grid>\n * <Pagination page={page} pageSize={10} count={totalItems} onPageChange={onPageChange} />\n * </Table>\n * )\n */\nexport function useTablePagination<T>(\n items: T[],\n options: UseTablePaginationOptions<T>\n): UseTablePaginationResult<T> {\n const { pageSize, initialPage = 1, getId } = options\n\n const [page, setPage] = useState(initialPage)\n const [selectedKeys, setSelectedKeys] = useState<Set<Key>>(() => new Set())\n\n const totalItems = items.length\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize))\n\n // Clamp current page when the total page count changes (e.g. items length shrinks).\n useEffect(() => {\n setPage(current => {\n if (current < 1) return 1\n if (current > totalPages) return totalPages\n\n return current\n })\n }, [totalPages])\n\n let effectivePage = page\n if (effectivePage < 1) {\n effectivePage = 1\n } else if (effectivePage > totalPages) {\n effectivePage = totalPages\n }\n\n const pageItems = useMemo(() => {\n const start = (effectivePage - 1) * pageSize\n const end = start + pageSize\n\n return items.slice(start, end)\n }, [items, effectivePage, pageSize])\n\n const allKeys = useMemo(() => {\n const resolveId =\n getId ??\n ((item: T) => {\n const candidate = (item as unknown as { id?: Key }).id\n\n if (candidate == null) {\n throw new Error(\n 'useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.'\n )\n }\n\n return candidate\n })\n\n return new Set<Key>(items.map(item => resolveId(item)))\n }, [getId, items])\n\n const pageIds = useMemo(() => {\n const resolveId =\n getId ??\n ((item: T) => {\n const candidate = (item as unknown as { id?: Key }).id\n\n if (candidate == null) {\n throw new Error(\n 'useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.'\n )\n }\n\n return candidate\n })\n\n return new Set<Key>(pageItems.map(item => resolveId(item)))\n }, [getId, pageItems])\n\n const handleSelectionChange = (keys: Selection) => {\n // React Aria uses \"all\" to represent \"select all\" in the current context.\n // For the table header checkbox, interpret \"all\" as \"all items on the current page\".\n const newPageSelection = keys === 'all' ? new Set<Key>(pageIds) : new Set(keys as Set<Key>)\n\n setSelectedKeys(prev => {\n const next = new Set<Key>(newPageSelection)\n\n // Keep selections from other pages.\n for (const key of prev) {\n if (!pageIds.has(key)) {\n next.add(key)\n }\n }\n\n return next\n })\n }\n\n const handlePageChange = (details: { page: number }) => {\n setPage(details.page)\n }\n\n const clearSelection = () => {\n setSelectedKeys(() => new Set())\n }\n\n return {\n page: effectivePage,\n setPage,\n pageItems,\n totalItems,\n totalPages,\n allKeys,\n selectedKeys,\n onSelectionChange: handleSelectionChange,\n onPageChange: handlePageChange,\n clearSelection,\n }\n}\n","import { TableGrid, TableRootWrapper } from './Table'\nimport { TableBody } from './TableBody'\nimport {\n TableBulkBar,\n TableBulkBarClearButton,\n TableBulkBarSelectAllButton,\n TableBulkBarSelectedCount,\n} from './TableBulkBar'\nimport { Cell } from './TableCell'\nimport { Column } from './TableColumn'\nimport { TableHeader } from './TableHeader'\nimport { Row } from './TableRow'\n\nexport const TableWithSubcomponents: typeof TableRootWrapper & {\n Grid: typeof TableGrid\n Header: typeof TableHeader\n Column: typeof Column\n Body: typeof TableBody\n Row: typeof Row\n Cell: typeof Cell\n BulkBar: typeof TableBulkBar\n BulkBarSelectedCount: typeof TableBulkBarSelectedCount\n BulkBarClearButton: typeof TableBulkBarClearButton\n BulkBarSelectAllButton: typeof TableBulkBarSelectAllButton\n} = Object.assign(TableRootWrapper, {\n Grid: TableGrid,\n Header: TableHeader,\n Column,\n Body: TableBody,\n Row,\n Cell,\n BulkBar: TableBulkBar,\n BulkBarSelectedCount: TableBulkBarSelectedCount,\n BulkBarClearButton: TableBulkBarClearButton,\n BulkBarSelectAllButton: TableBulkBarSelectAllButton,\n})\n\nTableWithSubcomponents.displayName = 'Table'\nTableHeader.displayName = 'Table.Header'\nColumn.displayName = 'Table.Column'\nTableBody.displayName = 'Table.Body'\nRow.displayName = 'Table.Row'\nCell.displayName = 'Table.Cell'\n\nexport { TableWithSubcomponents as Table }\n\nexport { useTableSort } from './useTableSort'\nexport { useTablePagination } from './useTablePagination'\nexport type { SortDescriptor } from 'react-aria-components'\nexport type { UseTableSortOptions } from './useTableSort'\nexport type { UseTablePaginationOptions, UseTablePaginationResult } from './useTablePagination'\nexport { type TableGridProps, type TableProps, type TableRootWrapperProps } from './Table'\nexport { type TableHeaderProps } from './TableHeader'\nexport { type ColumnProps } from './TableColumn'\nexport { type TableBodyProps } from './TableBody'\nexport { type RowProps } from './TableRow'\nexport { type CellProps } from './TableCell'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/table/table-utils.ts","../../src/table/TableContext.tsx","../../src/table/ResizableTableContainer.tsx","../../src/table/Table.tsx","../../src/table/Table.styles.tsx","../../src/table/TableBody.tsx","../../src/table/TableBulkBar.tsx","../../src/table/TableCell.tsx","../../src/table/TableColumn.tsx","../../src/table/TableSelectionCheckbox.tsx","../../src/table/TableHeaderSelectionCheckbox.tsx","../../src/table/TableHeader.tsx","../../src/table/TableRow.tsx","../../src/table/useTableSort.ts","../../src/table/useTablePagination.ts","../../src/table/index.ts"],"sourcesContent":["/**\n * Selector for elements that have their own Space/Enter behavior (buttons, switches, inputs, etc.).\n * Used to avoid table row selection capturing these keys when focus is on an interactive cell content.\n */\nconst INTERACTIVE_SELECTOR =\n 'button, [role=\"button\"], [role=\"switch\"], [role=\"checkbox\"], [role=\"option\"], input:not([type=\"hidden\"]), select, textarea, [href]'\n\n/** Column resizer uses a hidden focusable input for keyboard resize (Enter to toggle, ArrowLeft/Right). Don't convert Enter to click there. */\nconst COLUMN_RESIZER_SELECTOR = '[data-resizable-direction]'\n\nexport function isInteractiveElement(element: EventTarget | null): element is Element {\n if (!element || !(element instanceof Element)) return false\n const el = element as Element\n\n return el.matches(INTERACTIVE_SELECTOR) || el.closest(INTERACTIVE_SELECTOR) !== null\n}\n\nexport function isColumnResizerElement(element: EventTarget | null): element is Element {\n if (!element || !(element instanceof Element)) return false\n\n return (element as Element).closest(COLUMN_RESIZER_SELECTOR) !== null\n}\n","import { createContext, useContext } from 'react'\nimport type { Selection } from 'react-aria-components'\nimport type { SortDescriptor } from 'react-aria-components'\n\nimport type { ResizableTableContainerProps } from './ResizableTableContainer'\n\nexport interface TableResizableContextValue {\n isResizable: boolean\n}\n\nexport const TableResizableContext = createContext<TableResizableContextValue>({\n isResizable: false,\n})\n\nexport function useTableResizableContext() {\n return useContext(TableResizableContext)\n}\n\n/** Values provided by Table (root) and consumed by Table.Grid and Table.BulkBar. */\nexport interface TableContextValue\n extends Pick<ResizableTableContainerProps, 'onResizeStart' | 'onResize' | 'onResizeEnd'> {\n // Selection (optional when table has no selection)\n selectionMode?: 'none' | 'single' | 'multiple'\n selectionBehavior?: 'toggle' | 'replace'\n selectedKeys?: Selection\n onSelectionChange?: (keys: Selection) => void\n // BulkBar: optional when not using BulkBar\n totalCount?: number\n hasMultiplePages?: boolean\n onSelectAll?: () => void\n // Derived for BulkBar (from selectedKeys + onSelectionChange)\n selectedCount: number\n onClearSelection: () => void\n // Layout / grid\n allowsResizing?: boolean\n maxHeight?: number | string\n onKeyDownCapture?: React.KeyboardEventHandler<Element>\n sortDescriptor?: SortDescriptor\n onSortChange?: (descriptor: SortDescriptor) => void\n className?: string\n // Pass-through for AriaTable (aria-label, etc.)\n [key: string]: unknown\n}\n\nconst defaultTableContextValue: TableContextValue = {\n selectedCount: 0,\n onClearSelection: () => {},\n}\n\nexport const TableContext = createContext<TableContextValue>(defaultTableContextValue)\n\nexport function useTableContext(): TableContextValue {\n return useContext(TableContext)\n}\n","import { cx } from 'class-variance-authority'\nimport type { ComponentProps } from 'react'\nimport { useLayoutEffect, useRef } from 'react'\nimport { ResizableTableContainer as AriaResizableTableContainer } from 'react-aria-components'\n\nimport { isColumnResizerElement, isInteractiveElement } from './table-utils'\nimport { TableResizableContext } from './TableContext'\n\nexport interface ResizableTableContainerProps\n extends Omit<ComponentProps<typeof AriaResizableTableContainer>, 'className'> {\n className?: string\n}\n\nexport function ResizableTableContainer({\n className,\n children,\n ...props\n}: ResizableTableContainerProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n\n useLayoutEffect(() => {\n const el = containerRef.current\n if (!el) return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== ' ' && e.key !== 'Enter') return\n if (!isInteractiveElement(e.target)) return\n if (!el.contains(e.target as Node)) return\n // Column resizer uses Enter to toggle keyboard resize mode (ArrowLeft/Right to resize). Do not convert to click.\n if (isColumnResizerElement(e.target)) return\n\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n\n // Dispatch a click so the control (Switch, button, etc.) toggles/activates\n // as it would when Space/Enter is pressed natively (browser triggers click)\n const target = e.target as HTMLElement\n target.click()\n }\n\n el.addEventListener('keydown', handleKeyDown, true)\n\n return () => el.removeEventListener('keydown', handleKeyDown, true)\n }, [])\n\n return (\n <TableResizableContext.Provider value={{ isResizable: true }}>\n <AriaResizableTableContainer\n ref={containerRef}\n data-spark-component=\"resizable-table-container\"\n className={cx('relative w-full overflow-auto', className)}\n {...props}\n >\n {children}\n </AriaResizableTableContainer>\n </TableResizableContext.Provider>\n )\n}\n\nResizableTableContainer.displayName = 'ResizableTableContainer'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport { useLayoutEffect, useRef } from 'react'\nimport { Table as AriaTable, type TableProps as AriaTableProps } from 'react-aria-components'\n\nimport type { ResizableTableContainerProps } from './ResizableTableContainer'\nimport { ResizableTableContainer } from './ResizableTableContainer'\nimport { isColumnResizerElement, isInteractiveElement } from './table-utils'\nimport { TableContext, type TableContextValue, useTableContext } from './TableContext'\n\nexport interface TableProps\n extends Omit<AriaTableProps, 'className'>,\n Pick<ResizableTableContainerProps, 'onResizeStart' | 'onResize' | 'onResizeEnd'> {\n className?: string\n onKeyDownCapture?: React.KeyboardEventHandler<Element>\n /** When true (default), columns can be resized. Pass onResizeStart, onResize, onResizeEnd to react to resize events. */\n allowsResizing?: boolean\n /** Max height of the scroll container (number in px or CSS value). Applied so vertical and horizontal scrollbars share the same container. */\n maxHeight?: number | string\n /** For BulkBar: total number of items (e.g. for \"Select all X items\"). */\n totalCount?: number\n /** When true, BulkBar shows \"Clear all\" and \"Select all\" buttons. */\n hasMultiplePages?: boolean\n /**\n * Called when user clicks \"Clear all\" in BulkBar.\n * Useful with pagination selection models (e.g. `useTablePagination`) where clearing only the\n * current page would be incorrect.\n */\n onClearSelection?: () => void\n /** Called when user clicks \"Select all\" in BulkBar. */\n onSelectAll?: () => void\n}\n\nexport interface TableRootWrapperProps extends TableProps {\n children: ReactNode\n}\n\nexport function TableRootWrapper({\n children,\n className,\n selectedKeys,\n onSelectionChange,\n totalCount,\n hasMultiplePages,\n onClearSelection: onClearSelectionProp,\n onSelectAll,\n allowsResizing = true,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n ...restProps\n}: TableRootWrapperProps) {\n let selectedCount = 0\n\n if (selectedKeys === 'all') {\n selectedCount = totalCount ?? 0\n } else if (selectedKeys instanceof Set) {\n selectedCount = selectedKeys.size\n } else if (selectedKeys) {\n selectedCount = new Set(selectedKeys).size\n }\n const onClearSelection = onClearSelectionProp ?? (() => onSelectionChange?.(new Set()))\n\n const contextValue = {\n ...restProps,\n selectedKeys,\n onSelectionChange,\n totalCount,\n hasMultiplePages,\n onSelectAll,\n selectedCount,\n onClearSelection,\n allowsResizing,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n className,\n }\n\n return (\n <TableContext.Provider value={contextValue as TableContextValue}>\n <div className={cx('gap-md flex flex-col', className)}>{children}</div>\n </TableContext.Provider>\n )\n}\n\nTableRootWrapper.displayName = 'Table'\n\nexport const TableRoot = ({ className, onKeyDownCapture, ...props }: TableProps) => {\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // Native capture-phase listener so we run BEFORE react-aria's native listeners\n // (which handle row selection on Space/Enter). Synthetic onKeyDownCapture runs\n // too late. When focus is on an interactive element (switch, button, etc.),\n // we consume the event and trigger a click so the control activates without\n // the row being selected.\n useLayoutEffect(() => {\n const el = wrapperRef.current\n if (!el) return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== ' ' && e.key !== 'Enter') return\n if (!isInteractiveElement(e.target)) return\n if (!el.contains(e.target as Node)) return\n // Column resizer uses Enter to toggle keyboard resize mode (ArrowLeft/Right to resize). Do not convert to click.\n if (isColumnResizerElement(e.target)) return\n\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n ;(e.target as HTMLElement).click()\n }\n\n el.addEventListener('keydown', handleKeyDown, true)\n\n return () => el.removeEventListener('keydown', handleKeyDown, true)\n }, [])\n\n return (\n <AriaTable\n ref={wrapperRef}\n data-spark-component=\"table\"\n className={cx(\n 'default:w-full',\n 'border-separate border-spacing-y-0',\n 'bg-surface',\n 'outline-none',\n 'text-body-1',\n 'forced-color-adjust-none',\n 'data-focus-visible:u-outline-inset',\n 'has-[>[data-empty]]:h-full',\n className\n )}\n {...(onKeyDownCapture ? { ...props, onKeyDownCapture } : props)}\n />\n )\n}\n\nTableRoot.displayName = 'Table.Grid.Inner'\n\nfunction toMaxHeightStyle(value: number | string): React.CSSProperties['maxHeight'] {\n return typeof value === 'number' ? `${value}px` : value\n}\n\nexport interface TableGridProps {\n /** Required for accessibility. */\n 'aria-label'?: string\n 'aria-labelledby'?: string\n className?: string\n children?: ReactNode\n}\n\nexport function TableGrid({\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className: gridClassName,\n children,\n}: TableGridProps) {\n const ctx = useTableContext()\n const {\n allowsResizing = true,\n maxHeight,\n onResizeStart,\n onResize,\n onResizeEnd,\n onKeyDownCapture,\n sortDescriptor,\n onSortChange,\n className: contextClassName,\n ...ariaTableProps\n } = ctx\n\n const scrollContainerStyle =\n maxHeight != null ? { maxHeight: toMaxHeightStyle(maxHeight) } : undefined\n const className = gridClassName ?? contextClassName\n\n const tableRootProps = {\n ...ariaTableProps,\n ...(ariaLabel != null && { 'aria-label': ariaLabel }),\n ...(ariaLabelledBy != null && { 'aria-labelledby': ariaLabelledBy }),\n sortDescriptor,\n onSortChange,\n onKeyDownCapture,\n className,\n }\n\n if (allowsResizing) {\n return (\n <ResizableTableContainer\n className={className}\n style={scrollContainerStyle}\n onResizeStart={onResizeStart}\n onResize={onResize}\n onResizeEnd={onResizeEnd}\n >\n <TableRoot {...tableRootProps}>{children}</TableRoot>\n </ResizableTableContainer>\n )\n }\n\n return (\n <div className=\"relative w-full overflow-auto\" style={scrollContainerStyle}>\n <TableRoot {...tableRootProps}>{children}</TableRoot>\n </div>\n )\n}\n\nTableGrid.displayName = 'Table.Grid'\n","import { cva, type VariantProps } from 'class-variance-authority'\n\nexport const columnStyles = cva(\n [\n 'h-sz-64 min-w-sz-64',\n 'relative group/column first:rounded-l-xl last:rounded-r-xl bg-neutral-container',\n 'px-lg py-sm text-left outline-none box-border',\n 'cursor-default',\n 'data-focus-visible:u-outline data-focus-visible:-outline-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const columnHeaderContentStyles = cva(\n [\n 'flex flex-1 justify-between items-center gap-md',\n 'font-inherit text-left text-inherit',\n 'whitespace-nowrap text-ellipsis',\n 'border-transparent',\n 'data-focus-visible:u-outline data-focus-visible:outline-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const tableBodyStyles = cva(\n ['empty:italic empty:text-center empty:text-body-2 empty:py-lg'],\n {\n variants: {},\n defaultVariants: {},\n }\n)\n\nexport const cellStyles = cva(\n [\n 'p-lg outline-none box-border default:overflow-hidden',\n 'border-b-sm border-outline [tr:last-child>&]:border-b-0',\n '[-webkit-tap-highlight-color:transparent]',\n 'data-focus-visible:u-outline-inset data-focus-visible:outline-dashed',\n ],\n {\n variants: {\n /** When true, matches width + padding of the TableSelectionCheckbox header column (w-sz-64, py-sm, no horizontal padding). Use cellCheckboxInnerStyles on the inner wrapper to fill height and center content. */\n checkbox: {\n true: ['w-sz-64 py-sm px-0 align-middle'],\n },\n },\n defaultVariants: {\n checkbox: false,\n },\n }\n)\n\n/** Spacer row: 16px (md) visual gap between header and first data row. Use as first child of tbody. */\nexport const tableBodySpacerRowStyles = cva(\n [\n 'pointer-events-none',\n '[&_td]:h-sz-16 [&_td]:p-0 [&_td]:border-0 [&_td]:border-b-0 [&_td]:bg-surface [&_td]:align-middle',\n ],\n { variants: {}, defaultVariants: {} }\n)\n\nexport type ColumnStylesProps = VariantProps<typeof columnStyles>\nexport type CellStylesProps = VariantProps<typeof cellStyles>\n","import { cx } from 'class-variance-authority'\nimport {\n TableBody as AriaTableBody,\n type TableBodyProps as AriaTableBodyProps,\n} from 'react-aria-components'\n\nimport { tableBodyStyles } from './Table.styles'\n\nexport interface TableBodyProps<T extends object = object>\n extends Omit<AriaTableBodyProps<T>, 'className'> {\n className?: string\n}\n\nexport function TableBody<T extends object>({\n className,\n renderEmptyState,\n ...props\n}: TableBodyProps<T>) {\n const wrappedRenderEmptyState: AriaTableBodyProps<T>['renderEmptyState'] =\n renderEmptyState != null\n ? renderProps => (\n <div data-spark-component=\"table-empty\" className=\"p-lg\">\n {renderEmptyState(renderProps)}\n </div>\n )\n : undefined\n\n return (\n <AriaTableBody\n data-spark-component=\"table-body\"\n className={cx(tableBodyStyles(), className)}\n renderEmptyState={wrappedRenderEmptyState}\n {...props}\n />\n )\n}\n\nTableBody.displayName = 'Table.Body'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport { createContext, useContext } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { useTableContext } from './TableContext'\n\ninterface TableBulkBarContextValue {\n selectedCount: number\n totalCount?: number\n onClearSelection: () => void\n onSelectAll?: () => void\n /** When true, \"Clear all\" and \"Select all\" are shown (subject to their own conditions). */\n hasMultiplePages?: boolean\n}\n\nconst TableBulkBarContext = createContext<TableBulkBarContextValue | null>(null)\n\nfunction useTableBulkBarContext() {\n const ctx = useContext(TableBulkBarContext)\n\n if (!ctx) {\n throw new Error('Table.BulkBar subcomponents must be used within Table.BulkBar')\n }\n\n return ctx\n}\n\nexport interface TableBulkBarProps {\n children: ReactNode\n className?: string\n}\n\nfunction TableBulkBarRoot({ children, className }: TableBulkBarProps) {\n const { selectedCount, totalCount, onClearSelection, onSelectAll, hasMultiplePages } =\n useTableContext()\n\n const contextValue: TableBulkBarContextValue = {\n selectedCount,\n totalCount,\n onClearSelection,\n onSelectAll,\n hasMultiplePages,\n }\n\n return (\n <TableBulkBarContext.Provider value={contextValue}>\n <div\n role=\"toolbar\"\n aria-label=\"Table bulk actions\"\n data-spark-component=\"table-bulk-bar\"\n className={cx(\n 'gap-lg min-h-sz-64 flex w-full flex-wrap items-center justify-between',\n 'rounded-lg',\n 'bg-support-container text-on-support-container p-lg',\n className\n )}\n >\n {children}\n </div>\n </TableBulkBarContext.Provider>\n )\n}\n\nfunction TableBulkBarSelectedCount({ children }: { children: ReactNode }) {\n useTableBulkBarContext() // enforce usage within BulkBar\n\n return <span className=\"text-body-1 font-bold\">{children}</span>\n}\n\ntype BulkBarButtonProps = Omit<ButtonProps, 'onClick'>\n\nfunction TableBulkBarClearButton({ className, children, ...props }: BulkBarButtonProps) {\n const { selectedCount, onClearSelection, hasMultiplePages } = useTableBulkBarContext()\n\n if (!hasMultiplePages) {\n return null\n }\n\n const ariaDisabled = selectedCount === 0\n\n return (\n <Button\n size=\"sm\"\n design=\"ghost\"\n intent=\"support\"\n underline\n ariaDisabled={ariaDisabled}\n onClick={onClearSelection}\n className={cx('text-body-2', className)}\n {...props}\n >\n {children}\n </Button>\n )\n}\n\nfunction TableBulkBarSelectAllButton({ className, children, ...props }: BulkBarButtonProps) {\n const { selectedCount, totalCount, onSelectAll, hasMultiplePages } = useTableBulkBarContext()\n\n if (!hasMultiplePages) {\n return null\n }\n\n const ariaDisabled = totalCount == null || onSelectAll == null || selectedCount >= totalCount\n\n return (\n <Button\n size=\"sm\"\n design=\"ghost\"\n intent=\"support\"\n underline\n ariaDisabled={ariaDisabled}\n onClick={onSelectAll}\n className={cx('text-body-2', className)}\n {...props}\n >\n {children}\n </Button>\n )\n}\n\nTableBulkBarRoot.displayName = 'Table.BulkBar'\n\nexport const TableBulkBar = TableBulkBarRoot\nTableBulkBar.displayName = 'Table.BulkBar'\n\nexport { TableBulkBarSelectedCount, TableBulkBarClearButton, TableBulkBarSelectAllButton }\nTableBulkBarSelectedCount.displayName = 'Table.BulkBarSelectedCount'\nTableBulkBarClearButton.displayName = 'Table.BulkBarClearButton'\nTableBulkBarSelectAllButton.displayName = 'Table.BulkBarSelectAllButton'\n","import { cx } from 'class-variance-authority'\nimport { Cell as AriaCell, type CellProps as AriaCellProps } from 'react-aria-components'\n\nimport { cellStyles } from './Table.styles'\nimport { isInteractiveElement } from './table-utils'\n\nexport interface CellProps extends Omit<AriaCellProps, 'className'> {\n className?: string\n /** When true, cell uses same width + padding as the TableSelectionCheckbox header column. */\n checkbox?: boolean\n}\n\nexport function Cell({ className, checkbox, onClick, onPointerDown, ...props }: CellProps) {\n const stopIfInteractive = (e: React.MouseEvent | React.PointerEvent) => {\n if (isInteractiveElement(e.target)) e.stopPropagation()\n }\n\n return (\n <AriaCell\n data-spark-component=\"table-cell\"\n className={cx(cellStyles({ checkbox }), className)}\n onClick={e => {\n stopIfInteractive(e)\n onClick?.(e)\n }}\n onPointerDown={e => {\n stopIfInteractive(e)\n onPointerDown?.(e)\n }}\n {...props}\n />\n )\n}\n\nCell.displayName = 'Table.Cell'\n","import { Icon } from '@spark-ui/components/icon'\nimport { ArrowUp } from '@spark-ui/icons/ArrowUp'\nimport { Sort } from '@spark-ui/icons/Sort'\nimport { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Column as AriaColumn,\n type ColumnProps as AriaColumnProps,\n type ColumnRenderProps,\n ColumnResizer,\n composeRenderProps,\n Group,\n} from 'react-aria-components'\n\nimport { columnStyles } from './Table.styles'\nimport { isInteractiveElement } from './table-utils'\nimport { useTableResizableContext } from './TableContext'\n\nexport interface ColumnProps extends Omit<AriaColumnProps, 'className'> {\n className?: string\n children?: AriaColumnProps['children']\n label: string\n /** When false, the column cannot be resized. When true or omitted, the column can be resized when the Table has allowsResizing. */\n allowsResizing?: boolean\n}\n\nexport function Column({\n className,\n label,\n children,\n allowsResizing = true,\n minWidth = 120,\n ...props\n}: ColumnProps) {\n const { isResizable } = useTableResizableContext()\n\n const childrenOrRenderFn = children as\n | ReactNode\n | ((renderProps: ColumnRenderProps & { defaultChildren?: ReactNode }) => ReactNode)\n\n return (\n <AriaColumn\n data-spark-component=\"table-column\"\n className={cx(columnStyles(), className)}\n minWidth={minWidth} // necessary to avoid resizing overlapping visual elements\n {...props}\n >\n {composeRenderProps(childrenOrRenderFn, (content, renderProps) => {\n const { allowsSorting, sortDirection } = renderProps\n\n const stopIfInteractive = (e: React.MouseEvent | React.PointerEvent) => {\n if (isInteractiveElement(e.target)) e.stopPropagation()\n }\n\n return (\n <>\n <Group\n role=\"presentation\"\n tabIndex={-1}\n className={cx(\n 'border-transparent',\n 'focus-visible:u-outline focus-visible:outline-offset-2',\n 'gap-sm box-border flex flex-1 items-center'\n )}\n onClick={stopIfInteractive}\n onPointerDown={stopIfInteractive}\n >\n <div className=\"gap-md flex min-w-0 shrink items-center\">\n <p className=\"truncate\">{label}</p>\n\n {children && (\n <div className=\"inline-flex shrink-0 items-center\">\n {typeof content === 'function'\n ? (\n content as (\n props: ColumnRenderProps & { defaultChildren?: ReactNode }\n ) => ReactNode\n )({ ...renderProps, defaultChildren: undefined })\n : content}\n </div>\n )}\n </div>\n\n {allowsSorting && (\n <span className=\"size-sz-32 ml-auto inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full\">\n <Icon size=\"sm\" className={cx(sortDirection === 'descending' && 'rotate-180')}>\n {sortDirection ? <ArrowUp /> : <Sort />}\n </Icon>\n </span>\n )}\n </Group>\n\n {isResizable && allowsResizing && !props.width && (\n <ColumnResizer\n className={cx(\n 'z-raised absolute top-0 right-[-8px]',\n 'group-last/column:hidden',\n 'h-full w-[16px] touch-none',\n 'mx-0 cursor-col-resize',\n 'data-focus-visible:after:u-outline',\n 'data-resizing:after:bg-outline-high after:transition-transform after:duration-200 data-resizing:after:scale-125',\n 'after:h-sz-32 after:bg-outline after:absolute after:top-1/2 after:left-1/2 after:w-[2px] after:-translate-y-1/2'\n )}\n />\n )}\n </>\n )\n })}\n </AriaColumn>\n )\n}\n\nColumn.displayName = 'Table.Column'\n","import { forwardRef } from 'react'\nimport { CheckboxContext, useContextProps } from 'react-aria-components'\n\nimport { Checkbox } from '../checkbox'\n\n/**\n * Adapter that receives table selection state from React Aria's CheckboxContext\n * and renders Spark Checkbox. Used for row selection and \"select all\" in table header.\n */\nexport const TableSelectionCheckbox = forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof Checkbox>\n>(function TableSelectionCheckbox(props, ref) {\n // Aria's CheckboxContext is typed for HTMLLabelElement; we render Spark Checkbox (button).\n // We only consume context props (isSelected, isIndeterminate, onChange), ref comes from our forwardRef.\n const [mergedProps, mergedRef] = useContextProps(\n { ...props, slot: 'selection' as const },\n ref,\n CheckboxContext as any\n )\n\n const { isSelected, isIndeterminate, onChange, ...rest } = mergedProps as typeof props & {\n isSelected?: boolean\n isIndeterminate?: boolean\n onChange?: (checked: boolean) => void\n }\n\n const checked = isIndeterminate === true ? 'indeterminate' : Boolean(isSelected)\n\n return (\n <span\n onClick={e => e.stopPropagation()}\n onPointerDown={e => e.stopPropagation()}\n className=\"flex h-full min-h-full items-center justify-center\"\n >\n <Checkbox\n ref={mergedRef as React.Ref<HTMLButtonElement>}\n checked={checked}\n onCheckedChange={onChange}\n {...rest}\n />\n </span>\n )\n})\n\nTableSelectionCheckbox.displayName = 'Table.SelectionCheckbox'\n","import type { Key } from '@react-types/shared'\nimport { useContext } from 'react'\nimport { TableStateContext } from 'react-aria-components'\n\nimport { Checkbox } from '../checkbox'\nimport { TableSelectionCheckbox } from './TableSelectionCheckbox'\n\n/**\n * Header \"select all\" checkbox that bases its checked/indeterminate state only\n * on the currently visible (rendered) rows. So when the user changes page in a\n * paginated table, the header shows unchecked instead of indeterminate when no\n * visible row is selected.\n *\n * Renders the Checkbox directly and calls selectionManager.toggleSelectAll() so\n * we fully control the displayed state instead of overriding React Aria's context.\n */\nexport function TableHeaderSelectionCheckbox() {\n const tableState = useContext(TableStateContext)\n\n if (!tableState) {\n return <TableSelectionCheckbox />\n }\n\n const { collection, selectionManager } = tableState\n const selectedKeys = selectionManager.selectedKeys\n\n // Visible row keys: only the body row keys (currently rendered rows).\n // TableCollection has a body node whose children are the rows.\n const collectionWithBody = collection as unknown as {\n body?: { key: Key }\n getChildren: (key: Key) => Iterable<{ key: Key }>\n getKeys: () => IterableIterator<Key>\n }\n const bodyNode = collectionWithBody.body\n const visibleRowKeys =\n bodyNode != null\n ? new Set<Key>([...collectionWithBody.getChildren(bodyNode.key)].map(node => node.key))\n : new Set<Key>(collection.getKeys())\n\n const keysSet = (selectedKeys as unknown) === 'all' ? visibleRowKeys : (selectedKeys as Set<Key>)\n const selectedVisibleCount = [...visibleRowKeys].filter(key => keysSet.has(key)).length\n const visibleCount = visibleRowKeys.size\n\n const isAllSelected = visibleCount > 0 && selectedVisibleCount === visibleCount\n const isIndeterminate = selectedVisibleCount > 0 && selectedVisibleCount < visibleCount\n\n const checked = isIndeterminate ? 'indeterminate' : isAllSelected\n\n return (\n <span\n onClick={e => e.stopPropagation()}\n onPointerDown={e => e.stopPropagation()}\n className=\"flex h-full min-h-full items-center justify-center\"\n >\n <Checkbox\n checked={checked}\n onCheckedChange={() => {\n selectionManager.toggleSelectAll()\n }}\n />\n </span>\n )\n}\n\nTableHeaderSelectionCheckbox.displayName = 'Table.HeaderSelectionCheckbox'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Collection,\n Column as AriaColumn,\n TableHeader as AriaTableHeader,\n type TableHeaderProps as AriaTableHeaderProps,\n useTableOptions,\n} from 'react-aria-components'\n\nimport { columnStyles } from './Table.styles'\nimport { TableHeaderSelectionCheckbox } from './TableHeaderSelectionCheckbox'\n\nexport interface TableHeaderProps<T extends object = object>\n extends Omit<AriaTableHeaderProps<T>, 'className'> {\n className?: string\n /** When true (default), the header row is sticky with z-raised and top-0. */\n sticky?: boolean\n}\n\nexport function TableHeader<T extends object>({\n className,\n columns,\n children,\n sticky = true,\n ...props\n}: TableHeaderProps<T>) {\n const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions()\n\n return (\n <AriaTableHeader\n data-spark-component=\"table-header\"\n className={cx(\n [\n sticky && 'z-raised sticky top-0',\n 'text-on-neutral-container text-body-1 font-semibold',\n 'after:pt-md after:block after:size-0',\n ],\n className\n )}\n columns={columns}\n {...props}\n >\n {allowsDragging && (\n <AriaColumn width={20} minWidth={20} className=\"w-sz-20 min-w-sz-20 box-border\" />\n )}\n {selectionBehavior === 'toggle' && (\n <AriaColumn width={56} minWidth={56} className={cx(columnStyles())}>\n {selectionMode === 'multiple' && <TableHeaderSelectionCheckbox />}\n </AriaColumn>\n )}\n {columns != null ? (\n <Collection items={columns}>{children}</Collection>\n ) : (\n (children as ReactNode)\n )}\n </AriaTableHeader>\n )\n}\n\nTableHeader.displayName = 'Table.Header'\n","import { cx } from 'class-variance-authority'\nimport type { ReactNode } from 'react'\nimport {\n Button,\n Collection,\n Row as AriaRow,\n type RowProps as AriaRowProps,\n useTableOptions,\n} from 'react-aria-components'\n\nimport { Cell } from './TableCell'\nimport { TableSelectionCheckbox } from './TableSelectionCheckbox'\n\nexport interface RowProps<T extends object = object> extends Omit<AriaRowProps<T>, 'className'> {\n className?: string\n}\n\nexport function Row<T extends object>({ id, columns, children, className, ...props }: RowProps<T>) {\n const { selectionBehavior, allowsDragging } = useTableOptions()\n\n return (\n <AriaRow\n id={id}\n data-spark-component=\"table-row\"\n className={cx(\n 'group/row',\n 'h-sz-80', // first row: 96px so 16px gap (border-t) + 80px content\n 'group/row text-on-surface relative cursor-default select-none',\n '[-webkit-tap-highlight-color:transparent]',\n 'data-focus-visible:u-outline-inset outline-none data-focus-visible:outline-dashed',\n 'data-react-aria-pressable:hover:bg-surface-hovered data-react-aria-pressable:pressed:bg-surface-hovered',\n // Selected row styles\n 'data-selected:bg-support-container data-selected:text-on-support-container',\n 'data-selected:hover:bg-support-container-hovered data-selected:data-pressed:bg-support-container-hovered',\n // Disabled row styles\n 'data-disabled:text-on-surface/dim-3',\n // Href row styles\n 'data-href:cursor-pointer',\n className\n )}\n columns={columns}\n {...props}\n >\n {allowsDragging && (\n <Cell>\n <Button\n slot=\"drag\"\n className=\"w-sz-15 data-focus-visible:u-outline flex items-center justify-center text-center outline-none data-[focus-visible]:rounded-md\"\n >\n ≡\n </Button>\n </Cell>\n )}\n {selectionBehavior === 'toggle' && (\n <Cell checkbox>\n <TableSelectionCheckbox />\n </Cell>\n )}\n {columns != null ? (\n <Collection items={columns}>{children}</Collection>\n ) : (\n (children as ReactNode)\n )}\n </AriaRow>\n )\n}\n\nRow.displayName = 'Table.Row'\n","import { useMemo, useState } from 'react'\nimport type { SortDescriptor } from 'react-aria-components'\n\nexport interface UseTableSortOptions<T extends object> {\n /** Initial sort column and direction. */\n initialSort?: {\n column: keyof T\n direction: 'ascending' | 'descending'\n }\n /**\n * Custom compare function. If not provided, a default comparator is used:\n * - numbers: numeric comparison\n * - other: localeCompare on string representation\n */\n compare?: (a: T, b: T, column: keyof T, direction: 'ascending' | 'descending') => number\n}\n\nfunction defaultCompare<T extends object>(\n a: T,\n b: T,\n column: keyof T,\n direction: 'ascending' | 'descending'\n): number {\n const aVal = a[column]\n const bVal = b[column]\n\n if (aVal === bVal) return 0\n\n let comparisonResult: number\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparisonResult = aVal < bVal ? -1 : 1\n } else {\n comparisonResult = String(aVal).localeCompare(String(bVal))\n }\n\n return direction === 'descending' ? -comparisonResult : comparisonResult\n}\n\n/**\n * Hook to manage table sort state and derive sorted items from a list.\n * Use with Table's sortDescriptor and onSortChange props.\n *\n * @example\n * const { sortDescriptor, onSortChange, setSortDescriptor, sortedItems } = useTableSort(rows, {\n * initialSort: { column: 'name', direction: 'ascending' },\n * })\n * return (\n * <>\n * <Button onClick={() => setSortDescriptor({ column: 'name', direction: 'ascending' })}>Reset sort</Button>\n * <Table sortDescriptor={sortDescriptor} onSortChange={onSortChange}>\n * ...\n * </Table>\n * </>\n * )\n */\nexport function useTableSort<T extends object>(\n items: T[],\n options: UseTableSortOptions<T> = {}\n): {\n sortDescriptor: SortDescriptor\n onSortChange: (descriptor: SortDescriptor) => void\n /** Set sort from outside the table (e.g. a \"Reset sort\" button). */\n setSortDescriptor: (descriptor: SortDescriptor) => void\n sortedItems: T[]\n} {\n const { initialSort, compare } = options\n\n const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>(() =>\n initialSort\n ? { column: initialSort.column as string, direction: initialSort.direction }\n : { column: 'id', direction: 'ascending' }\n )\n\n const sortedItems = useMemo(() => {\n const column = sortDescriptor.column as keyof T\n if (!column) return [...items]\n\n const compareFn = compare ?? defaultCompare\n const direction = sortDescriptor.direction ?? 'ascending'\n\n return [...items].sort((a, b) => compareFn(a, b, column, direction))\n }, [items, sortDescriptor.column, sortDescriptor.direction, compare])\n\n return {\n sortDescriptor,\n onSortChange: setSortDescriptor,\n setSortDescriptor,\n sortedItems,\n }\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { Key, Selection } from 'react-aria-components'\n\nexport interface UseTablePaginationOptions<T> {\n /** Number of items per page. */\n pageSize: number\n /** Initial page index (1-based). Defaults to 1. */\n initialPage?: number\n /**\n * Function to extract a stable key from each item.\n * Defaults to `item.id` if present.\n */\n getId?: (item: T) => Key\n}\n\nexport interface UseTablePaginationResult<T> {\n /** Current page (1-based). */\n page: number\n /** Update the current page manually. */\n setPage: (page: number) => void\n /** Items sliced to the current page. */\n pageItems: T[]\n /** Total number of items. */\n totalItems: number\n /** Total number of pages (at least 1). */\n totalPages: number\n /** All item keys across all pages. */\n allKeys: Set<Key>\n /**\n * Selection state across all pages.\n * Pass to Table (root) as `selectedKeys`.\n */\n selectedKeys: Set<Key>\n /**\n * Selection change handler that keeps selection across pages.\n * Pass to Table (root) as `onSelectionChange`.\n */\n onSelectionChange: (keys: Selection) => void\n /**\n * Convenience handler matching Pagination's `onPageChange` signature:\n * `onPageChange={({ page }) => ...}`.\n */\n onPageChange: (details: { page: number }) => void\n /** Clear selection across all pages. */\n clearSelection: () => void\n}\n\n/**\n * Hook to manage simple client-side pagination and multi-page selection for Table.\n * It slices the full item list to the current page, tracks page state, and merges\n * selection across pages so that rows selected on previous pages remain selected.\n *\n * @example\n * const { page, pageItems, totalItems, allKeys, selectedKeys, onSelectionChange, onPageChange } =\n * useTablePagination(allItems, { pageSize: 10 })\n *\n * return (\n * <Table\n * selectionMode=\"multiple\"\n * selectedKeys={selectedKeys}\n * onSelectionChange={onSelectionChange}\n * totalCount={totalItems}\n * hasMultiplePages={totalItems > 10}\n * onSelectAll={() => onSelectionChange(allKeys)}\n * >\n * <Table.BulkBar>...</Table.BulkBar>\n * <Table.Grid aria-label=\"Items\">\n * <Table.Body>\n * {pageItems.map(item => (\n * <Table.Row key={item.id} id={item.id}>...</Table.Row>\n * ))}\n * </Table.Body>\n * </Table.Grid>\n * <Pagination page={page} pageSize={10} count={totalItems} onPageChange={onPageChange} />\n * </Table>\n * )\n */\nexport function useTablePagination<T>(\n items: T[],\n options: UseTablePaginationOptions<T>\n): UseTablePaginationResult<T> {\n const { pageSize, initialPage = 1, getId } = options\n\n const [page, setPage] = useState(initialPage)\n const [selectedKeys, setSelectedKeys] = useState<Set<Key>>(() => new Set())\n\n const totalItems = items.length\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize))\n\n // Clamp current page when the total page count changes (e.g. items length shrinks).\n useEffect(() => {\n setPage(current => {\n if (current < 1) return 1\n if (current > totalPages) return totalPages\n\n return current\n })\n }, [totalPages])\n\n let effectivePage = page\n if (effectivePage < 1) {\n effectivePage = 1\n } else if (effectivePage > totalPages) {\n effectivePage = totalPages\n }\n\n const pageItems = useMemo(() => {\n const start = (effectivePage - 1) * pageSize\n const end = start + pageSize\n\n return items.slice(start, end)\n }, [items, effectivePage, pageSize])\n\n const allKeys = useMemo(() => {\n const resolveId =\n getId ??\n ((item: T) => {\n const candidate = (item as unknown as { id?: Key }).id\n\n if (candidate == null) {\n throw new Error(\n 'useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.'\n )\n }\n\n return candidate\n })\n\n return new Set<Key>(items.map(item => resolveId(item)))\n }, [getId, items])\n\n const pageIds = useMemo(() => {\n const resolveId =\n getId ??\n ((item: T) => {\n const candidate = (item as unknown as { id?: Key }).id\n\n if (candidate == null) {\n throw new Error(\n 'useTablePagination: item.id is undefined. Provide a `getId` option to extract a stable key.'\n )\n }\n\n return candidate\n })\n\n return new Set<Key>(pageItems.map(item => resolveId(item)))\n }, [getId, pageItems])\n\n const handleSelectionChange = (keys: Selection) => {\n // React Aria uses \"all\" to represent \"select all\" in the current context.\n // For the table header checkbox, interpret \"all\" as \"all items on the current page\".\n const newPageSelection = keys === 'all' ? new Set<Key>(pageIds) : new Set(keys as Set<Key>)\n\n setSelectedKeys(prev => {\n const next = new Set<Key>(newPageSelection)\n\n // Keep selections from other pages.\n for (const key of prev) {\n if (!pageIds.has(key)) {\n next.add(key)\n }\n }\n\n return next\n })\n }\n\n const handlePageChange = (details: { page: number }) => {\n setPage(details.page)\n }\n\n const clearSelection = () => {\n setSelectedKeys(() => new Set())\n }\n\n return {\n page: effectivePage,\n setPage,\n pageItems,\n totalItems,\n totalPages,\n allKeys,\n selectedKeys,\n onSelectionChange: handleSelectionChange,\n onPageChange: handlePageChange,\n clearSelection,\n }\n}\n","import { TableGrid, TableRootWrapper } from './Table'\nimport { TableBody } from './TableBody'\nimport {\n TableBulkBar,\n TableBulkBarClearButton,\n TableBulkBarSelectAllButton,\n TableBulkBarSelectedCount,\n} from './TableBulkBar'\nimport { Cell } from './TableCell'\nimport { Column } from './TableColumn'\nimport { TableHeader } from './TableHeader'\nimport { Row } from './TableRow'\n\nexport const TableWithSubcomponents: typeof TableRootWrapper & {\n Grid: typeof TableGrid\n Header: typeof TableHeader\n Column: typeof Column\n Body: typeof TableBody\n Row: typeof Row\n Cell: typeof Cell\n BulkBar: typeof TableBulkBar\n BulkBarSelectedCount: typeof TableBulkBarSelectedCount\n BulkBarClearButton: typeof TableBulkBarClearButton\n BulkBarSelectAllButton: typeof TableBulkBarSelectAllButton\n} = Object.assign(TableRootWrapper, {\n Grid: TableGrid,\n Header: TableHeader,\n Column,\n Body: TableBody,\n Row,\n Cell,\n BulkBar: TableBulkBar,\n BulkBarSelectedCount: TableBulkBarSelectedCount,\n BulkBarClearButton: TableBulkBarClearButton,\n BulkBarSelectAllButton: TableBulkBarSelectAllButton,\n})\n\nTableWithSubcomponents.displayName = 'Table'\nTableHeader.displayName = 'Table.Header'\nColumn.displayName = 'Table.Column'\nTableBody.displayName = 'Table.Body'\nRow.displayName = 'Table.Row'\nCell.displayName = 'Table.Cell'\n\nexport { TableWithSubcomponents as Table }\n\nexport { useTableSort } from './useTableSort'\nexport { useTablePagination } from './useTablePagination'\nexport type { SortDescriptor } from 'react-aria-components'\nexport type { UseTableSortOptions } from './useTableSort'\nexport type { UseTablePaginationOptions, UseTablePaginationResult } from './useTablePagination'\nexport { type TableGridProps, type TableProps, type TableRootWrapperProps } from './Table'\nexport { type TableHeaderProps } from './TableHeader'\nexport { type ColumnProps } from './TableColumn'\nexport { type TableBodyProps } from './TableBody'\nexport { type RowProps } from './TableRow'\nexport { type CellProps } from './TableCell'\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spark-ui/components",
3
- "version": "17.3.0",
3
+ "version": "17.3.1",
4
4
  "license": "MIT",
5
5
  "description": "Spark (Leboncoin design system) components.",
6
6
  "exports": {
@@ -53,9 +53,9 @@
53
53
  "@react-aria/toast": "^3.0.0-beta.18",
54
54
  "@react-stately/numberfield": "3.9.11",
55
55
  "@react-stately/toast": "^3.0.0-beta.7",
56
- "@spark-ui/hooks": "^17.3.0",
57
- "@spark-ui/icons": "^17.3.0",
58
- "@spark-ui/internal-utils": "^17.3.0",
56
+ "@spark-ui/hooks": "^17.3.1",
57
+ "@spark-ui/icons": "^17.3.1",
58
+ "@spark-ui/internal-utils": "^17.3.1",
59
59
  "@zag-js/pagination": "1.30.0",
60
60
  "@zag-js/react": "1.30.0",
61
61
  "class-variance-authority": "0.7.1",