@mendylanda/ui 0.3.0-alpha.6 → 0.3.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/dist/class-names.js +1 -1
- package/dist/filters/filter-bar.d.ts +1 -1
- package/dist/filters/filter-bar.js +38 -6
- package/dist/filters/filter-menu-focus.d.ts +1 -1
- package/dist/filters/filter-menu-panel.d.ts +1 -1
- package/dist/filters/use-menu-placement.d.ts +1 -1
- package/dist/styles.css +3 -10
- package/dist/styles.tailwind3.css +3 -10
- package/dist/table/clipboard.d.ts +1 -1
- package/dist/table/clipboard.js +1 -1
- package/dist/table/data-table.d.ts +3 -0
- package/dist/table/data-table.js +3 -2
- package/dist/table/index.d.ts +1 -0
- package/dist/table/index.js +1 -0
- package/dist/table/table-feedback.d.ts +5 -1
- package/dist/table/table-feedback.js +4 -3
- package/dist/table/table-filters.d.ts +8 -0
- package/dist/table/table-filters.js +9 -0
- package/dist/table/table-parts.d.ts +7 -1
- package/dist/table/table-parts.js +19 -5
- package/dist/table/table-view.d.ts +13 -2
- package/dist/table/table-view.js +21 -11
- package/dist/table/use-column-window.d.ts +1 -1
- package/dist/table/use-column-window.js +4 -3
- package/dist/table/use-data-table.d.ts +1 -1
- package/dist/table/use-stable-array.d.ts +1 -0
- package/dist/table/use-stable-array.js +0 -1
- package/dist/table/use-table-interaction.d.ts +1 -1
- package/dist/table/use-table-interaction.js +8 -3
- package/dist/table/use-table-results.d.ts +8 -0
- package/dist/table/use-table-results.js +63 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ Opening the menu shows the category list without choosing a filter. Focusing a c
|
|
|
82
82
|
|
|
83
83
|
### Defaults and clearing
|
|
84
84
|
|
|
85
|
-
`FilterBar` and composed `FilterList`
|
|
85
|
+
`FilterBar` and composed `FilterList` show Clear all after the chips when a removable filter is active. It clears filters and search. Search-only bars use the input’s clear control and hide the filter menu when no menu fields are available. Set `showClear={false}` to opt out. Choice search is enabled by default; use `searchable: false` for short lists. Menu selections keep the menu open, and selecting the current single choice again clears it. Chip editor popups open instantly; `editorAnimation` opts into their animation.
|
|
86
86
|
|
|
87
87
|
See [defaults and app configuration](https://ui.mendylanda.com/docs/defaults) for the full behavior and [system reference](https://ui.mendylanda.com/docs/system) for query adapters, selected-label loading, grouped fields, and custom editors.
|
|
88
88
|
|
|
@@ -106,4 +106,21 @@ export function Projects({ rows }: { rows: Project[] }) {
|
|
|
106
106
|
|
|
107
107
|
Use `useDataTable` and `TableView` when the application already controls sorting, pagination, preferences, or selection. Data fetching and mutations stay in the application. `useResultSelection` represents explicit IDs or all matching results with exclusions. `TableSavedViews` accepts application-owned views; it does not create a backend.
|
|
108
108
|
|
|
109
|
+
Pass a filter controller once to place the shared filter bar and connect table recovery behavior:
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
<DataTable
|
|
113
|
+
table={table}
|
|
114
|
+
filters={filters}
|
|
115
|
+
toolbar={<ProjectActions />}
|
|
116
|
+
filterBar={{ showSearch: false }}
|
|
117
|
+
/>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Create the controller with `useFilters`, `useUrlFilters`, or `useControlledFilters`. Its values remain application query state. The table does not derive a predicate or fetch rows from filter definitions. Set `filterBar={false}` when controls live elsewhere, or use `TableFilters` and `TableView` with the same controller in a composed layout.
|
|
121
|
+
|
|
122
|
+
Tables fit their rows, headers, and empty content by default, capped at 65dvh. Short tables do not reserve a vertical scrollbar. Full-page layouts can set an explicit `height`. Rows remain 44px unless `rowHeight="auto"` opts into measurement for wrapped or editable content. Selected rows receive the standard highlight; `isRowHighlighted` adds application state. `onRowClick`, `rowClassName`, and `renderRowDetail` cover row actions and expandable content.
|
|
123
|
+
|
|
124
|
+
Changes to table query state or the shared controller reset scroll and cell selection. Appending rows keeps the current position and selection. Empty states distinguish an empty dataset, an empty filtered result with one controller clear, and an empty later page that can return to the first page. Locked filters never get a clear action.
|
|
125
|
+
|
|
109
126
|
See the [table documentation](https://ui.mendylanda.com/docs/components/table) for composition, remote data, and persistence.
|
package/dist/class-names.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const originalClassNames = {"mui-cb20bd519346":"pointer-events-auto","mui-33228ff7d583":"pointer-events-none","mui-b75af7ef6c4d":"invisible","mui-d42ef1497900":"visible","mui-32fb090591d9":"sr-only","mui-747355bdc2a2":"absolute","mui-d2d9e1f13413":"relative","mui-964a9431ff49":"sticky","mui-ce13093ad8c9":"inset-0","mui-3ba24c062d55":"inset-x-0","mui-eb9e48c5dda9":"inset-y-0","mui-cced28c6dc3f":"start","mui-207bd0b3f259":"start-2","mui-cea70f23972e":"start-3","mui-361e48d0308f":"end","mui-13422ddc8d83":"end-1","mui-585f4729f611":"end-9","mui-98599e4ee250":"top-0","mui-4e45f4841abb":"top-1/2","mui-a74c4477017c":"right-0","mui-30150dd033ab":"bottom-0","mui-a5c36273c0f0":"bottom-2","mui-635702706586":"left-0","mui-014aadadffad":"isolate","mui-d7efd1b0b0f9":"z-1","mui-418e44ad4f9e":"z-10","mui-4e8f0a87a0dc":"z-20","mui-fbb62f5cb6fe":"z-30","mui-3eef1ce97dba":"z-50","mui-a42d519714d6":"container","mui-a2526bc2efa3":"m-0","mui-abba77319850":"-mx-1","mui-1752f11474a6":"mx-auto","mui-d8747231f142":"my-1","mui-958e2cfcf5b6":"-ms-2","mui-291952c2525a":"-ms-px","mui-8cc46fa87f41":"-me-1.5","mui-f28fea81a5cd":"mt-2","mui-cc51bda60e7e":"ml-auto","mui-496aca80e4d8":"block","mui-d1b2a59fbea7":"contents","mui-222f930b8752":"flex","mui-0f2a693e93e2":"grid","mui-e564b4081d7a":"hidden","mui-995cf20a9c45":"inline","mui-123306850fe1":"inline-flex","mui-0d4fc4a78d37":"table","mui-3da89b3ed14b":"field-sizing-content","mui-129d6f9b1e07":"aspect-square","mui-f7d12b41bceb":"size-(--cell-size)","mui-dc797fcc7165":"size-1.5","mui-5e34f5313859":"size-3","mui-61c000c8a98a":"size-3.5","mui-100c22d5776b":"size-4","mui-2bd43fb57913":"size-5","mui-0712570dcc9f":"size-6","mui-79ede756e761":"size-7","mui-ebd37e04d422":"size-8","mui-3ee10ef4c057":"size-9","mui-d0a383a9c24f":"size-10","mui-4dad94bd15e3":"size-auto","mui-a5960ac1d283":"h-(--cell-size)","mui-c7d5500b77ab":"h-0","mui-2edce89ef182":"h-3","mui-099be97e1fa4":"h-4","mui-ce1945804664":"h-6","mui-c8e50836f8a1":"h-7","mui-1fb07b38c63b":"h-8","mui-539ae144f076":"h-9","mui-fdd2f85cad6b":"h-10","mui-a66e9985b093":"h-auto","mui-57c930dc1c31":"h-full","mui-ae2c4b060bb9":"h-px","mui-571ea69568d3":"max-h-(--filter-menu-height)","mui-1f061e70178e":"max-h-(--radix-dropdown-menu-content-available-height)","mui-4d3f1304ebb2":"max-h-(--radix-popover-content-available-height)","mui-da0beef015c9":"max-h-[400px]","mui-80baa5d03af7":"max-h-[calc(var(--filter-menu-height)-2px)]","mui-1326520533f0":"max-h-[min(6rem,calc(var(--filter-menu-height)*0.25))]","mui-fb4a3e97b5bd":"max-h-[min(20rem,var(--radix-dropdown-menu-content-available-height,20rem))]","mui-dcd942c18ddc":"max-h-[var(--radix-dropdown-menu-content-available-height)]","mui-7bd696ca6be3":"max-h-full","mui-410da8dfa8ac":"min-h-0","mui-9974acedf3f7":"min-h-9","mui-8423dc94ee06":"min-h-10","mui-50312c3ce4a3":"min-h-[60px]","mui-d48fe95d4da8":"w-(--cell-size)","mui-d4ea834145ae":"w-2","mui-56bb14cbd1fe":"w-2/3","mui-8867d85ed290":"w-8","mui-4ac4ec8dfbce":"w-40","mui-37535002f0f7":"w-72","mui-a4cce7869436":"w-[300px]","mui-fc6a57ff7553":"w-[var(--mendy-filter-editor-width,19rem)]","mui-0b9c84552e40":"w-[var(--mendy-filter-list-width,var(--mendy-filter-anchor-width,18.75rem))]","mui-4415137b0467":"w-[var(--mendy-filter-menu-width,calc(var(--filter-list-width)_+_var(--mendy-filter-editor-width,19rem)))]","mui-8cfb5a42ef9f":"w-fit","mui-58d0413dd93c":"w-full","mui-91f82aa1df0c":"max-w-[60%]","mui-34055e6f8c1b":"max-w-[calc(100vw-2rem)]","mui-81b198a2db84":"max-w-full","mui-1458e495e3ae":"min-w-(--cell-size)","mui-184ddc11e5f9":"min-w-0","mui-e9ab1547c94d":"min-w-[8rem]","mui-2bf6510f1330":"min-w-full","mui-7bd5bab6d7f4":"flex-1","mui-66b490dd6005":"shrink","mui-27ead27a81df":"shrink-0","mui-adca5146416e":"grow","mui-215061302c50":"border-collapse","mui-3a3774477287":"origin-(--radix-dropdown-menu-content-transform-origin)","mui-5dde0fd996f0":"-translate-y-1/2","mui-4e3f08588318":"-rotate-45","mui-c80411b7591f":"rotate-45","mui-aa214ea38326":"transform","mui-393df0d154e0":"animate-none!","mui-7b3cd77eb999":"animate-pulse","mui-2c14b55d77e6":"animate-spin","mui-2194d094b585":"cursor-col-resize","mui-d343f41ba73e":"cursor-default","mui-f2e47d9c52ad":"cursor-grab","mui-d2fa8848968d":"cursor-pointer","mui-739a9a000791":"touch-none","mui-acd532d8913e":"resize","mui-ae112c903ef8":"resize-y","mui-eeb3a8b33f69":"grid-cols-[min(var(--filter-list-width),calc(100%_-_min(var(--mendy-filter-editor-width,19rem),50%)))_minmax(0,1fr)]","mui-b5985369ee35":"grid-rows-[minmax(0,1fr)]","mui-302c0d124a94":"flex-col","mui-faa8a23c68f6":"flex-wrap","mui-8fd2e2355cbc":"place-content-center","mui-71556df3b421":"items-center","mui-b9677bd1cb66":"items-start","mui-32c92bb1fde4":"justify-between","mui-a503dd374cca":"justify-center","mui-307644c34db6":"justify-end","mui-c62ec162662e":"justify-start","mui-19e97f3f40e6":"gap-1","mui-70007b876865":"gap-1.5","mui-074569488cca":"gap-2","mui-d7db3451d154":"gap-3","mui-90fc3ec35a37":"gap-4","mui-27e6c432192f":"space-y-1","mui-267171770524":"space-y-2","mui-5a3a4ee420c2":"truncate","mui-1a26a0d28420":"overflow-auto","mui-d5111d0e9f48":"overflow-hidden","mui-0fc84a692dad":"overflow-visible","mui-3b82279f859f":"overflow-x-hidden","mui-2368e909f3a5":"overflow-y-auto","mui-998780cdef87":"overscroll-contain","mui-b005d61d0953":"rounded-full","mui-3fa8c572949b":"rounded-md","mui-52417259a4f5":"rounded-none","mui-02e603944040":"rounded-sm","mui-b31810dbd8a9":"rounded-s-none","mui-10c0bae8cba9":"rounded-l-md","mui-34bbd346e74c":"rounded-r-md","mui-4f1a55de40bc":"border","mui-dad556abfe15":"border-0","mui-55860251be20":"border-s","mui-3b6d5fc7b061":"border-e","mui-894c3815a57f":"border-t","mui-bbe39cfb5cc6":"border-b","mui-8450eb0f1857":"border-dashed","mui-163a623b3716":"border-border/50","mui-1267095cdeb7":"border-input","mui-9b76f456b8c9":"border-muted-foreground/50","mui-515f9fdc6db7":"border-primary","mui-292affc1f780":"bg-accent","mui-5b272f3c5076":"bg-background","mui-a943bea85d66":"bg-border","mui-0cf6c2e8fe7e":"bg-current","mui-965cf6587342":"bg-destructive","mui-047624ec0c39":"bg-green-100","mui-87ecb59f2d2d":"bg-muted","mui-810ae775809b":"bg-muted-foreground/20","mui-e593c38256e0":"bg-popover","mui-0c2864fba576":"bg-primary","mui-d191cb569aac":"bg-secondary","mui-8fca9236d191":"bg-transparent","mui-04760bcd507f":"p-0","mui-1dee6e3ec67d":"p-1","mui-b97db4a9f432":"p-2","mui-094f5333853b":"p-3","mui-c432836760e3":"p-6","mui-c7902d77ad80":"p-8","mui-56b8f5e0fb12":"px-(--cell-size)","mui-16e909e6f01d":"px-0","mui-1da2e8f173c5":"px-1.5","mui-e7e01cc7f4df":"px-2","mui-0f9e6672913a":"px-3","mui-9513b3968002":"px-4","mui-0194c6e46323":"px-8","mui-1fcf28756bb1":"py-1","mui-a8c1dfb1d4ef":"py-1.5","mui-b5edc3ea7c91":"py-2","mui-d3cea061f2f3":"py-3","mui-96b92a971c95":"py-5","mui-078d945937da":"ps-8","mui-b2100041c585":"ps-9","mui-05d4103bd67f":"pe-2","mui-a202804a1738":"pe-3","mui-0e14c365f9e8":"pe-9","mui-559069d2c2e5":"pe-16","mui-0a702d97ed7d":"pt-3","mui-1a52da5bc88c":"pr-1","mui-f5d8e661d857":"pl-2","mui-05ab12448317":"text-center","mui-10558dbb3a24":"text-end","mui-e9347b78185f":"text-start","mui-757071a1d1c4":"text-base","mui-c74ab393b96d":"text-sm","mui-3992de70b033":"text-xs","mui-5f120ad4b50b":"text-[0.8rem]","mui-761cdb81bddb":"leading-none","mui-daaac3fbf55e":"font-medium","mui-52101fc7d8bb":"font-normal","mui-e1683b3c030a":"tracking-widest","mui-393883c1db68":"[overflow-wrap:anywhere]","mui-37cf9655f30a":"break-words","mui-726fca123972":"whitespace-normal","mui-963f6168b7d6":"whitespace-nowrap","mui-cc209238d847":"text-accent-foreground","mui-5eafab9bbefc":"text-current","mui-887b9502d5c7":"text-destructive","mui-8d4bf2704c8d":"text-destructive-foreground","mui-957a109f887f":"text-foreground","mui-35f35c41d134":"text-muted-foreground","mui-5bd2afe89f0b":"text-popover-foreground","mui-249f14ee5b6b":"text-primary","mui-abd1aaa1f5b2":"text-primary-foreground","mui-80df79ec9bb5":"text-secondary-foreground","mui-944969efb294":"underline","mui-d52f902a57e8":"underline-offset-4","mui-94f91922a10e":"opacity-0","mui-0b5a4d1257ab":"opacity-50","mui-65694092f002":"opacity-100","mui-0d4ca75de41c":"shadow-lg","mui-94ea94fde25f":"shadow-md","mui-89c3006b2722":"shadow-none","mui-7de07d413c13":"shadow-xs","mui-853be6c11609":"ring-2","mui-fd9d0b696aac":"ring-primary","mui-59edd3d33673":"outline-hidden","mui-318678825324":"outline","mui-e42932b7a79c":"blur","mui-e0122edc668b":"drop-shadow-md","mui-dfc3376b8266":"filter","mui-70dd37c11434":"transition","mui-eae178841c68":"transition-colors","mui-2cdd01663c76":"transition-opacity","mui-2b48746f4314":"transition-shadow","mui-b4b2fd95f324":"transition-none","mui-b30fc56058b6":"outline-none","mui-78905c9e865c":"select-none","mui-d80b6593dae5":"[--cell-size:--spacing(8)]","mui-82c2977beb8e":"[--cell-size:min(2rem,calc((100vw-3.5rem)/7))]","mui-d7d803c609c5":"[--filter-list-width:var(--mendy-filter-list-width,var(--mendy-filter-anchor-width,13rem))]","mui-971625533e56":"[--filter-menu-height:min(var(--mendy-filter-menu-max-height,44rem),var(--radix-dropdown-menu-content-available-height,44rem))]","mui-cacb19aa9640":"[scrollbar-width:thin]","mui-14bd99410890":"[unicode-bidi:isolate]","mui-97b1c00ff005":"group-hover:bg-accent","mui-ad936fcbed63":"group","mui-9af9a4182597":"group-data-[disabled=true]:pointer-events-none","mui-272ef88d6a0c":"group-data-[disabled=true]:opacity-50","mui-60052b901494":"group-data-[focused=true]/day:relative","mui-d9c5891363f9":"group/day","mui-3f96bf138f7b":"group-data-[focused=true]/day:z-10","mui-d39eb62b8363":"group-data-[focused=true]/day:border-ring","mui-5892a880410a":"group-data-[focused=true]/day:ring-1","mui-31b75c623c06":"group-data-[focused=true]/day:ring-ring","mui-e6020023567a":"group-data-[highlighted=true]:bg-accent","mui-f0ee83167878":"peer-disabled:cursor-not-allowed","mui-2ffc1d06387e":"peer","mui-25d26df52a1d":"peer-disabled:opacity-50","mui-32713fefe32f":"file:border-0","mui-25a74d576c42":"file:bg-transparent","mui-844abccf1fd0":"file:text-sm","mui-dc43de54f42a":"file:font-medium","mui-20315da78444":"placeholder:text-muted-foreground","mui-3deb00079b4c":"first:border-s-0","mui-37ad15a95595":"hover:bg-accent","mui-63b29dace366":"hover:bg-accent/50","mui-bb6a4b3e902d":"hover:bg-destructive/90","mui-5cbdd1b32f1a":"hover:bg-muted/50","mui-4273133a876a":"hover:bg-primary/20","mui-af9ea085901b":"hover:bg-primary/90","mui-099700a5a311":"hover:bg-secondary/80","mui-71863717995b":"hover:bg-transparent","mui-9f1f77b92dcb":"hover:text-accent-foreground","mui-4d6720d47806":"hover:text-foreground","mui-b56720602554":"hover:underline","mui-8da02faac748":"hover:opacity-100","mui-a8c1861c5d03":"focus:bg-accent","mui-a85c4c5d7465":"focus:text-accent-foreground","mui-b906a32b31ee":"focus-visible:border-ring","mui-2f669cfad5aa":"focus-visible:bg-primary/20","mui-39be5a15b766":"focus-visible:ring-1","mui-355efe22aedb":"focus-visible:ring-2","mui-365a4654f7b1":"focus-visible:ring-[3px]","mui-db549d38ff19":"focus-visible:ring-ring","mui-392a26f4c1b0":"focus-visible:ring-ring/50","mui-a47d391255f3":"focus-visible:outline","mui-1df9125eebaf":"focus-visible:outline-1","mui-a8719ed8b095":"focus-visible:-outline-offset-2","mui-2b1c7d88acff":"focus-visible:outline-primary","mui-223daa83ed2d":"focus-visible:outline-ring","mui-2e357972fc10":"focus-visible:outline-none","mui-50aafa8694bb":"focus-visible:ring-inset","mui-71998ea7a2d0":"active:cursor-grabbing","mui-8d3c1014b967":"disabled:pointer-events-none","mui-db567af109b7":"disabled:cursor-not-allowed","mui-4600b77303d6":"disabled:opacity-50","mui-7eb7501a2ef0":"has-focus:border-ring","mui-d0449753ba7b":"has-focus:ring-[3px]","mui-fc19c8471f34":"has-focus:ring-ring/50","mui-e288cffc2ef4":"has-[>svg]:px-1.5","mui-3b01ee05b16d":"has-[>svg]:px-2.5","mui-9e08353b774f":"has-[>svg]:px-3","mui-2c0115d1c32a":"aria-disabled:opacity-50","mui-1fac1d7d1df3":"aria-invalid:border-destructive","mui-2d91b4cbc3cb":"aria-invalid:ring-destructive","mui-5491fd0b4dc5":"aria-invalid:ring-destructive/20","mui-2d6703b5473b":"aria-pressed:bg-accent","mui-ff2dcda51a27":"aria-pressed:text-accent-foreground","mui-7d900a71e5ba":"aria-selected:text-muted-foreground","mui-397f5ba426a0":"data-[disabled]:pointer-events-none","mui-9beb654fcb0d":"data-[disabled]:opacity-50","mui-9d7d1760cd8e":"data-[highlighted=true]:bg-accent","mui-6fa6a8ade7c4":"data-[inset]:pl-8","mui-bbaaa5969856":"data-[more-below=true]:[mask-image:linear-gradient(#000_calc(100%_-_1rem),transparent)]","mui-dfc89afd7885":"data-[navigation=pointer]:focus-visible:ring-0","mui-96308b55e0d6":"data-[range-end=true]:rounded-md","mui-a55dbe6f3eec":"data-[range-end=true]:rounded-r-md","mui-714051e55e8e":"data-[range-end=true]:bg-primary","mui-c764cebcd540":"data-[range-end=true]:text-primary-foreground","mui-05ec0700cd48":"data-[range-middle=true]:rounded-none","mui-5fb598fb06f4":"data-[range-middle=true]:bg-accent","mui-0813905aa141":"data-[range-middle=true]:text-accent-foreground","mui-8020e31bff67":"data-[range-start=true]:rounded-md","mui-ab65911baf1d":"data-[range-start=true]:rounded-l-md","mui-f5460d79341c":"data-[range-start=true]:bg-primary","mui-421a7d3e6631":"data-[range-start=true]:text-primary-foreground","mui-a39af81d518c":"data-[selected-single=true]:bg-primary","mui-b6991ab170de":"data-[selected-single=true]:text-primary-foreground","mui-3cc0d07ef843":"data-[selected=true]:rounded-none","mui-89f6aab7a3f8":"data-[side=bottom]:slide-in-from-top-2","mui-3550f48d66b9":"data-[side=left]:slide-in-from-right-2","mui-7720fe004f5c":"data-[side=right]:slide-in-from-left-2","mui-66b560f839de":"data-[side=top]:slide-in-from-bottom-2","mui-20553d55d224":"data-[state=checked]:border-primary","mui-57d6d6401a2f":"data-[state=checked]:bg-primary","mui-7ca12016214f":"data-[state=checked]:text-primary-foreground","mui-37d8a3f448ff":"data-[state=closed]:animate-none!","mui-0cb4489c3645":"data-[state=closed]:animate-out","mui-bb5869ef903b":"data-[state=closed]:fade-out-0","mui-f4cf4be63707":"data-[state=closed]:zoom-out-95","mui-bae1e782f277":"data-[state=open]:animate-in","mui-4027d9c589b6":"data-[state=open]:bg-accent","mui-1952cd5b00aa":"data-[state=open]:text-accent-foreground","mui-6f73a280432e":"data-[state=open]:text-foreground","mui-790ed041a953":"data-[state=open]:opacity-100","mui-45464a92c1f6":"data-[state=open]:fade-in-0","mui-9ca352480f25":"data-[state=open]:zoom-in-95","mui-f3f7a9c5e1b3":"data-[variant=destructive]:text-destructive","mui-e2bb4ac97190":"data-[variant=destructive]:focus:bg-destructive/10","mui-353a727facfd":"data-[variant=destructive]:focus:text-destructive","mui-237747164b60":"motion-reduce:animate-none","mui-0cc20f4e20c8":"sm:w-[21.875rem]","mui-56760b222da0":"md:flex-row","mui-c05c9b99939d":"md:text-sm","mui-36b12e8339c7":"rtl:rotate-180","mui-d254c96aea74":"dark:bg-green-950","mui-9daa2369a41b":"dark:bg-input/30","mui-b2786f463a62":"dark:hover:text-accent-foreground","mui-c88f65aa011e":"dark:aria-invalid:ring-destructive/40","mui-bd73d819941e":"dark:data-[state=checked]:bg-primary","mui-98a28c2293f7":"dark:data-[variant=destructive]:focus:bg-destructive/20","mui-d78a8526410d":"pointer-coarse:[--cell-size:min(2.5rem,calc((100vw-3.5rem)/7))]","mui-b51243872d85":"sm:pointer-fine:h-8","mui-e771a8b4d87d":"sm:pointer-fine:h-9","mui-aa0e3c036805":"sm:pointer-fine:min-h-8","mui-0288c4ea71ea":"sm:pointer-fine:py-0.5","mui-41d1475cf71a":"sm:pointer-fine:py-1.5","mui-548a450e8e53":"[&_*]:transition-none!","mui-a1c8c43d9be2":"[&_[role^=menuitem]]:min-h-9","mui-b43343fe71c0":"sm:pointer-fine:[&_[role^=menuitem]]:min-h-8","mui-cc310a330231":"[&_button]:font-semibold","mui-b7ff49878425":"[&_button]:underline","mui-d9bdd2c94504":"[&_button]:underline-offset-4","mui-bcae9d37090c":"[&_svg]:pointer-events-none","mui-c77732bd3ab4":"[&_svg]:size-3.5","mui-040e748a3fa0":"[&_svg]:shrink-0","mui-be87a4a64d81":"[&_svg:not([class*='size-'])]:size-3","mui-eb5ef2dbc2d4":"[&_svg:not([class*='size-'])]:size-4","mui-8637dfd54fbb":"[&_svg:not([class*='text-'])]:text-muted-foreground","mui-4f05a238500e":"[&::-webkit-search-cancel-button]:appearance-none","mui-74ab31abd804":"[&:first-child[data-selected=true]_button]:rounded-l-md","mui-13858191ca50":"rtl:**:[.rdp-button\\_next>svg]:rotate-180","mui-a324a7f99932":"rtl:**:[.rdp-button\\_previous>svg]:rotate-180","mui-82b114bbff3d":"data-[variant=destructive]:*:[svg]:text-destructive!","mui-6ee0c74de40c":"[&:last-child[data-selected=true]_button]:rounded-r-md","mui-6162ab70efb5":"[&:nth-child(2)[data-selected=true]_button]:rounded-l-md","mui-f157ee6bae99":"[&>div]:w-full","mui-ba417cf466b0":"[&>span]:text-xs","mui-829c8ef4f9c5":"[&>span]:opacity-70","mui-bf95f682e553":"[&>span:first-child]:mt-[calc(0.5lh-0.4375rem)]","mui-eb740dd32318":"[&>svg]:size-3.5","mui-019fd73c95db":"[&>svg]:text-muted-foreground","mui-b8293c91796c":"[[data-slot=card-content]_&]:bg-transparent","mui-8dd7e6b42262":"[[data-slot=popover-content]_&]:bg-transparent"};
|
|
1
|
+
export const originalClassNames = {"mui-cb20bd519346":"pointer-events-auto","mui-33228ff7d583":"pointer-events-none","mui-b75af7ef6c4d":"invisible","mui-d42ef1497900":"visible","mui-32fb090591d9":"sr-only","mui-747355bdc2a2":"absolute","mui-d2d9e1f13413":"relative","mui-964a9431ff49":"sticky","mui-ce13093ad8c9":"inset-0","mui-3ba24c062d55":"inset-x-0","mui-eb9e48c5dda9":"inset-y-0","mui-cced28c6dc3f":"start","mui-207bd0b3f259":"start-2","mui-cea70f23972e":"start-3","mui-361e48d0308f":"end","mui-13422ddc8d83":"end-1","mui-585f4729f611":"end-9","mui-98599e4ee250":"top-0","mui-4e45f4841abb":"top-1/2","mui-a74c4477017c":"right-0","mui-30150dd033ab":"bottom-0","mui-a5c36273c0f0":"bottom-2","mui-635702706586":"left-0","mui-014aadadffad":"isolate","mui-d7efd1b0b0f9":"z-1","mui-418e44ad4f9e":"z-10","mui-4e8f0a87a0dc":"z-20","mui-fbb62f5cb6fe":"z-30","mui-3eef1ce97dba":"z-50","mui-a42d519714d6":"container","mui-a2526bc2efa3":"m-0","mui-abba77319850":"-mx-1","mui-1752f11474a6":"mx-auto","mui-d8747231f142":"my-1","mui-958e2cfcf5b6":"-ms-2","mui-291952c2525a":"-ms-px","mui-8cc46fa87f41":"-me-1.5","mui-f28fea81a5cd":"mt-2","mui-cc51bda60e7e":"ml-auto","mui-496aca80e4d8":"block","mui-d1b2a59fbea7":"contents","mui-222f930b8752":"flex","mui-0f2a693e93e2":"grid","mui-e564b4081d7a":"hidden","mui-995cf20a9c45":"inline","mui-123306850fe1":"inline-flex","mui-0d4fc4a78d37":"table","mui-3da89b3ed14b":"field-sizing-content","mui-129d6f9b1e07":"aspect-square","mui-f7d12b41bceb":"size-(--cell-size)","mui-dc797fcc7165":"size-1.5","mui-5e34f5313859":"size-3","mui-61c000c8a98a":"size-3.5","mui-100c22d5776b":"size-4","mui-2bd43fb57913":"size-5","mui-0712570dcc9f":"size-6","mui-79ede756e761":"size-7","mui-ebd37e04d422":"size-8","mui-3ee10ef4c057":"size-9","mui-d0a383a9c24f":"size-10","mui-4dad94bd15e3":"size-auto","mui-a5960ac1d283":"h-(--cell-size)","mui-c7d5500b77ab":"h-0","mui-2edce89ef182":"h-3","mui-099be97e1fa4":"h-4","mui-ce1945804664":"h-6","mui-c8e50836f8a1":"h-7","mui-1fb07b38c63b":"h-8","mui-539ae144f076":"h-9","mui-fdd2f85cad6b":"h-10","mui-a66e9985b093":"h-auto","mui-57c930dc1c31":"h-full","mui-ae2c4b060bb9":"h-px","mui-571ea69568d3":"max-h-(--filter-menu-height)","mui-1f061e70178e":"max-h-(--radix-dropdown-menu-content-available-height)","mui-4d3f1304ebb2":"max-h-(--radix-popover-content-available-height)","mui-da0beef015c9":"max-h-[400px]","mui-80baa5d03af7":"max-h-[calc(var(--filter-menu-height)-2px)]","mui-1326520533f0":"max-h-[min(6rem,calc(var(--filter-menu-height)*0.25))]","mui-fb4a3e97b5bd":"max-h-[min(20rem,var(--radix-dropdown-menu-content-available-height,20rem))]","mui-dcd942c18ddc":"max-h-[var(--radix-dropdown-menu-content-available-height)]","mui-7bd696ca6be3":"max-h-full","mui-410da8dfa8ac":"min-h-0","mui-9974acedf3f7":"min-h-9","mui-8423dc94ee06":"min-h-10","mui-50312c3ce4a3":"min-h-[60px]","mui-d48fe95d4da8":"w-(--cell-size)","mui-d4ea834145ae":"w-2","mui-56bb14cbd1fe":"w-2/3","mui-8867d85ed290":"w-8","mui-4ac4ec8dfbce":"w-40","mui-37535002f0f7":"w-72","mui-a4cce7869436":"w-[300px]","mui-fc6a57ff7553":"w-[var(--mendy-filter-editor-width,19rem)]","mui-0b9c84552e40":"w-[var(--mendy-filter-list-width,var(--mendy-filter-anchor-width,18.75rem))]","mui-4415137b0467":"w-[var(--mendy-filter-menu-width,calc(var(--filter-list-width)_+_var(--mendy-filter-editor-width,19rem)))]","mui-8cfb5a42ef9f":"w-fit","mui-58d0413dd93c":"w-full","mui-91f82aa1df0c":"max-w-[60%]","mui-34055e6f8c1b":"max-w-[calc(100vw-2rem)]","mui-81b198a2db84":"max-w-full","mui-1458e495e3ae":"min-w-(--cell-size)","mui-184ddc11e5f9":"min-w-0","mui-e9ab1547c94d":"min-w-[8rem]","mui-2bf6510f1330":"min-w-full","mui-7bd5bab6d7f4":"flex-1","mui-66b490dd6005":"shrink","mui-27ead27a81df":"shrink-0","mui-adca5146416e":"grow","mui-215061302c50":"border-collapse","mui-3a3774477287":"origin-(--radix-dropdown-menu-content-transform-origin)","mui-5dde0fd996f0":"-translate-y-1/2","mui-4e3f08588318":"-rotate-45","mui-c80411b7591f":"rotate-45","mui-aa214ea38326":"transform","mui-393df0d154e0":"animate-none!","mui-7b3cd77eb999":"animate-pulse","mui-2c14b55d77e6":"animate-spin","mui-2194d094b585":"cursor-col-resize","mui-d343f41ba73e":"cursor-default","mui-f2e47d9c52ad":"cursor-grab","mui-d2fa8848968d":"cursor-pointer","mui-739a9a000791":"touch-none","mui-acd532d8913e":"resize","mui-ae112c903ef8":"resize-y","mui-eeb3a8b33f69":"grid-cols-[min(var(--filter-list-width),calc(100%_-_min(var(--mendy-filter-editor-width,19rem),50%)))_minmax(0,1fr)]","mui-b5985369ee35":"grid-rows-[minmax(0,1fr)]","mui-302c0d124a94":"flex-col","mui-faa8a23c68f6":"flex-wrap","mui-8fd2e2355cbc":"place-content-center","mui-71556df3b421":"items-center","mui-b9677bd1cb66":"items-start","mui-32c92bb1fde4":"justify-between","mui-a503dd374cca":"justify-center","mui-307644c34db6":"justify-end","mui-c62ec162662e":"justify-start","mui-19e97f3f40e6":"gap-1","mui-70007b876865":"gap-1.5","mui-074569488cca":"gap-2","mui-d7db3451d154":"gap-3","mui-90fc3ec35a37":"gap-4","mui-27e6c432192f":"space-y-1","mui-267171770524":"space-y-2","mui-5a3a4ee420c2":"truncate","mui-1a26a0d28420":"overflow-auto","mui-d5111d0e9f48":"overflow-hidden","mui-0fc84a692dad":"overflow-visible","mui-3b82279f859f":"overflow-x-hidden","mui-2368e909f3a5":"overflow-y-auto","mui-998780cdef87":"overscroll-contain","mui-b005d61d0953":"rounded-full","mui-3fa8c572949b":"rounded-md","mui-52417259a4f5":"rounded-none","mui-02e603944040":"rounded-sm","mui-b31810dbd8a9":"rounded-s-none","mui-10c0bae8cba9":"rounded-l-md","mui-34bbd346e74c":"rounded-r-md","mui-4f1a55de40bc":"border","mui-dad556abfe15":"border-0","mui-55860251be20":"border-s","mui-3b6d5fc7b061":"border-e","mui-894c3815a57f":"border-t","mui-bbe39cfb5cc6":"border-b","mui-8450eb0f1857":"border-dashed","mui-163a623b3716":"border-border/50","mui-1267095cdeb7":"border-input","mui-9b76f456b8c9":"border-muted-foreground/50","mui-515f9fdc6db7":"border-primary","mui-292affc1f780":"bg-accent","mui-5b272f3c5076":"bg-background","mui-a943bea85d66":"bg-border","mui-0cf6c2e8fe7e":"bg-current","mui-965cf6587342":"bg-destructive","mui-047624ec0c39":"bg-green-100","mui-6ba846e1630e":"bg-inherit","mui-87ecb59f2d2d":"bg-muted","mui-810ae775809b":"bg-muted-foreground/20","mui-e593c38256e0":"bg-popover","mui-0c2864fba576":"bg-primary","mui-d191cb569aac":"bg-secondary","mui-8fca9236d191":"bg-transparent","mui-04760bcd507f":"p-0","mui-1dee6e3ec67d":"p-1","mui-b97db4a9f432":"p-2","mui-094f5333853b":"p-3","mui-c432836760e3":"p-6","mui-c7902d77ad80":"p-8","mui-56b8f5e0fb12":"px-(--cell-size)","mui-16e909e6f01d":"px-0","mui-1da2e8f173c5":"px-1.5","mui-e7e01cc7f4df":"px-2","mui-0f9e6672913a":"px-3","mui-9513b3968002":"px-4","mui-0194c6e46323":"px-8","mui-1fcf28756bb1":"py-1","mui-a8c1dfb1d4ef":"py-1.5","mui-b5edc3ea7c91":"py-2","mui-d3cea061f2f3":"py-3","mui-96b92a971c95":"py-5","mui-078d945937da":"ps-8","mui-b2100041c585":"ps-9","mui-05d4103bd67f":"pe-2","mui-a202804a1738":"pe-3","mui-0e14c365f9e8":"pe-9","mui-559069d2c2e5":"pe-16","mui-0a702d97ed7d":"pt-3","mui-1a52da5bc88c":"pr-1","mui-f5d8e661d857":"pl-2","mui-05ab12448317":"text-center","mui-10558dbb3a24":"text-end","mui-e9347b78185f":"text-start","mui-757071a1d1c4":"text-base","mui-c74ab393b96d":"text-sm","mui-3992de70b033":"text-xs","mui-5f120ad4b50b":"text-[0.8rem]","mui-761cdb81bddb":"leading-none","mui-daaac3fbf55e":"font-medium","mui-52101fc7d8bb":"font-normal","mui-e1683b3c030a":"tracking-widest","mui-393883c1db68":"[overflow-wrap:anywhere]","mui-37cf9655f30a":"break-words","mui-726fca123972":"whitespace-normal","mui-963f6168b7d6":"whitespace-nowrap","mui-cc209238d847":"text-accent-foreground","mui-5eafab9bbefc":"text-current","mui-887b9502d5c7":"text-destructive","mui-8d4bf2704c8d":"text-destructive-foreground","mui-957a109f887f":"text-foreground","mui-35f35c41d134":"text-muted-foreground","mui-5bd2afe89f0b":"text-popover-foreground","mui-249f14ee5b6b":"text-primary","mui-abd1aaa1f5b2":"text-primary-foreground","mui-80df79ec9bb5":"text-secondary-foreground","mui-944969efb294":"underline","mui-d52f902a57e8":"underline-offset-4","mui-94f91922a10e":"opacity-0","mui-0b5a4d1257ab":"opacity-50","mui-65694092f002":"opacity-100","mui-0d4ca75de41c":"shadow-lg","mui-94ea94fde25f":"shadow-md","mui-89c3006b2722":"shadow-none","mui-7de07d413c13":"shadow-xs","mui-853be6c11609":"ring-2","mui-fd9d0b696aac":"ring-primary","mui-59edd3d33673":"outline-hidden","mui-318678825324":"outline","mui-e42932b7a79c":"blur","mui-e0122edc668b":"drop-shadow-md","mui-dfc3376b8266":"filter","mui-70dd37c11434":"transition","mui-eae178841c68":"transition-colors","mui-2cdd01663c76":"transition-opacity","mui-2b48746f4314":"transition-shadow","mui-b4b2fd95f324":"transition-none","mui-b30fc56058b6":"outline-none","mui-78905c9e865c":"select-none","mui-d80b6593dae5":"[--cell-size:--spacing(8)]","mui-82c2977beb8e":"[--cell-size:min(2rem,calc((100vw-3.5rem)/7))]","mui-d7d803c609c5":"[--filter-list-width:var(--mendy-filter-list-width,var(--mendy-filter-anchor-width,13rem))]","mui-971625533e56":"[--filter-menu-height:min(var(--mendy-filter-menu-max-height,44rem),var(--radix-dropdown-menu-content-available-height,44rem))]","mui-cacb19aa9640":"[scrollbar-width:thin]","mui-14bd99410890":"[unicode-bidi:isolate]","mui-97b1c00ff005":"group-hover:bg-accent","mui-ad936fcbed63":"group","mui-9af9a4182597":"group-data-[disabled=true]:pointer-events-none","mui-272ef88d6a0c":"group-data-[disabled=true]:opacity-50","mui-60052b901494":"group-data-[focused=true]/day:relative","mui-d9c5891363f9":"group/day","mui-3f96bf138f7b":"group-data-[focused=true]/day:z-10","mui-d39eb62b8363":"group-data-[focused=true]/day:border-ring","mui-5892a880410a":"group-data-[focused=true]/day:ring-1","mui-31b75c623c06":"group-data-[focused=true]/day:ring-ring","mui-e6020023567a":"group-data-[highlighted=true]:bg-accent","mui-f0ee83167878":"peer-disabled:cursor-not-allowed","mui-2ffc1d06387e":"peer","mui-25d26df52a1d":"peer-disabled:opacity-50","mui-32713fefe32f":"file:border-0","mui-25a74d576c42":"file:bg-transparent","mui-844abccf1fd0":"file:text-sm","mui-dc43de54f42a":"file:font-medium","mui-20315da78444":"placeholder:text-muted-foreground","mui-3deb00079b4c":"first:border-s-0","mui-37ad15a95595":"hover:bg-accent","mui-bb6a4b3e902d":"hover:bg-destructive/90","mui-5cbdd1b32f1a":"hover:bg-muted/50","mui-4273133a876a":"hover:bg-primary/20","mui-af9ea085901b":"hover:bg-primary/90","mui-099700a5a311":"hover:bg-secondary/80","mui-71863717995b":"hover:bg-transparent","mui-9f1f77b92dcb":"hover:text-accent-foreground","mui-4d6720d47806":"hover:text-foreground","mui-b56720602554":"hover:underline","mui-8da02faac748":"hover:opacity-100","mui-a8c1861c5d03":"focus:bg-accent","mui-a85c4c5d7465":"focus:text-accent-foreground","mui-b906a32b31ee":"focus-visible:border-ring","mui-2f669cfad5aa":"focus-visible:bg-primary/20","mui-39be5a15b766":"focus-visible:ring-1","mui-355efe22aedb":"focus-visible:ring-2","mui-365a4654f7b1":"focus-visible:ring-[3px]","mui-db549d38ff19":"focus-visible:ring-ring","mui-392a26f4c1b0":"focus-visible:ring-ring/50","mui-a47d391255f3":"focus-visible:outline","mui-1df9125eebaf":"focus-visible:outline-1","mui-a8719ed8b095":"focus-visible:-outline-offset-2","mui-2b1c7d88acff":"focus-visible:outline-primary","mui-223daa83ed2d":"focus-visible:outline-ring","mui-2e357972fc10":"focus-visible:outline-none","mui-50aafa8694bb":"focus-visible:ring-inset","mui-71998ea7a2d0":"active:cursor-grabbing","mui-8d3c1014b967":"disabled:pointer-events-none","mui-db567af109b7":"disabled:cursor-not-allowed","mui-4600b77303d6":"disabled:opacity-50","mui-7eb7501a2ef0":"has-focus:border-ring","mui-d0449753ba7b":"has-focus:ring-[3px]","mui-fc19c8471f34":"has-focus:ring-ring/50","mui-e288cffc2ef4":"has-[>svg]:px-1.5","mui-3b01ee05b16d":"has-[>svg]:px-2.5","mui-9e08353b774f":"has-[>svg]:px-3","mui-2c0115d1c32a":"aria-disabled:opacity-50","mui-1fac1d7d1df3":"aria-invalid:border-destructive","mui-2d91b4cbc3cb":"aria-invalid:ring-destructive","mui-5491fd0b4dc5":"aria-invalid:ring-destructive/20","mui-2d6703b5473b":"aria-pressed:bg-accent","mui-ff2dcda51a27":"aria-pressed:text-accent-foreground","mui-7d900a71e5ba":"aria-selected:text-muted-foreground","mui-397f5ba426a0":"data-[disabled]:pointer-events-none","mui-9beb654fcb0d":"data-[disabled]:opacity-50","mui-9d7d1760cd8e":"data-[highlighted=true]:bg-accent","mui-6fa6a8ade7c4":"data-[inset]:pl-8","mui-bbaaa5969856":"data-[more-below=true]:[mask-image:linear-gradient(#000_calc(100%_-_1rem),transparent)]","mui-dfc89afd7885":"data-[navigation=pointer]:focus-visible:ring-0","mui-96308b55e0d6":"data-[range-end=true]:rounded-md","mui-a55dbe6f3eec":"data-[range-end=true]:rounded-r-md","mui-714051e55e8e":"data-[range-end=true]:bg-primary","mui-c764cebcd540":"data-[range-end=true]:text-primary-foreground","mui-05ec0700cd48":"data-[range-middle=true]:rounded-none","mui-5fb598fb06f4":"data-[range-middle=true]:bg-accent","mui-0813905aa141":"data-[range-middle=true]:text-accent-foreground","mui-8020e31bff67":"data-[range-start=true]:rounded-md","mui-ab65911baf1d":"data-[range-start=true]:rounded-l-md","mui-f5460d79341c":"data-[range-start=true]:bg-primary","mui-421a7d3e6631":"data-[range-start=true]:text-primary-foreground","mui-a39af81d518c":"data-[selected-single=true]:bg-primary","mui-b6991ab170de":"data-[selected-single=true]:text-primary-foreground","mui-3cc0d07ef843":"data-[selected=true]:rounded-none","mui-89f6aab7a3f8":"data-[side=bottom]:slide-in-from-top-2","mui-3550f48d66b9":"data-[side=left]:slide-in-from-right-2","mui-7720fe004f5c":"data-[side=right]:slide-in-from-left-2","mui-66b560f839de":"data-[side=top]:slide-in-from-bottom-2","mui-20553d55d224":"data-[state=checked]:border-primary","mui-57d6d6401a2f":"data-[state=checked]:bg-primary","mui-7ca12016214f":"data-[state=checked]:text-primary-foreground","mui-37d8a3f448ff":"data-[state=closed]:animate-none!","mui-0cb4489c3645":"data-[state=closed]:animate-out","mui-bb5869ef903b":"data-[state=closed]:fade-out-0","mui-f4cf4be63707":"data-[state=closed]:zoom-out-95","mui-bae1e782f277":"data-[state=open]:animate-in","mui-4027d9c589b6":"data-[state=open]:bg-accent","mui-1952cd5b00aa":"data-[state=open]:text-accent-foreground","mui-6f73a280432e":"data-[state=open]:text-foreground","mui-790ed041a953":"data-[state=open]:opacity-100","mui-45464a92c1f6":"data-[state=open]:fade-in-0","mui-9ca352480f25":"data-[state=open]:zoom-in-95","mui-f3f7a9c5e1b3":"data-[variant=destructive]:text-destructive","mui-e2bb4ac97190":"data-[variant=destructive]:focus:bg-destructive/10","mui-353a727facfd":"data-[variant=destructive]:focus:text-destructive","mui-237747164b60":"motion-reduce:animate-none","mui-0cc20f4e20c8":"sm:w-[21.875rem]","mui-56760b222da0":"md:flex-row","mui-c05c9b99939d":"md:text-sm","mui-36b12e8339c7":"rtl:rotate-180","mui-d254c96aea74":"dark:bg-green-950","mui-9daa2369a41b":"dark:bg-input/30","mui-b2786f463a62":"dark:hover:text-accent-foreground","mui-c88f65aa011e":"dark:aria-invalid:ring-destructive/40","mui-bd73d819941e":"dark:data-[state=checked]:bg-primary","mui-98a28c2293f7":"dark:data-[variant=destructive]:focus:bg-destructive/20","mui-d78a8526410d":"pointer-coarse:[--cell-size:min(2.5rem,calc((100vw-3.5rem)/7))]","mui-b51243872d85":"sm:pointer-fine:h-8","mui-e771a8b4d87d":"sm:pointer-fine:h-9","mui-aa0e3c036805":"sm:pointer-fine:min-h-8","mui-0288c4ea71ea":"sm:pointer-fine:py-0.5","mui-41d1475cf71a":"sm:pointer-fine:py-1.5","mui-548a450e8e53":"[&_*]:transition-none!","mui-a1c8c43d9be2":"[&_[role^=menuitem]]:min-h-9","mui-b43343fe71c0":"sm:pointer-fine:[&_[role^=menuitem]]:min-h-8","mui-cc310a330231":"[&_button]:font-semibold","mui-b7ff49878425":"[&_button]:underline","mui-d9bdd2c94504":"[&_button]:underline-offset-4","mui-bcae9d37090c":"[&_svg]:pointer-events-none","mui-c77732bd3ab4":"[&_svg]:size-3.5","mui-040e748a3fa0":"[&_svg]:shrink-0","mui-be87a4a64d81":"[&_svg:not([class*='size-'])]:size-3","mui-eb5ef2dbc2d4":"[&_svg:not([class*='size-'])]:size-4","mui-8637dfd54fbb":"[&_svg:not([class*='text-'])]:text-muted-foreground","mui-4f05a238500e":"[&::-webkit-search-cancel-button]:appearance-none","mui-74ab31abd804":"[&:first-child[data-selected=true]_button]:rounded-l-md","mui-13858191ca50":"rtl:**:[.rdp-button\\_next>svg]:rotate-180","mui-a324a7f99932":"rtl:**:[.rdp-button\\_previous>svg]:rotate-180","mui-82b114bbff3d":"data-[variant=destructive]:*:[svg]:text-destructive!","mui-6ee0c74de40c":"[&:last-child[data-selected=true]_button]:rounded-r-md","mui-6162ab70efb5":"[&:nth-child(2)[data-selected=true]_button]:rounded-l-md","mui-f157ee6bae99":"[&>div]:w-full","mui-ba417cf466b0":"[&>span]:text-xs","mui-829c8ef4f9c5":"[&>span]:opacity-70","mui-bf95f682e553":"[&>span:first-child]:mt-[calc(0.5lh-0.4375rem)]","mui-eb740dd32318":"[&>svg]:size-3.5","mui-019fd73c95db":"[&>svg]:text-muted-foreground","mui-b8293c91796c":"[[data-slot=card-content]_&]:bg-transparent","mui-8dd7e6b42262":"[[data-slot=popover-content]_&]:bg-transparent"};
|
|
@@ -38,7 +38,7 @@ export declare function FilterMenu({ children, asChild, anchor, }: {
|
|
|
38
38
|
asChild?: boolean;
|
|
39
39
|
/** Align a standalone trigger to an application-owned search field. */
|
|
40
40
|
anchor?: React.RefObject<HTMLDivElement | null>;
|
|
41
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
42
42
|
/** Applied chips followed by Clear all. Opt out when placing FilterClear elsewhere. */
|
|
43
43
|
export declare function FilterList({ showClear }: {
|
|
44
44
|
showClear?: boolean;
|
|
@@ -23,6 +23,12 @@ const subscribeHydration = () => () => { };
|
|
|
23
23
|
const clientHydrated = () => true;
|
|
24
24
|
const serverHydrated = () => false;
|
|
25
25
|
const Context = createContext(null);
|
|
26
|
+
function availableMenuEntries(filters) {
|
|
27
|
+
return filters.entries.filter((entry) => !entry.field.hidden && entry.field.menu !== false);
|
|
28
|
+
}
|
|
29
|
+
function hasClearableActiveField(filters) {
|
|
30
|
+
return filters.entries.some(({ field, value }) => !field.hidden && !field.disabled && field.removable !== false && field.isActive(value));
|
|
31
|
+
}
|
|
26
32
|
function useRoot() {
|
|
27
33
|
const context = useContext(Context);
|
|
28
34
|
if (!context)
|
|
@@ -69,7 +75,22 @@ export function FilterSearch({ label = "Search", placeholder = "Search or filter
|
|
|
69
75
|
const anchor = useRef(null);
|
|
70
76
|
const input = useRef(null);
|
|
71
77
|
const shift = useRef(false);
|
|
72
|
-
|
|
78
|
+
const hasMenu = availableMenuEntries(filters).length > 0;
|
|
79
|
+
useLayoutEffect(() => {
|
|
80
|
+
if (hasMenu)
|
|
81
|
+
return;
|
|
82
|
+
const focusTarget = input.current;
|
|
83
|
+
trigger.current = focusTarget;
|
|
84
|
+
return () => {
|
|
85
|
+
if (trigger.current === focusTarget)
|
|
86
|
+
trigger.current = null;
|
|
87
|
+
};
|
|
88
|
+
}, [hasMenu, trigger]);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (!hasMenu && filters.menuOpen)
|
|
91
|
+
filters.setMenuOpen(false);
|
|
92
|
+
}, [filters, hasMenu]);
|
|
93
|
+
return (_jsxs(DropdownMenu, { dir: direction, modal: false, open: hasMenu && filters.menuOpen, onOpenChange: filters.setMenuOpen, children: [_jsxs("div", { ref: anchor, className: cn("mui-d2d9e1f13413 mui-58d0413dd93c mui-81b198a2db84 mui-27ead27a81df mui-0cc20f4e20c8", classNames?.search), children: [_jsx(Search, { className: "mui-33228ff7d583 mui-747355bdc2a2 mui-cea70f23972e mui-4e45f4841abb mui-100c22d5776b mui-5dde0fd996f0", "aria-hidden": "true" }), _jsx(Input, { ref: input, type: "text", role: "searchbox", disabled: disabled, "aria-label": label, placeholder: placeholder, value: filters.search, autoComplete: "off", autoCapitalize: "none", autoCorrect: "off", spellCheck: false, className: cn("mui-58d0413dd93c mui-b2100041c585 mui-c74ab393b96d mui-4f05a238500e", filters.search ? (hasMenu ? "mui-559069d2c2e5" : "mui-0e14c365f9e8") : hasMenu ? "mui-0e14c365f9e8" : "mui-a202804a1738", classNames?.searchInput), onKeyDown: (event) => {
|
|
73
94
|
shift.current = event.shiftKey;
|
|
74
95
|
if (event.key === "Enter" && !event.nativeEvent.isComposing && !event.shiftKey) {
|
|
75
96
|
const classified = classifyPaste(event.currentTarget.value, filters.entries);
|
|
@@ -105,17 +126,28 @@ export function FilterSearch({ label = "Search", placeholder = "Search or filter
|
|
|
105
126
|
after: element.value.slice(end),
|
|
106
127
|
});
|
|
107
128
|
setAmbiguous(result.ambiguous);
|
|
108
|
-
} }), filters.search && (_jsx(Button, { variant: "ghost", size: "icon", type: "button", disabled: disabled, "aria-label": "Clear search", className: "mui-747355bdc2a2 mui-
|
|
129
|
+
} }), filters.search && (_jsx(Button, { variant: "ghost", size: "icon", type: "button", disabled: disabled, "aria-label": "Clear search", className: cn("mui-747355bdc2a2 mui-4e45f4841abb mui-222f930b8752 mui-0712570dcc9f mui-5dde0fd996f0 mui-71556df3b421 mui-a503dd374cca mui-02e603944040 mui-0b5a4d1257ab mui-8da02faac748 mui-2e357972fc10 mui-39be5a15b766 mui-db549d38ff19", hasMenu ? "mui-585f4729f611" : "mui-13422ddc8d83"), onClick: () => {
|
|
109
130
|
setAmbiguous([]);
|
|
110
131
|
filters.setSearch("");
|
|
111
132
|
input.current?.focus();
|
|
112
|
-
}, children: _jsx(X, { className: "mui-61c000c8a98a", "aria-hidden": "true" }) })), _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", ref:
|
|
133
|
+
}, children: _jsx(X, { className: "mui-61c000c8a98a", "aria-hidden": "true" }) })), hasMenu && (_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", ref: (element) => {
|
|
134
|
+
trigger.current = element;
|
|
135
|
+
}, type: "button", disabled: disabled, "aria-label": "Open filters", "aria-haspopup": "dialog", className: cn("mui-747355bdc2a2 mui-13422ddc8d83 mui-4e45f4841abb mui-79ede756e761 mui-5dde0fd996f0 mui-2cdd01663c76 mui-8da02faac748 mui-2e357972fc10 mui-39be5a15b766 mui-db549d38ff19 mui-790ed041a953", filters.active.length ? "mui-65694092f002" : "mui-0b5a4d1257ab", classNames?.menuTrigger), children: _jsx(ListFilter, { className: "mui-100c22d5776b", "aria-hidden": "true" }) }) }))] }), hasMenu && filters.menuOpen && _jsx(FilterMenuContent, { anchor: anchor })] }));
|
|
113
136
|
}
|
|
114
137
|
/** A standalone menu button for layouts without a search field. */
|
|
115
138
|
export function FilterMenu({ children = "Add filter", asChild = false, anchor, }) {
|
|
116
139
|
const { filters, trigger, disabled, direction } = useRoot();
|
|
117
140
|
const { classNames } = useMendyUI();
|
|
118
|
-
|
|
141
|
+
const hasMenu = availableMenuEntries(filters).length > 0;
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (!hasMenu && filters.menuOpen)
|
|
144
|
+
filters.setMenuOpen(false);
|
|
145
|
+
}, [filters, hasMenu]);
|
|
146
|
+
if (!hasMenu)
|
|
147
|
+
return null;
|
|
148
|
+
return (_jsxs(DropdownMenu, { dir: direction, modal: false, open: filters.menuOpen, onOpenChange: filters.setMenuOpen, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { ref: (element) => {
|
|
149
|
+
trigger.current = element;
|
|
150
|
+
}, asChild: asChild, className: classNames?.menuTrigger, variant: "outline", disabled: disabled, "aria-haspopup": "dialog", children: children }) }), filters.menuOpen && _jsx(FilterMenuContent, { anchor: anchor })] }));
|
|
119
151
|
}
|
|
120
152
|
const fieldIcons = {
|
|
121
153
|
single: Circle,
|
|
@@ -131,7 +163,7 @@ function FilterMenuContent({ anchor }) {
|
|
|
131
163
|
const [clearEpoch, setClearEpoch] = useState(0);
|
|
132
164
|
const [drafts] = useState(() => new Map());
|
|
133
165
|
const grouped = new Set(groups.flatMap((group) => group.fields));
|
|
134
|
-
const visible = filters
|
|
166
|
+
const visible = availableMenuEntries(filters);
|
|
135
167
|
const sections = [
|
|
136
168
|
...visible.flatMap((entry) => grouped.has(entry.id)
|
|
137
169
|
? []
|
|
@@ -190,7 +222,7 @@ export function FilterList({ showClear = true }) {
|
|
|
190
222
|
(entry.field.isActive(entry.value) ||
|
|
191
223
|
showSuggestion(entry, suggestions, filters.active.length))
|
|
192
224
|
? [_jsx(FieldChip, { entry: entry }, entry.id)]
|
|
193
|
-
: []), showClear && _jsx(FilterClear, {})] }));
|
|
225
|
+
: []), showClear && hasClearableActiveField(filters) && _jsx(FilterClear, {})] }));
|
|
194
226
|
}
|
|
195
227
|
function summarize(field, value, choices) {
|
|
196
228
|
if (field.kind === "numberRange" && Array.isArray(value))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { KeyboardEvent } from "react";
|
|
2
2
|
export declare function focusMenuEditor(root: HTMLDivElement | null): void;
|
|
3
3
|
export declare function handleMenuTab(event: KeyboardEvent<HTMLDivElement>, { trigger, editor, onClose, hasSelection, }: {
|
|
4
|
-
trigger:
|
|
4
|
+
trigger: HTMLElement | null;
|
|
5
5
|
editor: HTMLDivElement | null;
|
|
6
6
|
onClose(): void;
|
|
7
7
|
hasSelection: boolean;
|
|
@@ -16,7 +16,7 @@ interface FilterMenuPanelProps {
|
|
|
16
16
|
onSelect(id: string | null): void;
|
|
17
17
|
onClose(): void;
|
|
18
18
|
anchor?: RefObject<HTMLDivElement | null>;
|
|
19
|
-
trigger: RefObject<
|
|
19
|
+
trigger: RefObject<HTMLElement | null>;
|
|
20
20
|
}
|
|
21
21
|
/** One dialog contains the filter list and its editor, with a single-panel layout on phones. */
|
|
22
22
|
export declare function FilterMenuPanel({ sections, selectedId, onSelect, onClose, anchor, trigger, }: FilterMenuPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, RefObject } from "react";
|
|
2
2
|
/** Position the menu against the search field and the available viewport. */
|
|
3
|
-
export declare function useMenuPlacement(anchor: RefObject<HTMLDivElement | null> | undefined, trigger: RefObject<
|
|
3
|
+
export declare function useMenuPlacement(anchor: RefObject<HTMLDivElement | null> | undefined, trigger: RefObject<HTMLElement | null>, desktop: boolean): {
|
|
4
4
|
alignOffset: number;
|
|
5
5
|
side: "top" | "bottom";
|
|
6
6
|
anchorStyle: CSSProperties | undefined;
|
package/dist/styles.css
CHANGED
|
@@ -607,6 +607,9 @@
|
|
|
607
607
|
.mui-047624ec0c39:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
608
608
|
background-color: var(--color-green-100);
|
|
609
609
|
}
|
|
610
|
+
.mui-6ba846e1630e:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
611
|
+
background-color: inherit;
|
|
612
|
+
}
|
|
610
613
|
.mui-87ecb59f2d2d:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
611
614
|
background-color: var(--muted, #f5f5f5);
|
|
612
615
|
}
|
|
@@ -1001,16 +1004,6 @@
|
|
|
1001
1004
|
}
|
|
1002
1005
|
}
|
|
1003
1006
|
}
|
|
1004
|
-
.mui-63b29dace366:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
1005
|
-
&:hover {
|
|
1006
|
-
@media (hover: hover) {
|
|
1007
|
-
background-color: var(--accent, #f5f5f5);
|
|
1008
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1009
|
-
background-color: color-mix(in oklab, var(--accent, #f5f5f5) 50%, transparent);
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
1007
|
.mui-bb6a4b3e902d:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
1015
1008
|
&:hover {
|
|
1016
1009
|
@media (hover: hover) {
|
|
@@ -606,6 +606,9 @@
|
|
|
606
606
|
.mui-047624ec0c39:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
607
607
|
background-color: var(--color-green-100);
|
|
608
608
|
}
|
|
609
|
+
.mui-6ba846e1630e:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
610
|
+
background-color: inherit;
|
|
611
|
+
}
|
|
609
612
|
.mui-87ecb59f2d2d:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
610
613
|
background-color: var(--muted, #f5f5f5);
|
|
611
614
|
}
|
|
@@ -1000,16 +1003,6 @@
|
|
|
1000
1003
|
}
|
|
1001
1004
|
}
|
|
1002
1005
|
}
|
|
1003
|
-
.mui-63b29dace366:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
1004
|
-
&:hover {
|
|
1005
|
-
@media (hover: hover) {
|
|
1006
|
-
background-color: var(--accent, #f5f5f5);
|
|
1007
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1008
|
-
background-color: color-mix(in oklab, var(--accent, #f5f5f5) 50%, transparent);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
1006
|
.mui-bb6a4b3e902d:where([data-mendy-ui], [data-mendy-ui] *) {
|
|
1014
1007
|
&:hover {
|
|
1015
1008
|
@media (hover: hover) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DataTableInstance } from "./use-data-table.js";
|
|
2
|
-
export declare const interactiveSelector = "button, a, input, textarea, select, [contenteditable]:not([contenteditable=\"false\"]), [role=\"checkbox\"], [role=\"button\"], [role=\"textbox\"]";
|
|
2
|
+
export declare const interactiveSelector = "button, a, summary, input, textarea, select, [contenteditable]:not([contenteditable=\"false\"]), [role=\"checkbox\"], [role=\"button\"], [role=\"textbox\"]";
|
|
3
3
|
export declare function selectedCellsText<T extends object>(table: DataTableInstance<T>): string;
|
|
4
4
|
export declare function tableCsv<T extends object>(table: DataTableInstance<T>, options?: {
|
|
5
5
|
selectedOnly?: boolean;
|
package/dist/table/clipboard.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { constructCell } from "@tanstack/react-table";
|
|
2
2
|
import { csvValue, tsvValue } from "./state.js";
|
|
3
|
-
export const interactiveSelector = 'button, a, input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="checkbox"], [role="button"], [role="textbox"]';
|
|
3
|
+
export const interactiveSelector = 'button, a, summary, input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="checkbox"], [role="button"], [role="textbox"]';
|
|
4
4
|
export function selectedCellsText(table) {
|
|
5
5
|
const rows = table.getRowsInDisplayOrder();
|
|
6
6
|
const columns = [
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { UseDataTableOptions, DataTableInstance } from "./use-data-table.js";
|
|
3
3
|
import type { TableViewProps } from "./table-view.js";
|
|
4
|
+
import { type TableFiltersProps } from "./table-filters.js";
|
|
4
5
|
type Appearance<T extends object> = Omit<TableViewProps<T>, "table"> & {
|
|
5
6
|
toolbar?: ReactNode;
|
|
6
7
|
footer?: ReactNode;
|
|
7
8
|
showColumnSettings?: boolean;
|
|
8
9
|
showPagination?: boolean;
|
|
10
|
+
/** Customize the built-in filter bar, or render it yourself with false. */
|
|
11
|
+
filterBar?: Omit<TableFiltersProps, "filters"> | false;
|
|
9
12
|
};
|
|
10
13
|
export type DataTableProps<T extends object> = Appearance<T> & (UseDataTableOptions<T> | {
|
|
11
14
|
table: DataTableInstance<T>;
|
package/dist/table/data-table.js
CHANGED
|
@@ -3,8 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useDataTable } from "./use-data-table.js";
|
|
4
4
|
import { TableView } from "./table-view.js";
|
|
5
5
|
import { TableColumnSettings, TablePagination } from "./table-controls.js";
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { TableFilters } from "./table-filters.js";
|
|
7
|
+
function ControlledTable({ table, toolbar, footer, showColumnSettings = true, showPagination = false, filters, filterBar, ...view }) {
|
|
8
|
+
return (_jsxs("div", { "data-mendy-ui": "", className: "mui-184ddc11e5f9 mui-267171770524", children: [(toolbar || showColumnSettings || (filters && filterBar !== false)) && (_jsxs("div", { className: "mui-222f930b8752 mui-faa8a23c68f6 mui-b9677bd1cb66 mui-32c92bb1fde4 mui-074569488cca", children: [_jsxs("div", { className: "mui-184ddc11e5f9 mui-7bd5bab6d7f4 mui-267171770524", children: [filters && filterBar !== false && _jsx(TableFilters, { ...filterBar, filters: filters }), !filters && toolbar] }), filters && toolbar, showColumnSettings && _jsx(TableColumnSettings, { table: table })] })), _jsx(TableView, { table: table, filters: filters, ...view }), showPagination && (_jsx(TablePagination, { table: table, loading: view.status === "loading" || view.refreshing })), footer] }));
|
|
8
9
|
}
|
|
9
10
|
function ConfiguredTable(props) {
|
|
10
11
|
const table = useDataTable(props);
|
package/dist/table/index.d.ts
CHANGED
package/dist/table/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { TableDataState } from "./table-view.js";
|
|
3
|
-
export declare function TableInitialState({ status, hasRows, loadingState, emptyState, error, retry, }: Pick<TableDataState, "status" | "error" | "retry"> & {
|
|
3
|
+
export declare function TableInitialState({ status, hasRows, loadingState, emptyState, error, retry, hasFilters, pageIndex, clearFilters, firstPage, }: Pick<TableDataState, "status" | "error" | "retry"> & {
|
|
4
4
|
hasRows: boolean;
|
|
5
5
|
loadingState?: ReactNode;
|
|
6
6
|
emptyState?: ReactNode;
|
|
7
|
+
hasFilters?: boolean;
|
|
8
|
+
pageIndex?: number;
|
|
9
|
+
clearFilters?: () => void;
|
|
10
|
+
firstPage?: () => void;
|
|
7
11
|
}): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Button } from "../primitives/button.js";
|
|
3
|
-
export function TableInitialState({ status, hasRows, loadingState, emptyState, error, retry, }) {
|
|
3
|
+
export function TableInitialState({ status, hasRows, loadingState, emptyState, error, retry, hasFilters, pageIndex = 0, clearFilters, firstPage, }) {
|
|
4
4
|
if (hasRows)
|
|
5
5
|
return null;
|
|
6
6
|
if (status === "loading")
|
|
7
7
|
return loadingState ?? null;
|
|
8
8
|
if (status === "error")
|
|
9
9
|
return (_jsxs("div", { role: "alert", className: "mui-c432836760e3 mui-05ab12448317", children: [error ?? "Could not load rows.", retry && (_jsx(Button, { variant: "outline", size: "sm", onClick: retry, children: "Retry" }))] }));
|
|
10
|
-
return (_jsx("div", { role: "status", className: "mui-c7902d77ad80 mui-05ab12448317 mui-35f35c41d134", children: emptyState ??
|
|
10
|
+
return (_jsx("div", { role: "status", className: "mui-222f930b8752 mui-302c0d124a94 mui-71556df3b421 mui-074569488cca mui-c7902d77ad80 mui-05ab12448317 mui-35f35c41d134", children: emptyState ??
|
|
11
|
+
(pageIndex > 0 ? (_jsxs(_Fragment, { children: [_jsx("span", { children: "No results on this page." }), _jsx(Button, { variant: "outline", size: "sm", onClick: firstPage, children: "Go to first page" })] })) : hasFilters ? (_jsxs(_Fragment, { children: [_jsx("span", { children: "No results match your filters." }), clearFilters && (_jsx(Button, { variant: "outline", size: "sm", onClick: clearFilters, children: "Clear filters" }))] })) : ("No rows yet.")) }));
|
|
11
12
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import { FilterBar } from "../filters/filter-bar.js";
|
|
3
|
+
export type TableFiltersProps = ComponentProps<typeof FilterBar> & {
|
|
4
|
+
/** Hide the free-text search when the query only supports defined filters. */
|
|
5
|
+
showSearch?: boolean;
|
|
6
|
+
};
|
|
7
|
+
/** Use the same controller here and on TableView when composing a custom toolbar. */
|
|
8
|
+
export declare function TableFilters({ showSearch, ...props }: TableFiltersProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { FilterBar, FilterRoot, FilterMenu, FilterList, FilterFeedback, } from "../filters/filter-bar.js";
|
|
4
|
+
/** Use the same controller here and on TableView when composing a custom toolbar. */
|
|
5
|
+
export function TableFilters({ showSearch = true, ...props }) {
|
|
6
|
+
if (showSearch)
|
|
7
|
+
return _jsx(FilterBar, { ...props });
|
|
8
|
+
return (_jsxs(FilterRoot, { ...props, children: [_jsx(FilterMenu, {}), _jsx(FilterList, { showClear: props.showClear }), _jsx(FilterFeedback, {})] }));
|
|
9
|
+
}
|
|
@@ -10,11 +10,16 @@ export declare function TableHeaderCell<T extends object>({ table, header, index
|
|
|
10
10
|
renderHeader?: (header: Header<DataTableFeatures, T, unknown>) => ReactNode;
|
|
11
11
|
contentClassName?: string;
|
|
12
12
|
}): import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
declare function TableBodyRowImpl<T extends object>({ row, rowIndex, start, rowHeight, cellStyle, columns, columnGaps, columnIndexes, contentVersion, contentState, focusedId, copied, contentClassName, onRowActivate, isRowHighlighted, }: {
|
|
13
|
+
declare function TableBodyRowImpl<T extends object>({ row, rowIndex, start, rowHeight, autoRowHeight, measureElement, rowClassName, renderRowDetail, detailWidth, cellStyle, columns, columnGaps, columnIndexes, contentVersion, contentState, focusedId, copied, contentClassName, onRowClick, onRowActivate, isRowHighlighted, }: {
|
|
14
14
|
row: Row<DataTableFeatures, T>;
|
|
15
15
|
rowIndex: number;
|
|
16
16
|
start: number;
|
|
17
17
|
rowHeight: number;
|
|
18
|
+
autoRowHeight: boolean;
|
|
19
|
+
measureElement?: (element: HTMLDivElement | null) => void;
|
|
20
|
+
rowClassName?: (row: T) => string | undefined;
|
|
21
|
+
renderRowDetail?: (row: T) => ReactNode;
|
|
22
|
+
detailWidth: number;
|
|
18
23
|
cellStyle: (column: Column<DataTableFeatures, T>) => CSSProperties;
|
|
19
24
|
columns: Column<DataTableFeatures, T>[];
|
|
20
25
|
columnGaps: Map<string, number>;
|
|
@@ -24,6 +29,7 @@ declare function TableBodyRowImpl<T extends object>({ row, rowIndex, start, rowH
|
|
|
24
29
|
focusedId?: string;
|
|
25
30
|
copied: boolean;
|
|
26
31
|
contentClassName?: string;
|
|
32
|
+
onRowClick?: (row: T) => void;
|
|
27
33
|
onRowActivate?: (row: T) => void;
|
|
28
34
|
isRowHighlighted?: (row: T) => boolean;
|
|
29
35
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -13,7 +13,7 @@ export function TableHeaderCell({ table, header, index, style, renderHeader, con
|
|
|
13
13
|
const sorted = column.getIsSorted();
|
|
14
14
|
return (_jsxs("div", { role: "columnheader", "data-column-id": column.id, "aria-colindex": index + 1, "aria-sort": sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : undefined, style: style, className: "mui-d2d9e1f13413 mui-222f930b8752 mui-27ead27a81df mui-71556df3b421 mui-19e97f3f40e6 mui-3b6d5fc7b061 mui-5b272f3c5076 mui-0f9e6672913a mui-daaac3fbf55e mui-35f35c41d134", children: [_jsx("div", { className: cn("mui-184ddc11e5f9 mui-7bd5bab6d7f4 mui-d5111d0e9f48", (renderHeader || typeof definition.header === "function") && contentClassName), children: _jsx(TableHeaderContent, { header: header, renderHeader: renderHeader, title: title }) }), column.getCanResize() && (_jsx(TableResizeHandle, { table: table, header: header, title: title, width: Number(style.width) }))] }, column.id));
|
|
15
15
|
}
|
|
16
|
-
function TableBodyRowImpl({ row, rowIndex, start, rowHeight, cellStyle, columns, columnGaps, columnIndexes, contentVersion, contentState, focusedId, copied, contentClassName, onRowActivate, isRowHighlighted, }) {
|
|
16
|
+
function TableBodyRowImpl({ row, rowIndex, start, rowHeight, autoRowHeight, measureElement, rowClassName, renderRowDetail, detailWidth, cellStyle, columns, columnGaps, columnIndexes, contentVersion, contentState, focusedId, copied, contentClassName, onRowClick, onRowActivate, isRowHighlighted, }) {
|
|
17
17
|
// The engine's getAllCells API eagerly allocates every column. Build only the
|
|
18
18
|
// viewport cells with its public constructor, and release them with this row.
|
|
19
19
|
const cache = useMemo(() => new WeakMap(), [row]);
|
|
@@ -25,7 +25,12 @@ function TableBodyRowImpl({ row, rowIndex, start, rowHeight, cellStyle, columns,
|
|
|
25
25
|
}
|
|
26
26
|
return cell;
|
|
27
27
|
});
|
|
28
|
-
|
|
28
|
+
const rowElement = (_jsx("div", { ref: renderRowDetail ? undefined : measureElement, role: "row", "aria-rowindex": renderRowDetail ? undefined : rowIndex + 2, "aria-selected": row.getIsSelected(), "data-highlighted": row.getIsSelected() || isRowHighlighted?.(row.original), "data-index": rowIndex, className: cn("mui-ad936fcbed63 mui-635702706586 mui-222f930b8752 mui-2bf6510f1330 mui-5b272f3c5076 mui-37ad15a95595 mui-9d7d1760cd8e", rowClassName?.(row.original)), style: {
|
|
29
|
+
height: autoRowHeight ? undefined : rowHeight,
|
|
30
|
+
minHeight: rowHeight,
|
|
31
|
+
top: renderRowDetail ? 0 : start,
|
|
32
|
+
position: renderRowDetail ? "relative" : "absolute",
|
|
33
|
+
}, children: cells.map((cell) => {
|
|
29
34
|
const index = columnIndexes.get(cell.column.id);
|
|
30
35
|
const selected = cell.getIsSelected();
|
|
31
36
|
const definition = cell.column.columnDef;
|
|
@@ -36,7 +41,9 @@ function TableBodyRowImpl({ row, rowIndex, start, rowHeight, cellStyle, columns,
|
|
|
36
41
|
: -1
|
|
37
42
|
: rowIndex === 0 && index === 0
|
|
38
43
|
? 0
|
|
39
|
-
: -1, style:
|
|
44
|
+
: -1, style: autoRowHeight
|
|
45
|
+
? { ...cellStyle(cell.column), height: undefined, minHeight: rowHeight }
|
|
46
|
+
: cellStyle(cell.column), className: cn("mui-d2d9e1f13413 mui-222f930b8752 mui-27ead27a81df mui-71556df3b421 mui-bbe39cfb5cc6 mui-3b6d5fc7b061 mui-6ba846e1630e mui-0f9e6672913a", !(selected && copied) && "mui-97b1c00ff005 mui-e6020023567a", !selected && "mui-a47d391255f3 mui-a8719ed8b095 mui-2b1c7d88acff", definition.align === "end" && "mui-307644c34db6 mui-10558dbb3a24", definition.align === "center" && "mui-a503dd374cca mui-05ab12448317", selected && "mui-292affc1f780 mui-b30fc56058b6", selected && copied && "mui-047624ec0c39 mui-d254c96aea74"), onMouseDown: (event) => {
|
|
40
47
|
if (event.button !== 0 ||
|
|
41
48
|
event.detail > 1 ||
|
|
42
49
|
!cell.getCanSelect() ||
|
|
@@ -47,7 +54,10 @@ function TableBodyRowImpl({ row, rowIndex, start, rowHeight, cellStyle, columns,
|
|
|
47
54
|
event.stopPropagation();
|
|
48
55
|
event.currentTarget.focus({ preventScroll: true });
|
|
49
56
|
cell.getSelectionStartHandler()(event);
|
|
50
|
-
}, onMouseEnter: cell.getSelectionExtendHandler(),
|
|
57
|
+
}, onMouseEnter: cell.getSelectionExtendHandler(), onClick: (event) => {
|
|
58
|
+
if (event.detail <= 1 && !event.target.closest(interactiveSelector))
|
|
59
|
+
onRowClick?.(row.original);
|
|
60
|
+
}, onDoubleClick: (event) => {
|
|
51
61
|
if (!event.target.closest(interactiveSelector))
|
|
52
62
|
onRowActivate?.(row.original);
|
|
53
63
|
}, children: [selected && (_jsx("span", { "aria-hidden": "true", "data-selection-outline": "", className: "mui-33228ff7d583 mui-747355bdc2a2 mui-d7efd1b0b0f9 mui-515f9fdc6db7", style: {
|
|
@@ -59,8 +69,12 @@ function TableBodyRowImpl({ row, rowIndex, start, rowHeight, cellStyle, columns,
|
|
|
59
69
|
borderBottomWidth: edge?.bottom ? 2 : 0,
|
|
60
70
|
borderLeftWidth: edge?.left ? 2 : 0,
|
|
61
71
|
borderRightWidth: edge?.right ? 2 : 0,
|
|
62
|
-
} })), _jsx("div", { className: cn("mui-
|
|
72
|
+
} })), _jsx("div", { className: cn("mui-184ddc11e5f9 mui-81b198a2db84", autoRowHeight ? "mui-726fca123972 mui-37cf9655f30a mui-b5edc3ea7c91" : "mui-7bd696ca6be3 mui-5a3a4ee420c2", contentClassName), children: _jsx(TableCellContent, { cell: cell, renderer: cell.column.columnDef.cell, version: contentVersion, state: contentState }) })] }, cell.id)] }, cell.id));
|
|
63
73
|
}) }, row.id));
|
|
74
|
+
if (!renderRowDetail)
|
|
75
|
+
return rowElement;
|
|
76
|
+
const detail = renderRowDetail(row.original);
|
|
77
|
+
return (_jsxs("div", { ref: measureElement, "data-index": rowIndex, role: "rowgroup", className: "mui-747355bdc2a2 mui-635702706586 mui-2bf6510f1330", style: { top: start }, children: [rowElement, detail != null && (_jsx("div", { role: "row", className: "mui-bbe39cfb5cc6 mui-5b272f3c5076", children: _jsx("div", { role: "gridcell", "aria-colspan": columns.length, className: "mui-964a9431ff49 mui-184ddc11e5f9 mui-094f5333853b", style: { width: detailWidth, maxWidth: "100%", insetInlineStart: 0 }, children: detail }) }))] }));
|
|
64
78
|
}
|
|
65
79
|
export const TableBodyRow = memo(TableBodyRowImpl);
|
|
66
80
|
function TableResizeHandle({ table, header, title, width, }) {
|
|
@@ -2,6 +2,7 @@ import type { ReactNode, Ref } from "react";
|
|
|
2
2
|
import type { Header } from "@tanstack/react-table";
|
|
3
3
|
import type { DataTableFeatures } from "./features.js";
|
|
4
4
|
import type { DataTableInstance } from "./use-data-table.js";
|
|
5
|
+
import type { FilterController } from "../filters/use-filters.js";
|
|
5
6
|
export interface TableDataState {
|
|
6
7
|
status?: "loading" | "ready" | "error";
|
|
7
8
|
error?: ReactNode;
|
|
@@ -17,8 +18,13 @@ export interface TableDataState {
|
|
|
17
18
|
export interface TableViewProps<T extends object> extends TableDataState {
|
|
18
19
|
table: DataTableInstance<T>;
|
|
19
20
|
label?: string;
|
|
21
|
+
/** Defaults to "auto": fit the rows, capped at 65% of the viewport height. */
|
|
20
22
|
height?: number | string;
|
|
21
|
-
|
|
23
|
+
/** Auto measures multiline rows and retains all columns to keep their height stable. */
|
|
24
|
+
rowHeight?: number | "auto";
|
|
25
|
+
rowClassName?: (row: T) => string | undefined;
|
|
26
|
+
/** Expanded content beneath a record. Return null for collapsed records. */
|
|
27
|
+
renderRowDetail?: (row: T) => ReactNode;
|
|
22
28
|
className?: string;
|
|
23
29
|
/** Theme adapter for application-owned renderers, not package controls. */
|
|
24
30
|
contentClassName?: string;
|
|
@@ -27,9 +33,14 @@ export interface TableViewProps<T extends object> extends TableDataState {
|
|
|
27
33
|
scrollRef?: Ref<HTMLDivElement>;
|
|
28
34
|
/** Change when the result set changes, not when another page is appended. */
|
|
29
35
|
queryKey?: string;
|
|
36
|
+
/** Shared filter state for query resets and empty-result recovery. */
|
|
37
|
+
filters?: FilterController;
|
|
30
38
|
renderHeader?: (header: Header<DataTableFeatures, T, unknown>) => ReactNode;
|
|
39
|
+
/** Single-click action, also used by Enter unless onRowActivate is provided. */
|
|
40
|
+
onRowClick?: (row: T) => void;
|
|
41
|
+
/** Optional double-click and Enter action. Interactive controls keep their own behavior. */
|
|
31
42
|
onRowActivate?: (row: T) => void;
|
|
32
43
|
isRowHighlighted?: (row: T) => boolean;
|
|
33
44
|
onCopyError?: (error: unknown) => void;
|
|
34
45
|
}
|
|
35
|
-
export declare function TableView<T extends object>({ table, label, height, rowHeight, className, contentClassName, emptyState, loadingState, scrollRef, status, refreshing, error, retry, loadMore, queryKey, renderHeader, onRowActivate, isRowHighlighted, onCopyError, }: TableViewProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
export declare function TableView<T extends object>({ table, label, height, rowHeight: rowHeightOption, rowClassName, renderRowDetail, className, contentClassName, emptyState, loadingState, scrollRef, status, refreshing, error, retry, loadMore, queryKey, filters, renderHeader, onRowClick, onRowActivate, isRowHighlighted, onCopyError, }: TableViewProps<T>): import("react/jsx-runtime").JSX.Element;
|
package/dist/table/table-view.js
CHANGED
|
@@ -11,7 +11,11 @@ import { tableLayout } from "./table-layout.js";
|
|
|
11
11
|
import { TableLoadingRows } from "./table-loading.js";
|
|
12
12
|
import { TableInitialState } from "./table-feedback.js";
|
|
13
13
|
import { useTableInteraction } from "./use-table-interaction.js";
|
|
14
|
-
|
|
14
|
+
import { useTableResults } from "./use-table-results.js";
|
|
15
|
+
export function TableView({ table, label = "Data table", height = "auto", rowHeight: rowHeightOption = 44, rowClassName, renderRowDetail, className, contentClassName, emptyState, loadingState, scrollRef, status = "ready", refreshing, error, retry, loadMore, queryKey, filters, renderHeader, onRowClick, onRowActivate, isRowHighlighted, onCopyError, }) {
|
|
16
|
+
const { resultKey, hasFilters, clearFilters } = useTableResults(table, queryKey, filters);
|
|
17
|
+
const autoRowHeight = rowHeightOption === "auto" || Boolean(renderRowDetail);
|
|
18
|
+
const rowHeight = rowHeightOption === "auto" ? 44 : rowHeightOption;
|
|
15
19
|
const container = useRef(null);
|
|
16
20
|
const setContainer = useCallback((node) => {
|
|
17
21
|
container.current = node;
|
|
@@ -39,14 +43,14 @@ export function TableView({ table, label = "Data table", height = "min(65dvh, 64
|
|
|
39
43
|
const layout = useMemo(() => tableLayout(table, viewportWidth, rowHeight), [table, startColumns, centerColumns, endColumns, sizing, viewportWidth, rowHeight]);
|
|
40
44
|
const { totalWidth, pinningActive } = layout;
|
|
41
45
|
const focused = table.getFocusedCell();
|
|
42
|
-
const { columns, columnGaps, cellStyle } = useColumnWindow(layout, container, viewportWidth, focused?.column.id);
|
|
46
|
+
const { columns, columnGaps, cellStyle } = useColumnWindow(layout, container, viewportWidth, focused?.column.id, !autoRowHeight);
|
|
43
47
|
const columnIndexes = useMemo(() => new Map(layout.columns.map((column, index) => [column.id, index])), [layout.columns]);
|
|
44
48
|
const { announcement, copied, onKeyDown } = useTableInteraction({
|
|
45
49
|
table,
|
|
46
50
|
pinningActive,
|
|
47
51
|
container,
|
|
48
|
-
queryKey,
|
|
49
|
-
onRowActivate,
|
|
52
|
+
queryKey: resultKey,
|
|
53
|
+
onRowActivate: onRowActivate ?? onRowClick,
|
|
50
54
|
onCopyError,
|
|
51
55
|
scrollToIndex: (index) => virtual.scrollToIndex(index, { align: "auto" }),
|
|
52
56
|
});
|
|
@@ -59,24 +63,24 @@ export function TableView({ table, label = "Data table", height = "min(65dvh, 64
|
|
|
59
63
|
}, [loadMore]);
|
|
60
64
|
useEffect(() => {
|
|
61
65
|
requested.current = null;
|
|
62
|
-
}, [
|
|
66
|
+
}, [resultKey]);
|
|
63
67
|
useEffect(() => {
|
|
64
68
|
const data = load.current;
|
|
65
|
-
const requestKey = `${queryKey}:${rows.length}`;
|
|
66
69
|
if (!data?.available ||
|
|
67
70
|
data.loading ||
|
|
68
71
|
data.error ||
|
|
69
72
|
last < rows.length - 10 ||
|
|
70
|
-
requested.current ===
|
|
73
|
+
(requested.current?.key === resultKey && requested.current.count === rows.length))
|
|
71
74
|
return;
|
|
72
75
|
const element = container.current;
|
|
73
76
|
// Only measure near the end when another page can actually be requested.
|
|
74
77
|
// Reading clientHeight on every scroll otherwise forces layout needlessly.
|
|
75
78
|
const nearEnd = element &&
|
|
76
|
-
element.scrollTop + element.clientHeight + rowHeight * 10 >=
|
|
79
|
+
element.scrollTop + element.clientHeight + rowHeight * 10 >=
|
|
80
|
+
virtual.getTotalSize() + rowHeight;
|
|
77
81
|
if (!nearEnd)
|
|
78
82
|
return;
|
|
79
|
-
requested.current =
|
|
83
|
+
requested.current = { key: resultKey, count: rows.length };
|
|
80
84
|
Promise.resolve()
|
|
81
85
|
.then(() => data.load())
|
|
82
86
|
.catch(() => {
|
|
@@ -86,13 +90,19 @@ export function TableView({ table, label = "Data table", height = "min(65dvh, 64
|
|
|
86
90
|
last,
|
|
87
91
|
rows.length,
|
|
88
92
|
rowHeight,
|
|
89
|
-
|
|
93
|
+
resultKey,
|
|
90
94
|
loadMore?.available,
|
|
91
95
|
loadMore?.loading,
|
|
92
96
|
loadMore?.error,
|
|
97
|
+
virtual,
|
|
93
98
|
]);
|
|
94
99
|
const headersById = new Map(table.getFlatHeaders().map((header) => [header.column.id, header]));
|
|
95
|
-
return (_jsxs("div", { "data-mendy-ui": "", className: "mui-184ddc11e5f9", children: [_jsx("div", { "aria-live": "polite", className: "mui-32fb090591d9", children: announcement }), _jsxs("div", { ref: setContainer, role: "grid", tabIndex: -1, "aria-label": label, "aria-rowcount": rows.length + 1, "aria-colcount": layout.columns.length, "aria-busy": status === "loading" || refreshing, style: {
|
|
100
|
+
return (_jsxs("div", { "data-mendy-ui": "", className: "mui-184ddc11e5f9", children: [_jsx("div", { "aria-live": "polite", className: "mui-32fb090591d9", children: announcement }), _jsxs("div", { ref: setContainer, role: "grid", tabIndex: -1, "aria-label": label, "aria-rowcount": renderRowDetail ? -1 : rows.length + 1, "aria-colcount": layout.columns.length, "aria-busy": status === "loading" || refreshing, style: {
|
|
101
|
+
height: height === "auto" ? undefined : height,
|
|
102
|
+
maxHeight: height === "auto" ? "65dvh" : undefined,
|
|
103
|
+
}, className: cn("mui-d2d9e1f13413 mui-014aadadffad mui-1a26a0d28420 mui-3fa8c572949b mui-4f1a55de40bc mui-5b272f3c5076 mui-c74ab393b96d mui-b30fc56058b6", className), onKeyDown: onKeyDown, children: [_jsx("div", { role: "row", "aria-rowindex": 1, className: "mui-964a9431ff49 mui-98599e4ee250 mui-4e8f0a87a0dc mui-222f930b8752 mui-2bf6510f1330 mui-bbe39cfb5cc6 mui-5b272f3c5076", style: { width: totalWidth }, children: columns.map((column) => (_jsxs(Fragment, { children: [columnGaps.has(column.id) && (_jsx("div", { "aria-hidden": "true", className: "mui-27ead27a81df", style: { width: columnGaps.get(column.id) } })), _jsx(TableHeaderCell, { table: table, header: headersById.get(column.id), index: columnIndexes.get(column.id), style: cellStyle(column), renderHeader: renderHeader, contentClassName: contentClassName }, column.id)] }, column.id))) }), _jsx(TableInitialState, { status: status, hasRows: rows.length > 0, loadingState: loadingState ?? (_jsx(TableLoadingRows, { columns: columns, columnGaps: columnGaps, width: totalWidth, rowHeight: rowHeight, cellStyle: cellStyle, count: height === "auto"
|
|
104
|
+
? 8
|
|
105
|
+
: Math.max(1, Math.ceil(((virtual.scrollRect?.height ?? 400) - rowHeight) / rowHeight)) })), emptyState: emptyState, hasFilters: hasFilters, pageIndex: table.state.pagination.pageIndex, clearFilters: clearFilters, firstPage: () => table.setPageIndex(0), error: error, retry: retry }), _jsx("div", { role: "rowgroup", className: "mui-d2d9e1f13413 mui-2bf6510f1330", style: { height: virtual.getTotalSize(), width: totalWidth }, children: items.map((item) => (_jsx(TableBodyRow, { row: rows[item.index], rowIndex: item.index, start: item.start, rowHeight: rowHeight, autoRowHeight: autoRowHeight, measureElement: autoRowHeight ? virtual.measureElement : undefined, rowClassName: rowClassName, renderRowDetail: renderRowDetail, detailWidth: viewportWidth ?? totalWidth, cellStyle: cellStyle, columns: columns, columnGaps: columnGaps, columnIndexes: columnIndexes, contentVersion: table.options, contentState: table.state, focusedId: focused?.id, copied: copied, contentClassName: contentClassName, onRowClick: onRowClick, onRowActivate: onRowActivate, isRowHighlighted: isRowHighlighted }, item.key))) }), rows.length > 0 && status === "error" && (_jsxs("div", { role: "alert", className: "mui-964a9431ff49 mui-30150dd033ab mui-5b272f3c5076 mui-094f5333853b", children: [error ?? "Could not refresh rows.", retry && (_jsx(Button, { onClick: retry, variant: "outline", size: "sm", children: "Retry" }))] })), loadMore?.available && (_jsxs("div", { className: "mui-964a9431ff49 mui-635702706586 mui-222f930b8752 mui-71556df3b421 mui-a503dd374cca mui-074569488cca mui-96b92a971c95 mui-c74ab393b96d mui-35f35c41d134", children: [loadMore.loading ? (_jsxs("div", { role: "status", className: "mui-222f930b8752 mui-71556df3b421 mui-074569488cca", children: [_jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "mui-2bd43fb57913 mui-27ead27a81df mui-2c14b55d77e6 mui-237747164b60", children: _jsx("path", { d: "M12 3v3m6.366-.366-2.12 2.12M21 12h-3m.366 6.366-2.12-2.12M12 21v-3m-6.366.366 2.12-2.12M3 12h3m-.366-6.366 2.12 2.12" }) }), _jsx("span", { children: "Loading more\u2026" })] })) : (_jsx(Button, { size: "sm", variant: "ghost", onClick: () => {
|
|
96
106
|
requested.current = null;
|
|
97
107
|
void Promise.resolve()
|
|
98
108
|
.then(() => loadMore.load())
|
|
@@ -3,7 +3,7 @@ import type { Column } from "@tanstack/react-table";
|
|
|
3
3
|
import type { DataTableFeatures } from "./features.js";
|
|
4
4
|
import type { tableLayout } from "./table-layout.js";
|
|
5
5
|
/** Keep pinned and focused columns mounted, with two columns of overscan. */
|
|
6
|
-
export declare function useColumnWindow<T extends object>(layout: ReturnType<typeof tableLayout<T>>, container: RefObject<HTMLDivElement | null>, viewportWidth: number | null, focusedColumn?: string): {
|
|
6
|
+
export declare function useColumnWindow<T extends object>(layout: ReturnType<typeof tableLayout<T>>, container: RefObject<HTMLDivElement | null>, viewportWidth: number | null, focusedColumn?: string, enabled?: boolean): {
|
|
7
7
|
columns: Column<{
|
|
8
8
|
cellSelectionFeature: import("@tanstack/react-table").TableFeature;
|
|
9
9
|
columnResizingFeature: import("@tanstack/react-table").TableFeature;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useLayoutEffect, useMemo, useState } from "react";
|
|
3
3
|
/** Keep pinned and focused columns mounted, with two columns of overscan. */
|
|
4
|
-
export function useColumnWindow(layout, container, viewportWidth, focusedColumn) {
|
|
4
|
+
export function useColumnWindow(layout, container, viewportWidth, focusedColumn, enabled = true) {
|
|
5
5
|
const [scrollLeft, setScrollLeft] = useState(0);
|
|
6
6
|
const [activeColumn, setActiveColumn] = useState();
|
|
7
7
|
useLayoutEffect(() => {
|
|
@@ -39,7 +39,8 @@ export function useColumnWindow(layout, container, viewportWidth, focusedColumn)
|
|
|
39
39
|
const styles = new Map();
|
|
40
40
|
let previousEnd = 0;
|
|
41
41
|
layout.columns.forEach((column, index) => {
|
|
42
|
-
if (
|
|
42
|
+
if (!enabled ||
|
|
43
|
+
(index >= start && index <= end) ||
|
|
43
44
|
(layout.pinningActive && column.getIsPinned()) ||
|
|
44
45
|
column.id === focusedColumn ||
|
|
45
46
|
column.id === activeColumn) {
|
|
@@ -60,5 +61,5 @@ export function useColumnWindow(layout, container, viewportWidth, focusedColumn)
|
|
|
60
61
|
columnGaps,
|
|
61
62
|
cellStyle: (column) => styles.get(column.id),
|
|
62
63
|
};
|
|
63
|
-
}, [layout, start, end, focusedColumn, activeColumn]);
|
|
64
|
+
}, [layout, start, end, focusedColumn, activeColumn, enabled]);
|
|
64
65
|
}
|
|
@@ -4,7 +4,7 @@ import type { DataTableFeatures } from "./features.js";
|
|
|
4
4
|
import type { PreferenceStorage, TablePreferences } from "./state.js";
|
|
5
5
|
export type DataTableInstance<T extends object> = ReactTable<DataTableFeatures, T>;
|
|
6
6
|
export interface UseDataTableOptions<T extends object> extends Omit<TableOptions<DataTableFeatures, T>, "features" | "data" | "columns" | "manualFiltering" | "manualSorting" | "manualPagination"> {
|
|
7
|
-
rows: T[];
|
|
7
|
+
rows: readonly T[];
|
|
8
8
|
columns: TableColumn<T>[];
|
|
9
9
|
getRowId: (row: T, index: number) => string;
|
|
10
10
|
processing?: {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useLayoutEffect, useMemo, useRef } from "react";
|
|
3
|
-
/** Reuse equal array shells; never deep-compare records or ignore changed callbacks. */
|
|
4
3
|
export function useStableArray(input) {
|
|
5
4
|
const committed = useRef(input);
|
|
6
5
|
const value = useMemo(() => {
|
|
@@ -4,7 +4,7 @@ export declare function useTableInteraction<T extends object>({ table, pinningAc
|
|
|
4
4
|
table: DataTableInstance<T>;
|
|
5
5
|
pinningActive: boolean;
|
|
6
6
|
container: RefObject<HTMLDivElement | null>;
|
|
7
|
-
queryKey?:
|
|
7
|
+
queryKey?: unknown;
|
|
8
8
|
onRowActivate?: (row: T) => void;
|
|
9
9
|
onCopyError?: (error: unknown) => void;
|
|
10
10
|
scrollToIndex: (index: number) => void;
|
|
@@ -21,7 +21,9 @@ export function useTableInteraction({ table, pinningActive, container, queryKey,
|
|
|
21
21
|
const remember = (event) => {
|
|
22
22
|
const target = event.target;
|
|
23
23
|
ownedFocus.current =
|
|
24
|
-
|
|
24
|
+
target.closest('[role="grid"]') === element && target.getAttribute("role") === "gridcell"
|
|
25
|
+
? target
|
|
26
|
+
: null;
|
|
25
27
|
};
|
|
26
28
|
document.addEventListener("focusin", remember);
|
|
27
29
|
return () => document.removeEventListener("focusin", remember);
|
|
@@ -52,7 +54,8 @@ export function useTableInteraction({ table, pinningActive, container, queryKey,
|
|
|
52
54
|
}, [queryKey, resetCellSelection, container]);
|
|
53
55
|
useEffect(() => {
|
|
54
56
|
const dismiss = (event) => {
|
|
55
|
-
if (container.current &&
|
|
57
|
+
if (container.current &&
|
|
58
|
+
event.target.closest('[role="grid"]') !== container.current)
|
|
56
59
|
resetCellSelection(true);
|
|
57
60
|
};
|
|
58
61
|
document.addEventListener("pointerdown", dismiss);
|
|
@@ -102,7 +105,9 @@ export function useTableInteraction({ table, pinningActive, container, queryKey,
|
|
|
102
105
|
});
|
|
103
106
|
}
|
|
104
107
|
const onKeyDown = (event) => {
|
|
105
|
-
if (event.
|
|
108
|
+
if (event.defaultPrevented ||
|
|
109
|
+
event.target.closest('[role="grid"]') !== event.currentTarget ||
|
|
110
|
+
event.target.closest(interactiveSelector))
|
|
106
111
|
return;
|
|
107
112
|
if ((event.ctrlKey || event.metaKey) &&
|
|
108
113
|
event.key.toLowerCase() === "c" &&
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FilterController } from "../filters/use-filters.js";
|
|
2
|
+
import type { DataTableInstance } from "./use-data-table.js";
|
|
3
|
+
/** Only query state contributes to this key. Row appends and UI state never do. */
|
|
4
|
+
export declare function useTableResults<T extends object>(table: DataTableInstance<T>, queryKey?: string, filters?: FilterController): {
|
|
5
|
+
resultKey: string | any[];
|
|
6
|
+
hasFilters: boolean;
|
|
7
|
+
clearFilters: (() => void) | undefined;
|
|
8
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
function hasValue(value) {
|
|
4
|
+
if (value == null || value === "")
|
|
5
|
+
return false;
|
|
6
|
+
if (Array.isArray(value))
|
|
7
|
+
return value.some((item) => item != null && item !== "");
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
/** Only query state contributes to this key. Row appends and UI state never do. */
|
|
11
|
+
export function useTableResults(table, queryKey, filters) {
|
|
12
|
+
const { sorting, columnFilters, globalFilter, pagination } = table.state;
|
|
13
|
+
const entries = filters?.entries;
|
|
14
|
+
const search = filters?.search;
|
|
15
|
+
const resultKey = useMemo(() => {
|
|
16
|
+
const state = [
|
|
17
|
+
queryKey,
|
|
18
|
+
sorting,
|
|
19
|
+
columnFilters,
|
|
20
|
+
globalFilter,
|
|
21
|
+
pagination.pageIndex,
|
|
22
|
+
pagination.pageSize,
|
|
23
|
+
search,
|
|
24
|
+
];
|
|
25
|
+
try {
|
|
26
|
+
return JSON.stringify([...state, entries?.map(({ id, field, value }) => [id, field.codec.serialize(value)])], (_key, value) => (typeof value === "bigint" ? { $bigint: String(value) } : value));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Opaque application values may not be serializable. In that case their
|
|
30
|
+
// immutable references drive changes, without crashing table rendering.
|
|
31
|
+
return [...state, entries];
|
|
32
|
+
}
|
|
33
|
+
}, [
|
|
34
|
+
queryKey,
|
|
35
|
+
sorting,
|
|
36
|
+
columnFilters,
|
|
37
|
+
globalFilter,
|
|
38
|
+
pagination.pageIndex,
|
|
39
|
+
pagination.pageSize,
|
|
40
|
+
search,
|
|
41
|
+
entries,
|
|
42
|
+
]);
|
|
43
|
+
const hasFilters = Boolean(columnFilters.some(({ value }) => hasValue(value)) ||
|
|
44
|
+
hasValue(globalFilter) ||
|
|
45
|
+
search?.trim() ||
|
|
46
|
+
filters?.active.length);
|
|
47
|
+
const clearFilters = () => {
|
|
48
|
+
if (filters)
|
|
49
|
+
filters.clear();
|
|
50
|
+
else {
|
|
51
|
+
if (columnFilters.length)
|
|
52
|
+
table.setColumnFilters([]);
|
|
53
|
+
if (hasValue(globalFilter))
|
|
54
|
+
table.setGlobalFilter(undefined);
|
|
55
|
+
if (pagination.pageIndex)
|
|
56
|
+
table.setPageIndex(0);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const canClear = !filters ||
|
|
60
|
+
Boolean(search?.trim()) ||
|
|
61
|
+
filters.entries.some(({ field, value }) => !field.hidden && !field.disabled && field.removable !== false && field.isActive(value));
|
|
62
|
+
return { resultKey, hasFilters, clearFilters: canClear ? clearFilters : undefined };
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mendylanda/ui",
|
|
3
|
-
"version": "0.3.0-alpha.
|
|
3
|
+
"version": "0.3.0-alpha.8",
|
|
4
4
|
"description": "Mendy Landa’s reusable React components. Typed filters and tables with shared interaction behavior and customizable UI.",
|
|
5
5
|
"homepage": "https://ui.mendylanda.com",
|
|
6
6
|
"license": "MIT",
|