@12-apps/ui 6.38.0 → 6.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/components/data-display/DataGrid/DataGrid.body.js +3 -2
- package/dist/_internal/components/data-display/DataGrid/DataGrid.cells.js +2 -1
- package/dist/_internal/components/data-display/DataGrid/DataGrid.js +4 -4
- package/dist/_internal/components/data-display/DataGrid/DataGrid.model.js +2 -1
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +19 -19
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +26 -26
- package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +5 -5
- package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +4 -4
- package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +3 -3
- package/dist/_internal/components/data-display/DataViews/base-list-card.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-columns.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-display-tabs.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +8 -8
- package/dist/_internal/components/data-display/DataViews/data-views-grid-helpers.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +16 -16
- package/dist/_internal/components/data-display/DataViews/data-views-layout-context.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-overflow-costs.js +4 -3
- package/dist/_internal/components/data-display/DataViews/data-views-overflow.js +3 -2
- package/dist/_internal/components/data-display/DataViews/data-views-scope-tabs.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +5 -5
- package/dist/_internal/components/data-display/DataViews/list-card-rails.js +2 -2
- package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +3 -3
- package/dist/_internal/components/data-display/FleetMap/FleetBody.js +9 -9
- package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +8 -8
- package/dist/_internal/components/data-display/FleetMap/FleetMap.js +10 -10
- package/dist/_internal/components/data-display/LazyImage/LazyImage.js +1 -1
- package/dist/_internal/components/data-display/MapPreview/MapDecorations.js +2 -2
- package/dist/_internal/components/data-display/MapPreview/MapPreview.hooks.js +2 -2
- package/dist/_internal/components/data-display/MapPreview/MapPreview.js +7 -7
- package/dist/_internal/components/data-display/MapPreview/MapTiles.js +2 -2
- package/dist/_internal/components/data-display/MapPreview/StaticMapView.js +4 -4
- package/dist/_internal/components/data-display/MapPreview/mapProjection.js +3 -3
- package/dist/_internal/components/data-display/MapPreview/useMapPreview.js +3 -3
- package/dist/_internal/components/data-display/Table/Table.helpers.js +5 -3
- package/dist/_internal/components/data-display/Table/Table.hooks.js +2 -1
- package/dist/_internal/components/data-display/Table/Table.js +4 -4
- package/dist/_internal/components/data-display/Table/TableParts.hooks.js +4 -2
- package/dist/_internal/components/data-display/Table/TableParts.js +4 -2
- package/dist/_internal/components/data-display/index.js +19 -19
- package/dist/_internal/components/form/Calendar/Calendar.js +5 -4
- package/dist/_internal/components/form/Calendar/CalendarDay.js +2 -1
- package/dist/_internal/components/form/Calendar/CalendarDayCell.js +3 -2
- package/dist/_internal/components/form/Calendar/CalendarMonth.js +4 -3
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +5 -5
- package/dist/_internal/components/form/Switch/Switch.js +4 -4
- package/dist/_internal/components/form/Switch/Switch.metrics.js +5 -1
- package/dist/_internal/components/form/Switch/Switch.parts.js +3 -3
- package/dist/_internal/components/form/Switch/Switch.styles.js +2 -2
- package/dist/_internal/components/form/index.js +9 -9
- package/dist/_internal/components/index.js +38 -38
- package/dist/_internal/components/layout/CardGrid/CardGrid.js +2 -1
- package/dist/_internal/components/layout/Resizable/Resizable.helpers.js +8 -3
- package/dist/_internal/components/layout/Resizable/Resizable.hooks.js +3 -2
- package/dist/_internal/components/layout/Resizable/Resizable.js +4 -3
- package/dist/_internal/components/layout/ScrollArea/ScrollArea.helpers.js +1 -1
- package/dist/_internal/components/layout/ScrollArea/ScrollArea.js +2 -2
- package/dist/_internal/components/layout/index.js +5 -5
- package/dist/_internal/components/utility/InfiniteScroll/InfiniteScroll.hooks.js +1 -1
- package/dist/_internal/components/utility/InfiniteScroll/InfiniteScroll.js +4 -3
- package/dist/_internal/components/utility/InfiniteScroll/InfiniteScroll.parts.js +2 -1
- package/dist/_internal/components/utility/VirtualList/VirtualList.hooks.js +6 -3
- package/dist/_internal/components/utility/VirtualList/VirtualList.js +3 -2
- package/dist/_internal/components/utility/index.js +5 -5
- package/dist/{chunk-J2DAQQQH.js → chunk-222HN7GK.js} +33 -64
- package/dist/chunk-222HN7GK.js.map +1 -0
- package/dist/{chunk-MR2HKBHS.js → chunk-27LOJVR3.js} +2 -2
- package/dist/{chunk-S3D5VBHW.js → chunk-3YOXVNO4.js} +7 -7
- package/dist/{chunk-CZIX4BW2.js → chunk-4ALF5PB5.js} +3 -3
- package/dist/{chunk-XJPJ6ESI.js → chunk-4OAKGKK5.js} +3 -3
- package/dist/{chunk-4CHROSWR.js → chunk-5ETBB2DG.js} +2 -2
- package/dist/{chunk-ATSHKSSD.js → chunk-5KNDAC24.js} +20 -7
- package/dist/chunk-5KNDAC24.js.map +1 -0
- package/dist/{chunk-ULTOQ6ZV.js → chunk-5LWB4BYX.js} +80 -89
- package/dist/chunk-5LWB4BYX.js.map +1 -0
- package/dist/{chunk-46UPILLK.js → chunk-5NT2M2JI.js} +2 -2
- package/dist/{chunk-H5BEWPEY.js → chunk-6N2EDWMG.js} +2 -2
- package/dist/{chunk-GJQYM3PM.js → chunk-6PU3JYVY.js} +2 -2
- package/dist/{chunk-PUBPZOQJ.js → chunk-AG3DY5TH.js} +8 -5
- package/dist/chunk-AG3DY5TH.js.map +1 -0
- package/dist/{chunk-PPRV4LTM.js → chunk-BWHOCNGW.js} +4 -4
- package/dist/chunk-BWHOCNGW.js.map +1 -0
- package/dist/{chunk-TUBCN4DJ.js → chunk-CB6DTWD5.js} +7 -7
- package/dist/chunk-CB6DTWD5.js.map +1 -0
- package/dist/{chunk-ZAY6OA6F.js → chunk-D4FZ3ANG.js} +15 -5
- package/dist/chunk-D4FZ3ANG.js.map +1 -0
- package/dist/{chunk-Y7F5JBAT.js → chunk-DDRKYNPB.js} +2 -2
- package/dist/{chunk-DLJGBJZW.js → chunk-DGMDQHMI.js} +16 -9
- package/dist/chunk-DGMDQHMI.js.map +1 -0
- package/dist/{chunk-IAGOUTI6.js → chunk-DNT5PZLF.js} +21 -12
- package/dist/chunk-DNT5PZLF.js.map +1 -0
- package/dist/{chunk-DZA7RSLX.js → chunk-DVSO3EG6.js} +19 -11
- package/dist/chunk-DVSO3EG6.js.map +1 -0
- package/dist/{chunk-OS6KPL4D.js → chunk-EHYI2WCJ.js} +4 -4
- package/dist/{chunk-NB3FGWU4.js → chunk-EQXIW5MQ.js} +2 -2
- package/dist/{chunk-C66RGVAS.js → chunk-ERY6D2OV.js} +6 -4
- package/dist/chunk-ERY6D2OV.js.map +1 -0
- package/dist/{chunk-M2JTIH5M.js → chunk-F44R7US6.js} +2 -2
- package/dist/{chunk-AROBXRC5.js → chunk-F7JTIHV5.js} +18 -7
- package/dist/chunk-F7JTIHV5.js.map +1 -0
- package/dist/{chunk-T7DE44SP.js → chunk-FF2D7V7T.js} +6 -4
- package/dist/chunk-FF2D7V7T.js.map +1 -0
- package/dist/{chunk-XJJXBUPN.js → chunk-FX26DAFF.js} +2 -2
- package/dist/{chunk-R6SN73RX.js → chunk-GLHNMTP6.js} +7 -7
- package/dist/{chunk-YU26GBNX.js → chunk-H3AQQOTI.js} +9 -4
- package/dist/chunk-H3AQQOTI.js.map +1 -0
- package/dist/{chunk-HTZNB6IV.js → chunk-H5ZTIELC.js} +23 -8
- package/dist/chunk-H5ZTIELC.js.map +1 -0
- package/dist/{chunk-GSFNH4C5.js → chunk-HBP2OU4Q.js} +15 -8
- package/dist/chunk-HBP2OU4Q.js.map +1 -0
- package/dist/{chunk-I4QA2F4L.js → chunk-HBRQPG7H.js} +5 -5
- package/dist/{chunk-HGMBY5LP.js → chunk-HQWJUHR4.js} +18 -11
- package/dist/chunk-HQWJUHR4.js.map +1 -0
- package/dist/{chunk-CNQUCNEA.js → chunk-I3F4C5SS.js} +3 -3
- package/dist/{chunk-UFJYJHQI.js → chunk-J5VWGQSR.js} +2 -2
- package/dist/{chunk-MTFCPPZ5.js → chunk-JWZJSXI5.js} +3 -2
- package/dist/chunk-JWZJSXI5.js.map +1 -0
- package/dist/{chunk-4JFL62K3.js → chunk-K7FSTB2K.js} +3 -3
- package/dist/{chunk-FFCJ7NR2.js → chunk-KRQUPE4K.js} +4 -4
- package/dist/{chunk-2OYFTSG4.js → chunk-KXLUMEDX.js} +2 -2
- package/dist/{chunk-DVAAUWTC.js → chunk-LCHCE2G5.js} +2 -2
- package/dist/{chunk-G4HBNILE.js → chunk-LEHMWJNZ.js} +3 -3
- package/dist/{chunk-P6TNXBDA.js → chunk-MYKWJCR7.js} +9 -9
- package/dist/chunk-MYKWJCR7.js.map +1 -0
- package/dist/{chunk-TQ6FPOPD.js → chunk-ODW2D5PN.js} +39 -30
- package/dist/chunk-ODW2D5PN.js.map +1 -0
- package/dist/{chunk-RZYSKQTS.js → chunk-PCBZYORN.js} +3 -3
- package/dist/{chunk-5OBXEMQO.js → chunk-PRIBOWX4.js} +3 -3
- package/dist/{chunk-F42MJOHM.js → chunk-PVM7XTLZ.js} +64 -62
- package/dist/chunk-PVM7XTLZ.js.map +1 -0
- package/dist/{chunk-3TDVGZZN.js → chunk-QBTBRJ2Q.js} +37 -13
- package/dist/chunk-QBTBRJ2Q.js.map +1 -0
- package/dist/{chunk-2WFDHFK4.js → chunk-QNCWSDXE.js} +26 -11
- package/dist/chunk-QNCWSDXE.js.map +1 -0
- package/dist/{chunk-PQECNGDE.js → chunk-QSRZOXQI.js} +2 -2
- package/dist/{chunk-RHIDWUK7.js → chunk-QUWK7SYN.js} +1 -2
- package/dist/chunk-QUWK7SYN.js.map +1 -0
- package/dist/{chunk-UN5INW6K.js → chunk-R53ZOW4B.js} +8 -4
- package/dist/chunk-R53ZOW4B.js.map +1 -0
- package/dist/{chunk-DCJSHYE5.js → chunk-RSDYS5B3.js} +4 -4
- package/dist/{chunk-N5GVW6RO.js → chunk-S6IWKDWT.js} +2 -2
- package/dist/{chunk-TKC6WHGB.js → chunk-SBIZXZPP.js} +2 -2
- package/dist/{chunk-D5SZXH7Q.js → chunk-TNBJ4DK4.js} +7 -3
- package/dist/chunk-TNBJ4DK4.js.map +1 -0
- package/dist/{chunk-PMOEG36E.js → chunk-XZJM6EPC.js} +8 -6
- package/dist/chunk-XZJM6EPC.js.map +1 -0
- package/dist/{chunk-QF6LTUCE.js → chunk-Y2X7LYIN.js} +4 -4
- package/dist/chunk-Y2X7LYIN.js.map +1 -0
- package/dist/{chunk-UEVHI62V.js → chunk-YCCY77W5.js} +2 -2
- package/dist/{chunk-DF4K5XVW.js → chunk-YZVR5ROE.js} +14 -6
- package/dist/chunk-YZVR5ROE.js.map +1 -0
- package/dist/{chunk-AUSUCZYR.js → chunk-ZBVU2YWV.js} +5 -5
- package/dist/chunk-ZBVU2YWV.js.map +1 -0
- package/dist/{chunk-VZIB5W5L.js → chunk-ZGCPDA3F.js} +2 -2
- package/dist/data-display/DataGrid.js +4 -4
- package/dist/data-display/DataViews.js +29 -29
- package/dist/data-display/FleetMap.js +10 -10
- package/dist/data-display/LazyImage.js +1 -1
- package/dist/data-display/MapPreview.js +7 -7
- package/dist/data-display/Table.js +4 -4
- package/dist/form/Calendar.js +5 -4
- package/dist/form/DateRangePicker.js +5 -5
- package/dist/form/Switch.js +4 -4
- package/dist/layout/CardGrid.js +2 -1
- package/dist/layout/Resizable.js +4 -3
- package/dist/layout/ScrollArea.js +2 -2
- package/dist/native/form/Switch.js +3 -1
- package/dist/native/form/Switch.js.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.body.d.ts.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.cells.d.ts +4 -2
- package/dist/types/components/data-display/DataGrid/DataGrid.cells.d.ts.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.model.d.ts +7 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.model.d.ts.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts +10 -4
- package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-columns.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-helpers.d.ts +2 -0
- package/dist/types/components/data-display/DataViews/data-views-grid-helpers.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-layout-context.d.ts +7 -3
- package/dist/types/components/data-display/DataViews/data-views-layout-context.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-overflow-costs.d.ts +19 -9
- package/dist/types/components/data-display/DataViews/data-views-overflow-costs.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-overflow.d.ts.map +1 -1
- package/dist/types/components/data-display/LazyImage/LazyImage.d.ts.map +1 -1
- package/dist/types/components/data-display/LazyImage/LazyImage.types.d.ts +3 -1
- package/dist/types/components/data-display/LazyImage/LazyImage.types.d.ts.map +1 -1
- package/dist/types/components/data-display/MapPreview/MapTiles.d.ts.map +1 -1
- package/dist/types/components/data-display/MapPreview/mapProjection.d.ts +6 -1
- package/dist/types/components/data-display/MapPreview/mapProjection.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/Table.helpers.d.ts +6 -0
- package/dist/types/components/data-display/Table/Table.helpers.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/Table.hooks.d.ts +9 -1
- package/dist/types/components/data-display/Table/Table.hooks.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/Table.types.d.ts +6 -2
- package/dist/types/components/data-display/Table/Table.types.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/TableParts.d.ts +2 -0
- package/dist/types/components/data-display/Table/TableParts.d.ts.map +1 -1
- package/dist/types/components/form/Calendar/Calendar.d.ts.map +1 -1
- package/dist/types/components/form/Calendar/CalendarDay.d.ts.map +1 -1
- package/dist/types/components/form/Calendar/CalendarMonth.d.ts.map +1 -1
- package/dist/types/components/form/Switch/Switch.metrics.d.ts +13 -3
- package/dist/types/components/form/Switch/Switch.metrics.d.ts.map +1 -1
- package/dist/types/components/form/Switch/Switch.styles.d.ts.map +1 -1
- package/dist/types/components/layout/CardGrid/CardGrid.d.ts +9 -7
- package/dist/types/components/layout/CardGrid/CardGrid.d.ts.map +1 -1
- package/dist/types/components/layout/Resizable/Resizable.d.ts.map +1 -1
- package/dist/types/components/layout/Resizable/Resizable.helpers.d.ts +21 -9
- package/dist/types/components/layout/Resizable/Resizable.helpers.d.ts.map +1 -1
- package/dist/types/components/layout/Resizable/Resizable.hooks.d.ts +13 -3
- package/dist/types/components/layout/Resizable/Resizable.hooks.d.ts.map +1 -1
- package/dist/types/components/layout/Resizable/Resizable.types.d.ts +10 -0
- package/dist/types/components/layout/Resizable/Resizable.types.d.ts.map +1 -1
- package/dist/types/components/layout/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/components/layout/ScrollArea/ScrollArea.helpers.d.ts +1 -1
- package/dist/types/components/layout/ScrollArea/ScrollArea.helpers.d.ts.map +1 -1
- package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts +4 -1
- package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts.map +1 -1
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.d.ts.map +1 -1
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.hooks.d.ts +3 -2
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.hooks.d.ts.map +1 -1
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts +3 -2
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts.map +1 -1
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts +9 -0
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts.map +1 -1
- package/dist/types/components/utility/VirtualList/VirtualList.d.ts.map +1 -1
- package/dist/types/components/utility/VirtualList/VirtualList.hooks.d.ts +24 -28
- package/dist/types/components/utility/VirtualList/VirtualList.hooks.d.ts.map +1 -1
- package/dist/types/components/utility/VirtualList/VirtualList.types.d.ts +17 -0
- package/dist/types/components/utility/VirtualList/VirtualList.types.d.ts.map +1 -1
- package/dist/types-native/components/form/Switch/Switch.metrics.d.ts +13 -3
- package/dist/types-native/components/form/Switch/Switch.metrics.d.ts.map +1 -1
- package/dist/utility/InfiniteScroll.js +4 -3
- package/dist/utility/VirtualList.js +3 -2
- package/package.json +1 -1
- package/src/components/data-display/DataGrid/DataGrid.body.tsx +27 -7
- package/src/components/data-display/DataGrid/DataGrid.cells.tsx +33 -9
- package/src/components/data-display/DataGrid/DataGrid.model.ts +24 -11
- package/src/components/data-display/DataGrid/DataGrid.types.ts +12 -6
- package/src/components/data-display/DataViews/data-views-columns.ts +14 -3
- package/src/components/data-display/DataViews/data-views-grid-helpers.tsx +5 -3
- package/src/components/data-display/DataViews/data-views-layout-context.tsx +12 -9
- package/src/components/data-display/DataViews/data-views-overflow-costs.ts +32 -14
- package/src/components/data-display/DataViews/data-views-overflow.ts +40 -26
- package/src/components/data-display/LazyImage/LazyImage.tsx +5 -3
- package/src/components/data-display/LazyImage/LazyImage.types.ts +3 -1
- package/src/components/data-display/MapPreview/MapTiles.tsx +16 -9
- package/src/components/data-display/MapPreview/mapProjection.ts +10 -5
- package/src/components/data-display/Table/Table.helpers.ts +7 -1
- package/src/components/data-display/Table/Table.hooks.ts +16 -5
- package/src/components/data-display/Table/Table.types.ts +6 -2
- package/src/components/data-display/Table/TableParts.tsx +38 -42
- package/src/components/form/Calendar/Calendar.tsx +4 -2
- package/src/components/form/Calendar/CalendarDay.tsx +6 -3
- package/src/components/form/Calendar/CalendarMonth.tsx +6 -3
- package/src/components/form/Switch/Switch.metrics.ts +19 -5
- package/src/components/form/Switch/Switch.styles.ts +5 -3
- package/src/components/layout/CardGrid/CardGrid.tsx +37 -24
- package/src/components/layout/Resizable/Resizable.helpers.ts +43 -21
- package/src/components/layout/Resizable/Resizable.hooks.ts +17 -9
- package/src/components/layout/Resizable/Resizable.md +9 -5
- package/src/components/layout/Resizable/Resizable.tsx +20 -8
- package/src/components/layout/Resizable/Resizable.types.ts +10 -0
- package/src/components/layout/ScrollArea/ScrollArea.helpers.ts +0 -2
- package/src/components/layout/ScrollArea/ScrollArea.tsx +5 -3
- package/src/components/layout/ScrollArea/ScrollArea.types.ts +4 -1
- package/src/components/utility/InfiniteScroll/InfiniteScroll.hooks.ts +5 -4
- package/src/components/utility/InfiniteScroll/InfiniteScroll.parts.tsx +29 -12
- package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +11 -5
- package/src/components/utility/InfiniteScroll/InfiniteScroll.types.ts +10 -2
- package/src/components/utility/VirtualList/VirtualList.hooks.ts +101 -112
- package/src/components/utility/VirtualList/VirtualList.tsx +36 -65
- package/src/components/utility/VirtualList/VirtualList.types.ts +20 -3
- package/dist/chunk-2WFDHFK4.js.map +0 -1
- package/dist/chunk-3TDVGZZN.js.map +0 -1
- package/dist/chunk-AROBXRC5.js.map +0 -1
- package/dist/chunk-ATSHKSSD.js.map +0 -1
- package/dist/chunk-AUSUCZYR.js.map +0 -1
- package/dist/chunk-C66RGVAS.js.map +0 -1
- package/dist/chunk-D5SZXH7Q.js.map +0 -1
- package/dist/chunk-DF4K5XVW.js.map +0 -1
- package/dist/chunk-DLJGBJZW.js.map +0 -1
- package/dist/chunk-DZA7RSLX.js.map +0 -1
- package/dist/chunk-F42MJOHM.js.map +0 -1
- package/dist/chunk-GSFNH4C5.js.map +0 -1
- package/dist/chunk-HGMBY5LP.js.map +0 -1
- package/dist/chunk-HTZNB6IV.js.map +0 -1
- package/dist/chunk-IAGOUTI6.js.map +0 -1
- package/dist/chunk-J2DAQQQH.js.map +0 -1
- package/dist/chunk-MTFCPPZ5.js.map +0 -1
- package/dist/chunk-P6TNXBDA.js.map +0 -1
- package/dist/chunk-PMOEG36E.js.map +0 -1
- package/dist/chunk-PPRV4LTM.js.map +0 -1
- package/dist/chunk-PUBPZOQJ.js.map +0 -1
- package/dist/chunk-QF6LTUCE.js.map +0 -1
- package/dist/chunk-RHIDWUK7.js.map +0 -1
- package/dist/chunk-T7DE44SP.js.map +0 -1
- package/dist/chunk-TQ6FPOPD.js.map +0 -1
- package/dist/chunk-TUBCN4DJ.js.map +0 -1
- package/dist/chunk-ULTOQ6ZV.js.map +0 -1
- package/dist/chunk-UN5INW6K.js.map +0 -1
- package/dist/chunk-YU26GBNX.js.map +0 -1
- package/dist/chunk-ZAY6OA6F.js.map +0 -1
- /package/dist/{chunk-MR2HKBHS.js.map → chunk-27LOJVR3.js.map} +0 -0
- /package/dist/{chunk-S3D5VBHW.js.map → chunk-3YOXVNO4.js.map} +0 -0
- /package/dist/{chunk-CZIX4BW2.js.map → chunk-4ALF5PB5.js.map} +0 -0
- /package/dist/{chunk-XJPJ6ESI.js.map → chunk-4OAKGKK5.js.map} +0 -0
- /package/dist/{chunk-4CHROSWR.js.map → chunk-5ETBB2DG.js.map} +0 -0
- /package/dist/{chunk-46UPILLK.js.map → chunk-5NT2M2JI.js.map} +0 -0
- /package/dist/{chunk-H5BEWPEY.js.map → chunk-6N2EDWMG.js.map} +0 -0
- /package/dist/{chunk-GJQYM3PM.js.map → chunk-6PU3JYVY.js.map} +0 -0
- /package/dist/{chunk-Y7F5JBAT.js.map → chunk-DDRKYNPB.js.map} +0 -0
- /package/dist/{chunk-OS6KPL4D.js.map → chunk-EHYI2WCJ.js.map} +0 -0
- /package/dist/{chunk-NB3FGWU4.js.map → chunk-EQXIW5MQ.js.map} +0 -0
- /package/dist/{chunk-M2JTIH5M.js.map → chunk-F44R7US6.js.map} +0 -0
- /package/dist/{chunk-XJJXBUPN.js.map → chunk-FX26DAFF.js.map} +0 -0
- /package/dist/{chunk-R6SN73RX.js.map → chunk-GLHNMTP6.js.map} +0 -0
- /package/dist/{chunk-I4QA2F4L.js.map → chunk-HBRQPG7H.js.map} +0 -0
- /package/dist/{chunk-CNQUCNEA.js.map → chunk-I3F4C5SS.js.map} +0 -0
- /package/dist/{chunk-UFJYJHQI.js.map → chunk-J5VWGQSR.js.map} +0 -0
- /package/dist/{chunk-4JFL62K3.js.map → chunk-K7FSTB2K.js.map} +0 -0
- /package/dist/{chunk-FFCJ7NR2.js.map → chunk-KRQUPE4K.js.map} +0 -0
- /package/dist/{chunk-2OYFTSG4.js.map → chunk-KXLUMEDX.js.map} +0 -0
- /package/dist/{chunk-DVAAUWTC.js.map → chunk-LCHCE2G5.js.map} +0 -0
- /package/dist/{chunk-G4HBNILE.js.map → chunk-LEHMWJNZ.js.map} +0 -0
- /package/dist/{chunk-RZYSKQTS.js.map → chunk-PCBZYORN.js.map} +0 -0
- /package/dist/{chunk-5OBXEMQO.js.map → chunk-PRIBOWX4.js.map} +0 -0
- /package/dist/{chunk-PQECNGDE.js.map → chunk-QSRZOXQI.js.map} +0 -0
- /package/dist/{chunk-DCJSHYE5.js.map → chunk-RSDYS5B3.js.map} +0 -0
- /package/dist/{chunk-N5GVW6RO.js.map → chunk-S6IWKDWT.js.map} +0 -0
- /package/dist/{chunk-TKC6WHGB.js.map → chunk-SBIZXZPP.js.map} +0 -0
- /package/dist/{chunk-UEVHI62V.js.map → chunk-YCCY77W5.js.map} +0 -0
- /package/dist/{chunk-VZIB5W5L.js.map → chunk-ZGCPDA3F.js.map} +0 -0
|
@@ -2,27 +2,33 @@ import Alert from '@mui/material/Alert/index.js';
|
|
|
2
2
|
import Box from '@mui/material/Box/index.js';
|
|
3
3
|
import CircularProgress from '@mui/material/CircularProgress/index.js';
|
|
4
4
|
import Typography from '@mui/material/Typography/index.js';
|
|
5
|
+
import { useTheme, type SxProps, type Theme } from '@mui/material/styles/index.js';
|
|
5
6
|
import React from 'react';
|
|
6
7
|
|
|
8
|
+
import { rem } from '../../../tokens/relative';
|
|
9
|
+
|
|
7
10
|
import type { InfiniteScrollProps } from './InfiniteScroll.types';
|
|
8
11
|
|
|
9
12
|
type Variant = NonNullable<InfiniteScrollProps['variant']>;
|
|
10
13
|
|
|
11
|
-
const CENTERED = {
|
|
14
|
+
const CENTERED: SxProps<Theme> = {
|
|
12
15
|
display: 'flex',
|
|
13
16
|
justifyContent: 'center',
|
|
14
17
|
alignItems: 'center',
|
|
15
18
|
p: 2,
|
|
16
|
-
}
|
|
19
|
+
};
|
|
17
20
|
|
|
18
|
-
export const DefaultLoader: React.FC<{ loadingText: string }> = ({ loadingText }) =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
export const DefaultLoader: React.FC<{ loadingText: string }> = ({ loadingText }) => {
|
|
22
|
+
const theme = useTheme();
|
|
23
|
+
return (
|
|
24
|
+
<Box sx={CENTERED}>
|
|
25
|
+
<CircularProgress size={rem(theme, 24)} />
|
|
26
|
+
<Typography variant="body2" sx={{ ml: 1 }}>
|
|
27
|
+
{loadingText}
|
|
28
|
+
</Typography>
|
|
29
|
+
</Box>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
26
32
|
|
|
27
33
|
export const DefaultEndMessage: React.FC<{ endText: string }> = ({ endText }) => (
|
|
28
34
|
<Box sx={CENTERED}>
|
|
@@ -38,14 +44,25 @@ export const DefaultError: React.FC<{ error: Error }> = ({ error }) => (
|
|
|
38
44
|
</Alert>
|
|
39
45
|
);
|
|
40
46
|
|
|
47
|
+
/**
|
|
48
|
+
* The horizontal variant's `width` as CSS: a number of 1 or less stays the
|
|
49
|
+
* fraction `sx` reads it as, a larger one is design px, a string is as given;
|
|
50
|
+
* unset (or 0) fills the parent.
|
|
51
|
+
*/
|
|
52
|
+
const horizontalWidth = (theme: Theme, width: number | string | undefined): string => {
|
|
53
|
+
if (!width) return '100%';
|
|
54
|
+
if (typeof width !== 'number') return width;
|
|
55
|
+
return width <= 1 ? `${width * 100}%` : rem(theme, width);
|
|
56
|
+
};
|
|
57
|
+
|
|
41
58
|
/**
|
|
42
59
|
* `horizontal` scrolls along a row; `reverse` stacks bottom-up, for a chat log
|
|
43
60
|
* that loads older messages as you scroll away from the newest.
|
|
44
61
|
*/
|
|
45
|
-
export const containerStyles = (variant: Variant, width?: number | string) => {
|
|
62
|
+
export const containerStyles = (theme: Theme, variant: Variant, width?: number | string) => {
|
|
46
63
|
const horizontal = variant === 'horizontal';
|
|
47
64
|
const base = {
|
|
48
|
-
width: horizontal ? width
|
|
65
|
+
width: horizontal ? horizontalWidth(theme, width) : '100%',
|
|
49
66
|
height: horizontal ? '100%' : 'auto',
|
|
50
67
|
overflowX: horizontal ? 'auto' : 'hidden',
|
|
51
68
|
overflowY: horizontal ? 'hidden' : 'visible',
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import Box from '@mui/material/Box/index.js';
|
|
2
|
+
import { useTheme } from '@mui/material/styles/index.js';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
|
|
5
|
+
import { rem, remPx } from '../../../tokens/relative';
|
|
6
|
+
|
|
4
7
|
import { useLoadMore, useSentinel } from './InfiniteScroll.hooks';
|
|
5
8
|
import {
|
|
6
9
|
containerStyles,
|
|
@@ -15,7 +18,7 @@ export const InfiniteScroll: React.FC<InfiniteScrollProps> = ({
|
|
|
15
18
|
variant = 'default',
|
|
16
19
|
hasMore,
|
|
17
20
|
loading,
|
|
18
|
-
threshold
|
|
21
|
+
threshold,
|
|
19
22
|
loadMore,
|
|
20
23
|
loader,
|
|
21
24
|
loadingText,
|
|
@@ -31,7 +34,10 @@ export const InfiniteScroll: React.FC<InfiniteScrollProps> = ({
|
|
|
31
34
|
testMode = false,
|
|
32
35
|
testTriggerRef,
|
|
33
36
|
}) => {
|
|
34
|
-
const
|
|
37
|
+
const theme = useTheme();
|
|
38
|
+
// 150 design px unless the caller says; `rootMargin` only takes px.
|
|
39
|
+
const rootMargin = `${remPx(theme, threshold ?? 150)}px`;
|
|
40
|
+
const { sentinelRef, isIntersecting } = useSentinel({ testMode, rootMargin, scrollableTarget });
|
|
35
41
|
|
|
36
42
|
useLoadMore({
|
|
37
43
|
hasMore,
|
|
@@ -56,8 +62,8 @@ export const InfiniteScroll: React.FC<InfiniteScrollProps> = ({
|
|
|
56
62
|
ref={sentinelRef}
|
|
57
63
|
data-testid="infinite-scroll-sentinel"
|
|
58
64
|
style={{
|
|
59
|
-
height: variant === 'horizontal' ? '100%' :
|
|
60
|
-
width: variant === 'horizontal' ?
|
|
65
|
+
height: variant === 'horizontal' ? '100%' : rem(theme, 1),
|
|
66
|
+
width: variant === 'horizontal' ? rem(theme, 1) : '100%',
|
|
61
67
|
}}
|
|
62
68
|
/>
|
|
63
69
|
);
|
|
@@ -67,7 +73,7 @@ export const InfiniteScroll: React.FC<InfiniteScrollProps> = ({
|
|
|
67
73
|
<Box
|
|
68
74
|
className={className}
|
|
69
75
|
sx={{
|
|
70
|
-
...containerStyles(variant, width),
|
|
76
|
+
...containerStyles(theme, variant, width),
|
|
71
77
|
...style,
|
|
72
78
|
}}
|
|
73
79
|
>
|
|
@@ -13,7 +13,11 @@ export interface InfiniteScrollProps {
|
|
|
13
13
|
variant?: InfiniteScrollVariant;
|
|
14
14
|
hasMore: boolean;
|
|
15
15
|
loading: boolean;
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* How far before the end the next page is requested (default 150) — design
|
|
18
|
+
* px, scaled with the theme's type scale.
|
|
19
|
+
*/
|
|
20
|
+
threshold?: number;
|
|
17
21
|
loadMore: () => void | Promise<void>;
|
|
18
22
|
loader?: ReactNode;
|
|
19
23
|
endMessage?: ReactNode;
|
|
@@ -22,7 +26,11 @@ export interface InfiniteScrollProps {
|
|
|
22
26
|
onError?: (error: Error) => void;
|
|
23
27
|
className?: string;
|
|
24
28
|
style?: React.CSSProperties;
|
|
25
|
-
|
|
29
|
+
/**
|
|
30
|
+
* The `horizontal` variant's width. A number of 1 or less is a fraction of
|
|
31
|
+
* the parent (as in `sx`); a larger number is design px, scaled with the
|
|
32
|
+
* theme's type scale; a string is used as given.
|
|
33
|
+
*/
|
|
26
34
|
width?: number | string;
|
|
27
35
|
scrollableTarget?: string | HTMLElement; // For custom scroll containers
|
|
28
36
|
/**
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useTheme, type Theme } from '@mui/material/styles/index.js';
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
import { rem, remPx } from '../../../tokens/relative';
|
|
2
5
|
|
|
3
6
|
import type { VirtualGridProps, VirtualListProps } from './VirtualList.types';
|
|
4
7
|
|
|
5
8
|
type ScrollEvent = React.UIEvent<HTMLDivElement> | Event;
|
|
6
9
|
type ListItems = VirtualListProps['items'];
|
|
7
10
|
type ListVariant = NonNullable<VirtualListProps['variant']>;
|
|
8
|
-
type
|
|
11
|
+
type ItemSize = (index: number) => number;
|
|
9
12
|
|
|
10
13
|
// Handles both React synthetic events and native DOM events, since the same
|
|
11
14
|
// handler serves an internal onScroll and an external container's listener.
|
|
12
15
|
const scrollOffsets = (event: ScrollEvent) => {
|
|
13
16
|
const target = (event as React.UIEvent<HTMLDivElement>).currentTarget || (event as Event).target;
|
|
14
17
|
const element = target as HTMLElement;
|
|
15
|
-
return {
|
|
18
|
+
return { scrollTop: element.scrollTop, scrollLeft: element.scrollLeft };
|
|
16
19
|
};
|
|
17
20
|
|
|
18
21
|
/**
|
|
@@ -47,7 +50,7 @@ const useScrollTop = (
|
|
|
47
50
|
|
|
48
51
|
const handleScroll = useCallback(
|
|
49
52
|
(event: ScrollEvent) => {
|
|
50
|
-
const { top, left } = scrollOffsets(event);
|
|
53
|
+
const { scrollTop: top, scrollLeft: left } = scrollOffsets(event);
|
|
51
54
|
setScrollTop(top);
|
|
52
55
|
report(top, left);
|
|
53
56
|
},
|
|
@@ -59,63 +62,60 @@ const useScrollTop = (
|
|
|
59
62
|
return { scrollTop, handleScroll };
|
|
60
63
|
};
|
|
61
64
|
|
|
62
|
-
interface HeightArgs {
|
|
63
|
-
items: ListItems;
|
|
64
|
-
variant: ListVariant;
|
|
65
|
-
itemHeight: number;
|
|
66
|
-
estimatedItemHeight: number;
|
|
67
|
-
}
|
|
68
65
|
|
|
69
66
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
67
|
+
* A `width` prop as CSS. `sx` reads a number of 1 or less as a fraction of the
|
|
68
|
+
* parent, and that stays so; a larger number is design px, through the type
|
|
69
|
+
* scale; a string is as given.
|
|
73
70
|
*/
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
itemHeight,
|
|
78
|
-
estimatedItemHeight,
|
|
79
|
-
}: HeightArgs): ItemHeight => {
|
|
80
|
-
const measured = useRef<Map<number, number>>(new Map());
|
|
81
|
-
|
|
82
|
-
return useCallback(
|
|
83
|
-
(index: number): number => {
|
|
84
|
-
if (variant !== 'variable') {
|
|
85
|
-
return itemHeight;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return items[index]?.height || measured.current.get(index) || estimatedItemHeight;
|
|
89
|
-
},
|
|
90
|
-
[variant, itemHeight, estimatedItemHeight, items],
|
|
91
|
-
);
|
|
71
|
+
export const widthCss = (theme: Theme, width: number | string): string => {
|
|
72
|
+
if (typeof width !== 'number') return width;
|
|
73
|
+
return width <= 1 && width !== 0 ? `${width * 100}%` : rem(theme, width);
|
|
92
74
|
};
|
|
93
75
|
|
|
94
|
-
|
|
76
|
+
/** Every item's height, its offset from the top, and their sum — all in DESIGN px. */
|
|
77
|
+
interface DesignHeights {
|
|
78
|
+
size: ItemSize;
|
|
79
|
+
offset: ItemSize;
|
|
80
|
+
total: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Fixed lists know every height up front; variable ones take the item's own
|
|
85
|
+
* declared height and otherwise the estimate.
|
|
86
|
+
*
|
|
87
|
+
* Kept in the caller's DESIGN px on purpose: the CSS draws a height with `rem`
|
|
88
|
+
* and the range maths reads it through `remPx`, so the two are one number at
|
|
89
|
+
* any type scale — never a row drawn at one pitch and positioned at another.
|
|
90
|
+
*/
|
|
91
|
+
const useDesignHeights = (
|
|
95
92
|
items: ListItems,
|
|
96
93
|
variant: ListVariant,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
) =>
|
|
94
|
+
fixed: number,
|
|
95
|
+
estimated: number,
|
|
96
|
+
): DesignHeights =>
|
|
100
97
|
useMemo(() => {
|
|
101
|
-
if (variant
|
|
102
|
-
return items.length *
|
|
98
|
+
if (variant !== 'variable') {
|
|
99
|
+
return { size: () => fixed, offset: (index) => index * fixed, total: items.length * fixed };
|
|
103
100
|
}
|
|
104
101
|
|
|
105
|
-
|
|
102
|
+
const size = (index: number): number => items[index]?.height || estimated;
|
|
103
|
+
// Running sums, so an offset is a lookup rather than a walk from the top.
|
|
104
|
+
const starts = [0];
|
|
106
105
|
for (let i = 0; i < items.length; i++) {
|
|
107
|
-
|
|
106
|
+
starts.push((starts[i] ?? 0) + size(i));
|
|
108
107
|
}
|
|
109
|
-
return
|
|
110
|
-
}, [items
|
|
108
|
+
return { size, offset: (index) => starts[index] ?? 0, total: starts[items.length] ?? 0 };
|
|
109
|
+
}, [items, variant, fixed, estimated]);
|
|
111
110
|
|
|
111
|
+
/** The range maths' inputs, in the px the scroll offset is measured in. */
|
|
112
112
|
interface RangeArgs {
|
|
113
113
|
count: number;
|
|
114
114
|
scrollTop: number;
|
|
115
115
|
height: number;
|
|
116
116
|
overscan: number;
|
|
117
117
|
itemHeight: number;
|
|
118
|
-
getItemHeight:
|
|
118
|
+
getItemHeight: ItemSize;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
// Walks forward accumulating heights until it passes the viewport's top edge, then
|
|
@@ -155,56 +155,38 @@ const fixedRange = ({ count, scrollTop, height, overscan, itemHeight }: RangeArg
|
|
|
155
155
|
endIndex: Math.min(count - 1, Math.ceil((scrollTop + height) / itemHeight) + overscan),
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
(index: number): number => {
|
|
165
|
-
if (variant === 'fixed') {
|
|
166
|
-
return index * itemHeight;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
let offset = 0;
|
|
170
|
-
for (let i = 0; i < index; i++) {
|
|
171
|
-
offset += getItemHeight(i);
|
|
172
|
-
}
|
|
173
|
-
return offset;
|
|
174
|
-
},
|
|
175
|
-
[variant, itemHeight, getItemHeight],
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
interface ListArgs {
|
|
179
|
-
items: ListItems;
|
|
180
|
-
variant: ListVariant;
|
|
181
|
-
height: number;
|
|
182
|
-
itemHeight: number;
|
|
183
|
-
estimatedItemHeight: number;
|
|
184
|
-
overscan: number;
|
|
185
|
-
onScroll: VirtualListProps['onScroll'];
|
|
186
|
-
scrollContainerRef: VirtualListProps['scrollContainerRef'];
|
|
187
|
-
}
|
|
188
|
-
|
|
158
|
+
/**
|
|
159
|
+
* `height`, `itemHeight`, `estimatedItemHeight` and an item's own `height` are
|
|
160
|
+
* design px. The range is computed in the px `scrollTop` is measured in
|
|
161
|
+
* (`remPx`), the viewport and the scroll content are drawn in `rem`, and each
|
|
162
|
+
* item's `top`/`height` is the `remPx` of its design offset and height.
|
|
163
|
+
*/
|
|
189
164
|
export const useVirtualList = ({
|
|
190
165
|
items,
|
|
191
|
-
variant,
|
|
166
|
+
variant = 'fixed',
|
|
192
167
|
height,
|
|
193
168
|
itemHeight,
|
|
194
169
|
estimatedItemHeight,
|
|
195
|
-
overscan,
|
|
170
|
+
overscan = 5,
|
|
196
171
|
onScroll,
|
|
197
172
|
scrollContainerRef,
|
|
198
|
-
}:
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
const
|
|
173
|
+
}: VirtualListProps) => {
|
|
174
|
+
const theme = useTheme();
|
|
175
|
+
// 40 design px when the caller does not size a row.
|
|
176
|
+
const design = useDesignHeights(items, variant, itemHeight ?? 40, estimatedItemHeight ?? 40);
|
|
202
177
|
|
|
203
178
|
const report = useCallback((top: number) => onScroll?.(top), [onScroll]);
|
|
204
179
|
const { scrollTop, handleScroll } = useScrollTop(scrollContainerRef, report);
|
|
205
180
|
|
|
206
181
|
const visibleItems = useMemo(() => {
|
|
207
|
-
const args = {
|
|
182
|
+
const args = {
|
|
183
|
+
count: items.length,
|
|
184
|
+
scrollTop,
|
|
185
|
+
height: remPx(theme, height),
|
|
186
|
+
overscan,
|
|
187
|
+
itemHeight: remPx(theme, design.size(0)),
|
|
188
|
+
getItemHeight: (index: number) => remPx(theme, design.size(index)),
|
|
189
|
+
};
|
|
208
190
|
const { startIndex, endIndex } = variant === 'fixed' ? fixedRange(args) : variableRange(args);
|
|
209
191
|
const result = [];
|
|
210
192
|
|
|
@@ -217,33 +199,26 @@ export const useVirtualList = ({
|
|
|
217
199
|
index: i,
|
|
218
200
|
style: {
|
|
219
201
|
position: 'absolute' as const,
|
|
220
|
-
top:
|
|
202
|
+
top: remPx(theme, design.offset(i)),
|
|
221
203
|
left: 0,
|
|
222
204
|
width: '100%',
|
|
223
|
-
height:
|
|
205
|
+
height: remPx(theme, design.size(i)),
|
|
224
206
|
},
|
|
225
207
|
});
|
|
226
208
|
}
|
|
227
209
|
|
|
228
210
|
return result;
|
|
229
|
-
}, [items, scrollTop, height, overscan, variant,
|
|
230
|
-
|
|
231
|
-
return {
|
|
211
|
+
}, [items, scrollTop, height, overscan, variant, design, theme]);
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
totalHeight: rem(theme, design.total),
|
|
215
|
+
viewportHeight: rem(theme, height),
|
|
216
|
+
visibleItems,
|
|
217
|
+
handleScroll,
|
|
218
|
+
};
|
|
232
219
|
};
|
|
233
220
|
|
|
234
|
-
|
|
235
|
-
items: VirtualGridProps['items'];
|
|
236
|
-
height: number;
|
|
237
|
-
width: number | string;
|
|
238
|
-
columnCount: number;
|
|
239
|
-
rowHeight: number;
|
|
240
|
-
columnWidth?: number;
|
|
241
|
-
gap: number;
|
|
242
|
-
overscan: number;
|
|
243
|
-
onScroll: VirtualGridProps['onScroll'];
|
|
244
|
-
scrollContainerRef: VirtualGridProps['scrollContainerRef'];
|
|
245
|
-
}
|
|
246
|
-
|
|
221
|
+
/** The column width in DESIGN px: the caller's, or an even share of a numeric width. */
|
|
247
222
|
const useColumnWidth = (
|
|
248
223
|
columnWidth: number | undefined,
|
|
249
224
|
width: number | string,
|
|
@@ -257,21 +232,26 @@ const useColumnWidth = (
|
|
|
257
232
|
return (containerWidth - (columnCount - 1) * gap) / columnCount;
|
|
258
233
|
}, [columnWidth, width, columnCount, gap]);
|
|
259
234
|
|
|
235
|
+
/**
|
|
236
|
+
* `height`, `rowHeight`, `columnWidth` and `gap` are design px: the range and
|
|
237
|
+
* every cell's box are computed through `remPx`, the viewport and the content
|
|
238
|
+
* are drawn through `rem`.
|
|
239
|
+
*/
|
|
260
240
|
export const useVirtualGrid = ({
|
|
261
241
|
items,
|
|
262
242
|
height,
|
|
263
|
-
width,
|
|
243
|
+
width = '100%',
|
|
264
244
|
columnCount,
|
|
265
245
|
rowHeight,
|
|
266
246
|
columnWidth,
|
|
267
|
-
gap,
|
|
268
|
-
overscan,
|
|
247
|
+
gap = 0,
|
|
248
|
+
overscan = 5,
|
|
269
249
|
onScroll,
|
|
270
250
|
scrollContainerRef,
|
|
271
|
-
}:
|
|
251
|
+
}: VirtualGridProps) => {
|
|
252
|
+
const theme = useTheme();
|
|
272
253
|
const rowCount = Math.ceil(items.length / columnCount);
|
|
273
|
-
const
|
|
274
|
-
const computedColumnWidth = useColumnWidth(columnWidth, width, columnCount, gap);
|
|
254
|
+
const designColumn = useColumnWidth(columnWidth, width, columnCount, gap);
|
|
275
255
|
|
|
276
256
|
const report = useCallback(
|
|
277
257
|
(top: number, left: number) => onScroll?.(top, left),
|
|
@@ -280,9 +260,13 @@ export const useVirtualGrid = ({
|
|
|
280
260
|
const { scrollTop, handleScroll } = useScrollTop(scrollContainerRef, report);
|
|
281
261
|
|
|
282
262
|
const visibleItems = useMemo(() => {
|
|
283
|
-
const pitch = rowHeight + gap;
|
|
263
|
+
const pitch = remPx(theme, rowHeight + gap);
|
|
264
|
+
const stride = remPx(theme, designColumn + gap);
|
|
284
265
|
const startRow = Math.max(0, Math.floor(scrollTop / pitch) - overscan);
|
|
285
|
-
const endRow = Math.min(
|
|
266
|
+
const endRow = Math.min(
|
|
267
|
+
rowCount - 1,
|
|
268
|
+
Math.ceil((scrollTop + remPx(theme, height)) / pitch) + overscan,
|
|
269
|
+
);
|
|
286
270
|
|
|
287
271
|
// Rows are contiguous in `items`, so the visible block is one index range
|
|
288
272
|
// rather than a row loop wrapping a column loop.
|
|
@@ -305,15 +289,20 @@ export const useVirtualGrid = ({
|
|
|
305
289
|
style: {
|
|
306
290
|
position: 'absolute' as const,
|
|
307
291
|
top: rowIndex * pitch,
|
|
308
|
-
left: columnIndex *
|
|
309
|
-
width:
|
|
310
|
-
height: rowHeight,
|
|
292
|
+
left: columnIndex * stride,
|
|
293
|
+
width: remPx(theme, designColumn),
|
|
294
|
+
height: remPx(theme, rowHeight),
|
|
311
295
|
},
|
|
312
296
|
});
|
|
313
297
|
}
|
|
314
298
|
|
|
315
299
|
return result;
|
|
316
|
-
}, [items, scrollTop, height, overscan, rowCount, columnCount, rowHeight, gap,
|
|
317
|
-
|
|
318
|
-
return {
|
|
300
|
+
}, [items, scrollTop, height, overscan, rowCount, columnCount, rowHeight, gap, designColumn, theme]);
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
totalHeight: rem(theme, rowCount * (rowHeight + gap) - gap),
|
|
304
|
+
viewportHeight: rem(theme, height),
|
|
305
|
+
visibleItems,
|
|
306
|
+
handleScroll,
|
|
307
|
+
};
|
|
319
308
|
};
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import Box from '@mui/material/Box/index.js';
|
|
2
|
+
import { useTheme } from '@mui/material/styles/index.js';
|
|
2
3
|
import React, { useRef } from 'react';
|
|
3
4
|
|
|
4
|
-
import { useVirtualGrid, useVirtualList } from './VirtualList.hooks';
|
|
5
|
+
import { useVirtualGrid, useVirtualList, widthCss } from './VirtualList.hooks';
|
|
5
6
|
import type { VirtualGridProps, VirtualListProps } from './VirtualList.types';
|
|
6
7
|
|
|
7
8
|
interface ContainerProps {
|
|
8
9
|
children: React.ReactNode;
|
|
9
10
|
role: 'list' | 'grid';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/** The scroll content's height, as CSS. */
|
|
12
|
+
totalHeight: string;
|
|
13
|
+
/** The viewport's height, as CSS. */
|
|
14
|
+
height: string;
|
|
15
|
+
/** The viewport's width, as CSS. */
|
|
16
|
+
width: string;
|
|
13
17
|
disableInternalScroll: boolean;
|
|
14
18
|
onScroll: (event: React.UIEvent<HTMLDivElement>) => void;
|
|
15
19
|
className?: string;
|
|
@@ -64,40 +68,25 @@ const VirtualContainer: React.FC<ContainerProps> = ({
|
|
|
64
68
|
);
|
|
65
69
|
};
|
|
66
70
|
|
|
67
|
-
export const VirtualList: React.FC<VirtualListProps> = ({
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
'data-testid': dataTestId,
|
|
80
|
-
'aria-label': ariaLabel,
|
|
81
|
-
scrollContainerRef,
|
|
82
|
-
disableInternalScroll = false,
|
|
83
|
-
}) => {
|
|
84
|
-
const { totalHeight, visibleItems, handleScroll } = useVirtualList({
|
|
85
|
-
items,
|
|
86
|
-
variant,
|
|
87
|
-
height,
|
|
88
|
-
itemHeight,
|
|
89
|
-
estimatedItemHeight,
|
|
90
|
-
overscan,
|
|
91
|
-
onScroll,
|
|
92
|
-
scrollContainerRef,
|
|
93
|
-
});
|
|
71
|
+
export const VirtualList: React.FC<VirtualListProps> = (props) => {
|
|
72
|
+
const {
|
|
73
|
+
width = '100%',
|
|
74
|
+
renderItem,
|
|
75
|
+
className,
|
|
76
|
+
style,
|
|
77
|
+
'data-testid': dataTestId,
|
|
78
|
+
'aria-label': ariaLabel,
|
|
79
|
+
disableInternalScroll = false,
|
|
80
|
+
} = props;
|
|
81
|
+
const theme = useTheme();
|
|
82
|
+
const { totalHeight, viewportHeight, visibleItems, handleScroll } = useVirtualList(props);
|
|
94
83
|
|
|
95
84
|
return (
|
|
96
85
|
<VirtualContainer
|
|
97
86
|
role="list"
|
|
98
87
|
totalHeight={totalHeight}
|
|
99
|
-
height={
|
|
100
|
-
width={width}
|
|
88
|
+
height={viewportHeight}
|
|
89
|
+
width={widthCss(theme, width)}
|
|
101
90
|
disableInternalScroll={disableInternalScroll}
|
|
102
91
|
onScroll={handleScroll}
|
|
103
92
|
className={className}
|
|
@@ -112,43 +101,25 @@ export const VirtualList: React.FC<VirtualListProps> = ({
|
|
|
112
101
|
);
|
|
113
102
|
};
|
|
114
103
|
|
|
115
|
-
export const VirtualGrid: React.FC<VirtualGridProps> = ({
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
style,
|
|
128
|
-
'data-testid': dataTestId,
|
|
129
|
-
'aria-label': ariaLabel,
|
|
130
|
-
scrollContainerRef,
|
|
131
|
-
disableInternalScroll = false,
|
|
132
|
-
}) => {
|
|
133
|
-
const { totalHeight, visibleItems, handleScroll } = useVirtualGrid({
|
|
134
|
-
items,
|
|
135
|
-
height,
|
|
136
|
-
width,
|
|
137
|
-
columnCount,
|
|
138
|
-
rowHeight,
|
|
139
|
-
columnWidth,
|
|
140
|
-
gap,
|
|
141
|
-
overscan,
|
|
142
|
-
onScroll,
|
|
143
|
-
scrollContainerRef,
|
|
144
|
-
});
|
|
104
|
+
export const VirtualGrid: React.FC<VirtualGridProps> = (props) => {
|
|
105
|
+
const {
|
|
106
|
+
width = '100%',
|
|
107
|
+
renderItem,
|
|
108
|
+
className,
|
|
109
|
+
style,
|
|
110
|
+
'data-testid': dataTestId,
|
|
111
|
+
'aria-label': ariaLabel,
|
|
112
|
+
disableInternalScroll = false,
|
|
113
|
+
} = props;
|
|
114
|
+
const theme = useTheme();
|
|
115
|
+
const { totalHeight, viewportHeight, visibleItems, handleScroll } = useVirtualGrid(props);
|
|
145
116
|
|
|
146
117
|
return (
|
|
147
118
|
<VirtualContainer
|
|
148
119
|
role="grid"
|
|
149
120
|
totalHeight={totalHeight}
|
|
150
|
-
height={
|
|
151
|
-
width={width}
|
|
121
|
+
height={viewportHeight}
|
|
122
|
+
width={widthCss(theme, width)}
|
|
152
123
|
disableInternalScroll={disableInternalScroll}
|
|
153
124
|
onScroll={handleScroll}
|
|
154
125
|
className={className}
|
|
@@ -4,17 +4,25 @@ export type VirtualListVariant = 'fixed' | 'variable' | 'grid';
|
|
|
4
4
|
|
|
5
5
|
export interface VirtualListItem {
|
|
6
6
|
id: string | number;
|
|
7
|
-
height
|
|
7
|
+
/** This item's own height, for a `variable` list — design px, scaled with the theme's type scale. */
|
|
8
|
+
height?: number;
|
|
8
9
|
data?: unknown;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export interface VirtualListProps {
|
|
12
13
|
items: VirtualListItem[];
|
|
13
14
|
variant?: VirtualListVariant;
|
|
15
|
+
/** The viewport's height — design px, scaled with the theme's type scale. */
|
|
14
16
|
height: number;
|
|
17
|
+
/**
|
|
18
|
+
* The viewport's width. A number of 1 or less is a fraction of the parent (as
|
|
19
|
+
* in `sx`); a larger number is design px, scaled with the theme's type scale; a string is used as given.
|
|
20
|
+
*/
|
|
15
21
|
width?: number | string;
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
/** Every row's height in a `fixed` list (default 40) — design px, scaled with the theme's type scale. */
|
|
23
|
+
itemHeight?: number;
|
|
24
|
+
/** The height assumed for a `variable` item that declares none (default 40) — design px, scaled with the theme's type scale. */
|
|
25
|
+
estimatedItemHeight?: number;
|
|
18
26
|
overscan?: number; // Number of items to render outside visible area
|
|
19
27
|
renderItem: (params: { item: VirtualListItem; index: number; style: CSSProperties }) => ReactNode;
|
|
20
28
|
onScroll?: (scrollTop: number) => void;
|
|
@@ -30,11 +38,20 @@ export interface VirtualListProps {
|
|
|
30
38
|
|
|
31
39
|
export interface VirtualGridProps {
|
|
32
40
|
items: VirtualListItem[];
|
|
41
|
+
/** The viewport's height — design px, scaled with the theme's type scale. */
|
|
33
42
|
height: number;
|
|
43
|
+
/**
|
|
44
|
+
* The viewport's width. A number of 1 or less is a fraction of the parent (as
|
|
45
|
+
* in `sx`); a larger number is design px, scaled with the theme's type scale, and also what an unset
|
|
46
|
+
* `columnWidth` is shared out of; a string is used as given.
|
|
47
|
+
*/
|
|
34
48
|
width?: number | string;
|
|
35
49
|
columnCount: number;
|
|
50
|
+
/** Every row's height — design px, scaled with the theme's type scale. */
|
|
36
51
|
rowHeight: number;
|
|
52
|
+
/** Every column's width — design px, scaled with the theme's type scale. */
|
|
37
53
|
columnWidth?: number;
|
|
54
|
+
/** The space between two rows and between two columns — design px, scaled with the theme's type scale. */
|
|
38
55
|
gap?: number;
|
|
39
56
|
overscan?: number;
|
|
40
57
|
renderItem: (params: {
|