@12-apps/ui 6.39.8 → 6.39.10
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/Alert/Alert.js +2 -2
- package/dist/_internal/components/data-display/Alert/Alert.metrics.js +2 -2
- package/dist/_internal/components/data-display/Alert/Alert.styles.js +2 -2
- package/dist/_internal/components/data-display/Badge/Badge.js +4 -4
- package/dist/_internal/components/data-display/Badge/Badge.styles.js +2 -2
- package/dist/_internal/components/data-display/Badge/BadgeContent.js +2 -2
- package/dist/_internal/components/data-display/Banner/Banner.js +2 -2
- package/dist/_internal/components/data-display/Banner/Banner.styles.js +2 -2
- package/dist/_internal/components/data-display/CardKit/CardKebab.js +5 -5
- package/dist/_internal/components/data-display/CardKit/card-actions-context.js +2 -2
- package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +6 -6
- package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +6 -6
- package/dist/_internal/components/data-display/Carousel/Carousel.chrome.js +2 -2
- package/dist/_internal/components/data-display/Carousel/Carousel.js +2 -2
- package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +2 -2
- package/dist/_internal/components/data-display/Carousel/Carousel.styles.js +2 -2
- package/dist/_internal/components/data-display/Chart/Chart.js +6 -6
- package/dist/_internal/components/data-display/Chart/SpecChart.js +7 -7
- package/dist/_internal/components/data-display/Chart/chart-context.js +4 -4
- package/dist/_internal/components/data-display/Chart/chart-internals.js +2 -2
- package/dist/_internal/components/data-display/Chart/chart-renderers.js +5 -5
- package/dist/_internal/components/data-display/DataViews/DataViewsBoard.js +5 -5
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +38 -38
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +47 -47
- package/dist/_internal/components/data-display/DataViews/DeleteViewDialog.js +7 -7
- package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +9 -9
- package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +8 -8
- package/dist/_internal/components/data-display/DataViews/base-card.js +5 -5
- package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +7 -7
- package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +6 -6
- package/dist/_internal/components/data-display/DataViews/base-list-card.js +9 -9
- package/dist/_internal/components/data-display/DataViews/data-views-bar-controls.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-columns-tab.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-columns.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-day-input.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +10 -10
- package/dist/_internal/components/data-display/DataViews/data-views-display-tabs.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-empty.js +7 -7
- package/dist/_internal/components/data-display/DataViews/data-views-export.js +7 -7
- package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +10 -10
- package/dist/_internal/components/data-display/DataViews/data-views-grid-helpers.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +34 -34
- package/dist/_internal/components/data-display/DataViews/data-views-header-row.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +13 -13
- package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +9 -9
- package/dist/_internal/components/data-display/DataViews/data-views-number-input.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-pagination.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-scope-tabs.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-search.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-select-all-strip.js +7 -7
- package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +15 -15
- package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +13 -13
- package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +14 -14
- package/dist/_internal/components/data-display/DataViews/data-views-view-nav.js +7 -7
- package/dist/_internal/components/data-display/DataViews/save-view-preview.js +5 -5
- package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +7 -7
- package/dist/_internal/components/data-display/DescriptionItem/DescriptionItem.js +5 -5
- package/dist/_internal/components/data-display/FleetMap/FleetBody.js +11 -11
- package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +8 -8
- package/dist/_internal/components/data-display/FleetMap/FleetMap.js +13 -13
- package/dist/_internal/components/data-display/FleetMap/FleetRoster.js +2 -2
- package/dist/_internal/components/data-display/HoverCard/HoverCard.js +2 -2
- package/dist/_internal/components/data-display/Lightbox/Lightbox.js +2 -2
- package/dist/_internal/components/data-display/MapPreview/MapLayers.js +3 -3
- package/dist/_internal/components/data-display/MapPreview/MapPreview.js +7 -7
- package/dist/_internal/components/data-display/MapPreview/MapSearchBar.js +1 -1
- package/dist/_internal/components/data-display/Progress/Progress.js +5 -5
- package/dist/_internal/components/data-display/Progress/Progress.metrics.js +3 -3
- package/dist/_internal/components/data-display/Progress/Progress.styles.js +4 -4
- package/dist/_internal/components/data-display/Sheet/Sheet.body.js +2 -2
- package/dist/_internal/components/data-display/Sheet/Sheet.hooks.js +2 -2
- package/dist/_internal/components/data-display/Sheet/Sheet.js +5 -5
- package/dist/_internal/components/data-display/Sheet/Sheet.styles.js +2 -2
- package/dist/_internal/components/data-display/Table/Table.hooks.js +1 -1
- package/dist/_internal/components/data-display/Table/Table.js +6 -5
- package/dist/_internal/components/data-display/Table/Table.styles.js +1 -1
- package/dist/_internal/components/data-display/Table/TableParts.hooks.js +2 -1
- package/dist/_internal/components/data-display/Table/TableParts.js +2 -1
- package/dist/_internal/components/data-display/index.js +38 -38
- package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +5 -5
- package/dist/_internal/components/feedback/Modal/Modal.js +2 -2
- package/dist/_internal/components/feedback/NotificationStatusNotice/NotificationStatusNotice.js +5 -5
- package/dist/_internal/components/feedback/index.js +11 -11
- package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.hooks.js +2 -2
- package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.js +7 -7
- package/dist/_internal/components/form/AddressAutocomplete/AddressAutocompleteField.js +4 -4
- package/dist/_internal/components/form/AddressAutocomplete/AddressFallbackField.js +1 -1
- package/dist/_internal/components/form/AddressAutocomplete/AddressInputField.js +1 -1
- package/dist/_internal/components/form/AddressAutocomplete/AddressTextField.js +1 -1
- package/dist/_internal/components/form/Autocomplete/Autocomplete.js +1 -1
- package/dist/_internal/components/form/Autocomplete/Autocomplete.parts.js +1 -1
- package/dist/_internal/components/form/Button/Button.js +4 -4
- package/dist/_internal/components/form/Button/Button.styles.js +2 -2
- package/dist/_internal/components/form/Calendar/Calendar.hooks.js +2 -2
- package/dist/_internal/components/form/Calendar/Calendar.js +3 -3
- package/dist/_internal/components/form/CategorySelect/CategoryPanel.js +1 -1
- package/dist/_internal/components/form/CategorySelect/CategoryPanelFoot.js +1 -1
- package/dist/_internal/components/form/CategorySelect/CategoryPanelHead.js +1 -1
- package/dist/_internal/components/form/CategorySelect/CategoryPanelList.js +1 -1
- package/dist/_internal/components/form/CategorySelect/CategoryRows.js +1 -1
- package/dist/_internal/components/form/CategorySelect/CategorySelect.js +3 -3
- package/dist/_internal/components/form/CategorySelect/CategorySelect.styles.js +1 -1
- package/dist/_internal/components/form/CategorySelect/CategoryTrigger.js +1 -1
- package/dist/_internal/components/form/CepField/CepField.js +1 -1
- package/dist/_internal/components/form/CodeEditor/CodeEditor.js +2 -2
- package/dist/_internal/components/form/Command/Command.js +2 -2
- package/dist/_internal/components/form/Command/Command.styles.js +2 -2
- package/dist/_internal/components/form/CreatableSelect/CreatableSelect.js +1 -1
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.hooks.js +1 -1
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +5 -5
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.range.js +1 -1
- package/dist/_internal/components/form/DateRangePicker/DateRangePickerFields.js +1 -1
- package/dist/_internal/components/form/Input/Input.js +1 -1
- package/dist/_internal/components/form/Input/Input.styles.js +1 -1
- package/dist/_internal/components/form/InputOTP/InputOTP.js +3 -3
- package/dist/_internal/components/form/InputOTP/InputOTP.styles.js +1 -1
- package/dist/_internal/components/form/Label/Label.js +2 -2
- package/dist/_internal/components/form/Label/Label.styles.js +2 -2
- package/dist/_internal/components/form/Menubar/Menubar.item.js +2 -2
- package/dist/_internal/components/form/Menubar/Menubar.js +4 -4
- package/dist/_internal/components/form/Menubar/Menubar.styles.js +2 -2
- package/dist/_internal/components/form/Menubar/Menubar.toolbar.js +2 -2
- package/dist/_internal/components/form/PhoneInput/PhoneInput.js +1 -1
- package/dist/_internal/components/form/RadioGroup/RadioGroup.js +1 -1
- package/dist/_internal/components/form/RadioGroup/RadioGroup.styles.js +1 -1
- package/dist/_internal/components/form/RadioGroup/RadioGroup.variants.js +1 -1
- package/dist/_internal/components/form/Select/Select.js +1 -1
- package/dist/_internal/components/form/Switch/Switch.js +2 -2
- package/dist/_internal/components/form/Switch/Switch.parts.js +2 -2
- package/dist/_internal/components/form/Switch/Switch.styles.js +2 -2
- package/dist/_internal/components/form/Textarea/Textarea.js +2 -2
- package/dist/_internal/components/form/Textarea/TextareaRichEditor.js +1 -1
- package/dist/_internal/components/form/Toggle/Toggle.js +1 -1
- package/dist/_internal/components/form/Toggle/Toggle.styles.js +1 -1
- package/dist/_internal/components/form/ToggleGroup/ToggleGroup.js +1 -1
- package/dist/_internal/components/form/UploadButton/UploadButton.js +2 -2
- package/dist/_internal/components/form/index.js +23 -23
- package/dist/_internal/components/form/total-form/Fields/CategoryField.js +4 -4
- package/dist/_internal/components/form/total-form/Fields/CepField.js +1 -1
- package/dist/_internal/components/form/total-form/Fields/SelectField.js +1 -1
- package/dist/_internal/components/form/total-form/Fields/TextField.js +1 -1
- package/dist/_internal/components/form/total-form/Fields/ToggleField.js +1 -1
- package/dist/_internal/components/form/total-form/Fields/index.js +8 -8
- package/dist/_internal/components/form/total-form/SubmitButton.js +5 -5
- package/dist/_internal/components/index.js +75 -75
- package/dist/_internal/components/layout/Box/Box.js +5 -5
- package/dist/_internal/components/layout/ContentToolbar/ColumnsMenu.js +1 -1
- package/dist/_internal/components/layout/ContentToolbar/FilterTrigger.js +1 -1
- package/dist/_internal/components/layout/ContentToolbar/MultiSelectDropdown.js +1 -1
- package/dist/_internal/components/layout/ContentToolbar/MultiSelectTriggers.js +1 -1
- package/dist/_internal/components/layout/ContentToolbar/SavedViewsMenu.js +1 -1
- package/dist/_internal/components/layout/ContentToolbar/SortByDropdown.js +1 -1
- package/dist/_internal/components/layout/ContentToolbar/ViewSelector.js +1 -1
- package/dist/_internal/components/layout/ScrollArea/ScrollArea.js +2 -2
- package/dist/_internal/components/layout/SettingsLayout/SettingsLayout.js +5 -4
- package/dist/_internal/components/layout/SettingsLayout/SettingsPanel.js +3 -2
- package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.js +2 -1
- package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.scroll.js +8 -0
- package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.scroll.js.map +1 -0
- package/dist/_internal/components/layout/Stack/Stack.js +6 -6
- package/dist/_internal/components/layout/TableFilter/TableFilter.js +1 -1
- package/dist/_internal/components/layout/index.js +6 -6
- package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +8 -8
- package/dist/_internal/components/navigation/AppHeader/AppHeader.identity.js +2 -2
- package/dist/_internal/components/navigation/Pagination/Pagination.js +1 -1
- package/dist/_internal/components/navigation/Pagination/PaginationParts.js +1 -1
- package/dist/_internal/components/navigation/Tabs/Tabs.js +1 -1
- package/dist/_internal/components/navigation/Tabs/Tabs.styles.js +1 -1
- package/dist/_internal/components/navigation/index.js +8 -8
- package/dist/_internal/components/typography/Heading/Heading.js +5 -5
- package/dist/_internal/components/typography/Heading/Heading.metrics.js +3 -3
- package/dist/_internal/components/typography/Heading/Heading.styles.js +4 -4
- package/dist/_internal/components/typography/Text/Text.js +4 -4
- package/dist/_internal/components/typography/Text/Text.metrics.js +3 -3
- package/dist/_internal/components/typography/index.js +7 -7
- package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.helpers.js +2 -2
- package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.js +2 -2
- package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.parts.js +2 -2
- package/dist/_internal/components/utility/WorkflowStep/WorkflowStepRow.js +2 -2
- package/dist/_internal/components/utility/index.js +2 -2
- package/dist/_internal/icons/Icon.js +5 -5
- package/dist/_internal/provider/UiProvider.js +4 -4
- package/dist/_internal/provider/mui-bridge.js +3 -3
- package/dist/_internal/provider/use-ui-theme.js +4 -4
- package/dist/_internal/social-login-button/social-login-button.js +10 -10
- package/dist/_internal/tokens/field-height.js +1 -1
- package/dist/_internal/tokens/theme.js +2 -2
- package/dist/_internal/user-avatar/user-avatar.js +7 -7
- package/dist/charts.js +7 -7
- package/dist/{chunk-OAEYCKBN.js → chunk-2K7WPHI3.js} +2 -2
- package/dist/{chunk-GWEENWIS.js → chunk-3333KCAW.js} +3 -3
- package/dist/{chunk-L7NQCLFU.js → chunk-36JKV7CA.js} +3 -3
- package/dist/{chunk-JBI7ITL2.js → chunk-3BNQDOHC.js} +2 -2
- package/dist/{chunk-QGFBIUOK.js → chunk-3CTQZDSD.js} +2 -2
- package/dist/{chunk-YCCY77W5.js → chunk-3IF3I3FI.js} +2 -2
- package/dist/{chunk-A4OCNJWW.js → chunk-3UABIEP3.js} +2 -2
- package/dist/{chunk-R2WMSXQR.js → chunk-4BNV5AAI.js} +7 -7
- package/dist/{chunk-OHC3F7GJ.js → chunk-4NPPO63U.js} +6 -6
- package/dist/{chunk-WHQKH57H.js → chunk-4WF6ZLIW.js} +3 -3
- package/dist/{chunk-6WLHEZXI.js → chunk-4Y6W7BT4.js} +4 -4
- package/dist/{chunk-5KGABAQB.js → chunk-5752357K.js} +4 -4
- package/dist/{chunk-UITQ7KMK.js → chunk-5CQNBMLK.js} +4 -4
- package/dist/{chunk-3KREF4ZF.js → chunk-5FAI25JQ.js} +3 -3
- package/dist/{chunk-5CQ5HYJW.js → chunk-5KWHINO5.js} +4 -4
- package/dist/{chunk-BOGTTXPA.js → chunk-5QD6YGZ2.js} +16 -15
- package/dist/chunk-5QD6YGZ2.js.map +1 -0
- package/dist/{chunk-U4O47P6S.js → chunk-5WT4YWXC.js} +3 -3
- package/dist/{chunk-SZ3YFVO5.js → chunk-6MFMLQ72.js} +4 -4
- package/dist/{chunk-VIUDWOV6.js → chunk-7D2C4LK2.js} +5 -5
- package/dist/{chunk-6WBKOM5K.js → chunk-7DK6YVJU.js} +2 -2
- package/dist/{chunk-6QXFBZ7Q.js → chunk-7ICK5MXV.js} +4 -4
- package/dist/{chunk-QTNHAX2Z.js → chunk-A5B7B4HT.js} +3 -3
- package/dist/{chunk-KAIUDBHM.js → chunk-AXKLCWFR.js} +16 -16
- package/dist/{chunk-OB56SZGL.js → chunk-B7CNP5HW.js} +2 -2
- package/dist/{chunk-34BZXJGT.js → chunk-BKASAYQL.js} +4 -4
- package/dist/{chunk-PE4ZW3IA.js → chunk-BLW6KLDR.js} +4 -4
- package/dist/{chunk-UAVSBSV5.js → chunk-BUPDBEBA.js} +2 -2
- package/dist/{chunk-POV2KL2P.js → chunk-CCK7FB2V.js} +16 -2
- package/dist/chunk-CCK7FB2V.js.map +1 -0
- package/dist/{chunk-QKMJUOVH.js → chunk-CRG24BGI.js} +2 -2
- package/dist/{chunk-LKMMJKXU.js → chunk-CYZZHWNK.js} +2 -2
- package/dist/{chunk-DIM6SUGY.js → chunk-DAHYLPK7.js} +7 -7
- package/dist/{chunk-DUNG7D4B.js → chunk-DSF4VT7L.js} +1 -1
- package/dist/{chunk-KBZFBHLO.js → chunk-DXZOSP6P.js} +3 -3
- package/dist/{chunk-4GWHYLEB.js → chunk-DYGWKZ7T.js} +2 -2
- package/dist/{chunk-YOJASBHJ.js → chunk-DYNJQ3HJ.js} +3 -3
- package/dist/{chunk-CTKQCKRD.js → chunk-ECIHOZPK.js} +4 -4
- package/dist/{chunk-MYWROMGO.js → chunk-ENRBXB6L.js} +7 -7
- package/dist/{chunk-FWSMIUWA.js → chunk-ESCF5VMQ.js} +2 -2
- package/dist/{chunk-QI5CRSOW.js → chunk-F4KYBBTY.js} +4 -4
- package/dist/{chunk-NCEQWEXT.js → chunk-FNO5TWBJ.js} +4 -4
- package/dist/{chunk-S6IWKDWT.js → chunk-GC56IWIZ.js} +2 -2
- package/dist/{chunk-CXMVNYBY.js → chunk-GEB4WSZH.js} +3 -3
- package/dist/{chunk-RIF6L54B.js → chunk-H224XFFD.js} +2 -2
- package/dist/{chunk-2EAAWOZ2.js → chunk-HM2JJNUE.js} +4 -4
- package/dist/{chunk-JQWAANGN.js → chunk-HMAPQV4C.js} +3 -3
- package/dist/{chunk-7RRXLCOO.js → chunk-HUPR5JXY.js} +5 -5
- package/dist/{chunk-3RMDIO4G.js → chunk-I5T5PQQW.js} +2 -2
- package/dist/{chunk-F4WFUQYR.js → chunk-IFS3BRRL.js} +5 -5
- package/dist/{chunk-3GTMGPNQ.js → chunk-IQJCLFF4.js} +5 -5
- package/dist/{chunk-2ZRZTGWP.js → chunk-ISW5K72V.js} +5 -5
- package/dist/{chunk-IJFAF3A7.js → chunk-IWEUSZY3.js} +3 -3
- package/dist/{chunk-EDKLXA5W.js → chunk-J3XFUCCR.js} +3 -3
- package/dist/{chunk-TFMDZQK4.js → chunk-JGRBHNK6.js} +7 -7
- package/dist/{chunk-XEYLYUDM.js → chunk-JH5BKA3Y.js} +2 -2
- package/dist/{chunk-GS3RP2QE.js → chunk-KKN4LLVE.js} +2 -2
- package/dist/{chunk-3OBC6BOV.js → chunk-LH46NYGR.js} +2 -2
- package/dist/{chunk-5HQNHZ6Z.js → chunk-LH7KMYHC.js} +3 -4
- package/dist/chunk-LH7KMYHC.js.map +1 -0
- package/dist/{chunk-56JF5PZK.js → chunk-LYVTJLCF.js} +4 -4
- package/dist/{chunk-PZ7PU4AP.js → chunk-M2Q5CLPU.js} +4 -4
- package/dist/{chunk-XIG3DXXX.js → chunk-M4KVKQRN.js} +3 -3
- package/dist/{chunk-X4ZRPE37.js → chunk-MBHWVRV5.js} +2 -2
- package/dist/{chunk-ERY6D2OV.js → chunk-MWPXKZ7O.js} +4 -4
- package/dist/{chunk-XWZJLXJT.js → chunk-N7LPVR7P.js} +36 -10
- package/dist/chunk-N7LPVR7P.js.map +1 -0
- package/dist/{chunk-3AOQBR7N.js → chunk-OAW6GCS3.js} +2 -2
- package/dist/{chunk-6N2EDWMG.js → chunk-OGB25P3N.js} +4 -4
- package/dist/{chunk-R2XVTUVR.js → chunk-OQRG34VG.js} +2 -2
- package/dist/{chunk-RUEKY3VR.js → chunk-P52LYD6S.js} +2 -2
- package/dist/{chunk-R53ZOW4B.js → chunk-PARTZ7XI.js} +2 -2
- package/dist/{chunk-7GHYCQCJ.js → chunk-PCLKFR27.js} +4 -4
- package/dist/{chunk-K6VKL62Z.js → chunk-PG5C2AA4.js} +5 -5
- package/dist/{chunk-RGT6DM5W.js → chunk-PX6TWS5T.js} +68 -42
- package/dist/chunk-PX6TWS5T.js.map +1 -0
- package/dist/{chunk-R3JYC63P.js → chunk-QXSV7Z57.js} +2 -2
- package/dist/{chunk-5JSRM7WC.js → chunk-RB3X6CEE.js} +2 -2
- package/dist/{chunk-DW6F7354.js → chunk-S36NC22G.js} +2 -2
- package/dist/{chunk-6N4AA2Y7.js → chunk-S6JHTEV4.js} +3 -3
- package/dist/{chunk-5JCGBCFJ.js → chunk-SAOCDKNK.js} +4 -4
- package/dist/chunk-SLJAQA2X.js +82 -0
- package/dist/chunk-SLJAQA2X.js.map +1 -0
- package/dist/{chunk-ISFFETTG.js → chunk-T3DNYPEA.js} +6 -6
- package/dist/{chunk-JU4MSYYH.js → chunk-T6EKPFKZ.js} +2 -2
- package/dist/{chunk-Q2YNXJEL.js → chunk-TZBOWSAM.js} +5 -5
- package/dist/{chunk-D4FZ3ANG.js → chunk-UKX3MPB7.js} +2 -2
- package/dist/{chunk-YBH4SPMM.js → chunk-URHX4FAQ.js} +2 -2
- package/dist/{chunk-4CXCOR6F.js → chunk-V2UZQS2K.js} +2 -2
- package/dist/{chunk-TXGB2WSW.js → chunk-VJ2BNJ5M.js} +2 -2
- package/dist/{chunk-ASYR22BJ.js → chunk-VJG7NMGL.js} +4 -4
- package/dist/{chunk-BWHOCNGW.js → chunk-VPPIODKX.js} +2 -2
- package/dist/{chunk-4B5XUQQS.js → chunk-WB6ZU3B3.js} +3 -3
- package/dist/{chunk-W7F2QIAT.js → chunk-WCRGSMLV.js} +3 -3
- package/dist/{chunk-G62KCU3D.js → chunk-WL6N33AB.js} +2 -2
- package/dist/{chunk-VIRYHNEM.js → chunk-WY5PBZ7Q.js} +2 -2
- package/dist/{chunk-TKKQ7RGT.js → chunk-WZNTZX5N.js} +2 -2
- package/dist/{chunk-KE473LK6.js → chunk-YMTZN54Q.js} +2 -2
- package/dist/{chunk-JSD5TFDK.js → chunk-YS67XMOP.js} +5 -5
- package/dist/{chunk-UGGJ3KDT.js → chunk-YTINPQKU.js} +2 -2
- package/dist/{chunk-U3PPLAFB.js → chunk-ZN6YATOG.js} +2 -2
- package/dist/{chunk-WC3W36AM.js → chunk-ZOUWHGV3.js} +4 -4
- package/dist/data-display/Alert.js +2 -2
- package/dist/data-display/Badge.js +4 -4
- package/dist/data-display/Banner.js +2 -2
- package/dist/data-display/CardKit.js +10 -10
- package/dist/data-display/Carousel.js +2 -2
- package/dist/data-display/Chart.js +7 -7
- package/dist/data-display/DataViews.js +63 -63
- package/dist/data-display/DescriptionItem.js +5 -5
- package/dist/data-display/FleetMap.js +13 -13
- package/dist/data-display/HoverCard.js +2 -2
- package/dist/data-display/Lightbox.js +2 -2
- package/dist/data-display/MapPreview.js +7 -7
- package/dist/data-display/Progress.js +5 -5
- package/dist/data-display/Sheet.js +5 -5
- package/dist/data-display/Table.js +6 -5
- package/dist/feedback/ConfirmAction.js +8 -8
- package/dist/feedback/Modal.js +2 -2
- package/dist/feedback/NotificationStatusNotice.js +5 -5
- package/dist/form/AddressAutocomplete.js +7 -7
- package/dist/form/Autocomplete.js +1 -1
- package/dist/form/Button.js +4 -4
- package/dist/form/Calendar.js +3 -3
- package/dist/form/CategorySelect.js +3 -3
- package/dist/form/CepField.js +1 -1
- package/dist/form/CodeEditor.js +2 -2
- package/dist/form/Command.js +2 -2
- package/dist/form/CreatableSelect.js +1 -1
- package/dist/form/DateRangePicker.js +5 -5
- package/dist/form/Input.js +1 -1
- package/dist/form/InputOTP.js +3 -3
- package/dist/form/Label.js +2 -2
- package/dist/form/Menubar.js +4 -4
- package/dist/form/PhoneInput.js +1 -1
- package/dist/form/RadioGroup.js +1 -1
- package/dist/form/Select.js +1 -1
- package/dist/form/Switch.js +2 -2
- package/dist/form/Textarea.js +2 -2
- package/dist/form/Toggle.js +1 -1
- package/dist/form/ToggleGroup.js +1 -1
- package/dist/form/UploadButton.js +2 -2
- package/dist/form/total-form.js +10 -10
- package/dist/icons.js +5 -5
- package/dist/layout/Box.js +5 -5
- package/dist/layout/ContentToolbar.js +4 -4
- package/dist/layout/ScrollArea.js +2 -2
- package/dist/layout/SettingsLayout.js +5 -4
- package/dist/layout/Stack.js +6 -6
- package/dist/layout/TableFilter.js +1 -1
- package/dist/navigation/AppHeader.js +8 -8
- package/dist/navigation/Pagination.js +1 -1
- package/dist/navigation/Tabs.js +1 -1
- package/dist/provider.js +5 -5
- package/dist/social-login-button.js +10 -10
- package/dist/tokens.js +4 -4
- package/dist/types/components/data-display/Table/Table.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/Table.hooks.d.ts +3 -2
- package/dist/types/components/data-display/Table/Table.hooks.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/Table.styles.d.ts +3 -1
- package/dist/types/components/data-display/Table/Table.styles.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/Table.types.d.ts +6 -4
- 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 -3
- package/dist/types/components/data-display/Table/TableParts.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/TableParts.hooks.d.ts +6 -2
- package/dist/types/components/data-display/Table/TableParts.hooks.d.ts.map +1 -1
- package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.d.ts.map +1 -1
- package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.scroll.d.ts +64 -0
- package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.scroll.d.ts.map +1 -0
- package/dist/typography/Heading.js +5 -5
- package/dist/typography/Text.js +4 -4
- package/dist/user-avatar.js +7 -7
- package/dist/utility/WorkflowStep.js +2 -2
- package/package.json +1 -1
- package/src/components/data-display/Table/Table.hooks.ts +5 -4
- package/src/components/data-display/Table/Table.md +6 -0
- package/src/components/data-display/Table/Table.styles.ts +28 -1
- package/src/components/data-display/Table/Table.tsx +6 -4
- package/src/components/data-display/Table/Table.types.ts +6 -4
- package/src/components/data-display/Table/TableParts.hooks.tsx +23 -19
- package/src/components/data-display/Table/TableParts.tsx +112 -49
- package/src/components/layout/SettingsLayout/SettingsLayout.md +3 -1
- package/src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts +180 -0
- package/src/components/layout/SettingsLayout/SettingsSectionChips.tsx +73 -15
- package/dist/chunk-5HQNHZ6Z.js.map +0 -1
- package/dist/chunk-BOGTTXPA.js.map +0 -1
- package/dist/chunk-POV2KL2P.js.map +0 -1
- package/dist/chunk-RGT6DM5W.js.map +0 -1
- package/dist/chunk-XWZJLXJT.js.map +0 -1
- /package/dist/{chunk-OAEYCKBN.js.map → chunk-2K7WPHI3.js.map} +0 -0
- /package/dist/{chunk-GWEENWIS.js.map → chunk-3333KCAW.js.map} +0 -0
- /package/dist/{chunk-L7NQCLFU.js.map → chunk-36JKV7CA.js.map} +0 -0
- /package/dist/{chunk-JBI7ITL2.js.map → chunk-3BNQDOHC.js.map} +0 -0
- /package/dist/{chunk-QGFBIUOK.js.map → chunk-3CTQZDSD.js.map} +0 -0
- /package/dist/{chunk-YCCY77W5.js.map → chunk-3IF3I3FI.js.map} +0 -0
- /package/dist/{chunk-A4OCNJWW.js.map → chunk-3UABIEP3.js.map} +0 -0
- /package/dist/{chunk-R2WMSXQR.js.map → chunk-4BNV5AAI.js.map} +0 -0
- /package/dist/{chunk-OHC3F7GJ.js.map → chunk-4NPPO63U.js.map} +0 -0
- /package/dist/{chunk-WHQKH57H.js.map → chunk-4WF6ZLIW.js.map} +0 -0
- /package/dist/{chunk-6WLHEZXI.js.map → chunk-4Y6W7BT4.js.map} +0 -0
- /package/dist/{chunk-5KGABAQB.js.map → chunk-5752357K.js.map} +0 -0
- /package/dist/{chunk-UITQ7KMK.js.map → chunk-5CQNBMLK.js.map} +0 -0
- /package/dist/{chunk-3KREF4ZF.js.map → chunk-5FAI25JQ.js.map} +0 -0
- /package/dist/{chunk-5CQ5HYJW.js.map → chunk-5KWHINO5.js.map} +0 -0
- /package/dist/{chunk-U4O47P6S.js.map → chunk-5WT4YWXC.js.map} +0 -0
- /package/dist/{chunk-SZ3YFVO5.js.map → chunk-6MFMLQ72.js.map} +0 -0
- /package/dist/{chunk-VIUDWOV6.js.map → chunk-7D2C4LK2.js.map} +0 -0
- /package/dist/{chunk-6WBKOM5K.js.map → chunk-7DK6YVJU.js.map} +0 -0
- /package/dist/{chunk-6QXFBZ7Q.js.map → chunk-7ICK5MXV.js.map} +0 -0
- /package/dist/{chunk-QTNHAX2Z.js.map → chunk-A5B7B4HT.js.map} +0 -0
- /package/dist/{chunk-KAIUDBHM.js.map → chunk-AXKLCWFR.js.map} +0 -0
- /package/dist/{chunk-OB56SZGL.js.map → chunk-B7CNP5HW.js.map} +0 -0
- /package/dist/{chunk-34BZXJGT.js.map → chunk-BKASAYQL.js.map} +0 -0
- /package/dist/{chunk-PE4ZW3IA.js.map → chunk-BLW6KLDR.js.map} +0 -0
- /package/dist/{chunk-UAVSBSV5.js.map → chunk-BUPDBEBA.js.map} +0 -0
- /package/dist/{chunk-QKMJUOVH.js.map → chunk-CRG24BGI.js.map} +0 -0
- /package/dist/{chunk-LKMMJKXU.js.map → chunk-CYZZHWNK.js.map} +0 -0
- /package/dist/{chunk-DIM6SUGY.js.map → chunk-DAHYLPK7.js.map} +0 -0
- /package/dist/{chunk-DUNG7D4B.js.map → chunk-DSF4VT7L.js.map} +0 -0
- /package/dist/{chunk-KBZFBHLO.js.map → chunk-DXZOSP6P.js.map} +0 -0
- /package/dist/{chunk-4GWHYLEB.js.map → chunk-DYGWKZ7T.js.map} +0 -0
- /package/dist/{chunk-YOJASBHJ.js.map → chunk-DYNJQ3HJ.js.map} +0 -0
- /package/dist/{chunk-CTKQCKRD.js.map → chunk-ECIHOZPK.js.map} +0 -0
- /package/dist/{chunk-MYWROMGO.js.map → chunk-ENRBXB6L.js.map} +0 -0
- /package/dist/{chunk-FWSMIUWA.js.map → chunk-ESCF5VMQ.js.map} +0 -0
- /package/dist/{chunk-QI5CRSOW.js.map → chunk-F4KYBBTY.js.map} +0 -0
- /package/dist/{chunk-NCEQWEXT.js.map → chunk-FNO5TWBJ.js.map} +0 -0
- /package/dist/{chunk-S6IWKDWT.js.map → chunk-GC56IWIZ.js.map} +0 -0
- /package/dist/{chunk-CXMVNYBY.js.map → chunk-GEB4WSZH.js.map} +0 -0
- /package/dist/{chunk-RIF6L54B.js.map → chunk-H224XFFD.js.map} +0 -0
- /package/dist/{chunk-2EAAWOZ2.js.map → chunk-HM2JJNUE.js.map} +0 -0
- /package/dist/{chunk-JQWAANGN.js.map → chunk-HMAPQV4C.js.map} +0 -0
- /package/dist/{chunk-7RRXLCOO.js.map → chunk-HUPR5JXY.js.map} +0 -0
- /package/dist/{chunk-3RMDIO4G.js.map → chunk-I5T5PQQW.js.map} +0 -0
- /package/dist/{chunk-F4WFUQYR.js.map → chunk-IFS3BRRL.js.map} +0 -0
- /package/dist/{chunk-3GTMGPNQ.js.map → chunk-IQJCLFF4.js.map} +0 -0
- /package/dist/{chunk-2ZRZTGWP.js.map → chunk-ISW5K72V.js.map} +0 -0
- /package/dist/{chunk-IJFAF3A7.js.map → chunk-IWEUSZY3.js.map} +0 -0
- /package/dist/{chunk-EDKLXA5W.js.map → chunk-J3XFUCCR.js.map} +0 -0
- /package/dist/{chunk-TFMDZQK4.js.map → chunk-JGRBHNK6.js.map} +0 -0
- /package/dist/{chunk-XEYLYUDM.js.map → chunk-JH5BKA3Y.js.map} +0 -0
- /package/dist/{chunk-GS3RP2QE.js.map → chunk-KKN4LLVE.js.map} +0 -0
- /package/dist/{chunk-3OBC6BOV.js.map → chunk-LH46NYGR.js.map} +0 -0
- /package/dist/{chunk-56JF5PZK.js.map → chunk-LYVTJLCF.js.map} +0 -0
- /package/dist/{chunk-PZ7PU4AP.js.map → chunk-M2Q5CLPU.js.map} +0 -0
- /package/dist/{chunk-XIG3DXXX.js.map → chunk-M4KVKQRN.js.map} +0 -0
- /package/dist/{chunk-X4ZRPE37.js.map → chunk-MBHWVRV5.js.map} +0 -0
- /package/dist/{chunk-ERY6D2OV.js.map → chunk-MWPXKZ7O.js.map} +0 -0
- /package/dist/{chunk-3AOQBR7N.js.map → chunk-OAW6GCS3.js.map} +0 -0
- /package/dist/{chunk-6N2EDWMG.js.map → chunk-OGB25P3N.js.map} +0 -0
- /package/dist/{chunk-R2XVTUVR.js.map → chunk-OQRG34VG.js.map} +0 -0
- /package/dist/{chunk-RUEKY3VR.js.map → chunk-P52LYD6S.js.map} +0 -0
- /package/dist/{chunk-R53ZOW4B.js.map → chunk-PARTZ7XI.js.map} +0 -0
- /package/dist/{chunk-7GHYCQCJ.js.map → chunk-PCLKFR27.js.map} +0 -0
- /package/dist/{chunk-K6VKL62Z.js.map → chunk-PG5C2AA4.js.map} +0 -0
- /package/dist/{chunk-R3JYC63P.js.map → chunk-QXSV7Z57.js.map} +0 -0
- /package/dist/{chunk-5JSRM7WC.js.map → chunk-RB3X6CEE.js.map} +0 -0
- /package/dist/{chunk-DW6F7354.js.map → chunk-S36NC22G.js.map} +0 -0
- /package/dist/{chunk-6N4AA2Y7.js.map → chunk-S6JHTEV4.js.map} +0 -0
- /package/dist/{chunk-5JCGBCFJ.js.map → chunk-SAOCDKNK.js.map} +0 -0
- /package/dist/{chunk-ISFFETTG.js.map → chunk-T3DNYPEA.js.map} +0 -0
- /package/dist/{chunk-JU4MSYYH.js.map → chunk-T6EKPFKZ.js.map} +0 -0
- /package/dist/{chunk-Q2YNXJEL.js.map → chunk-TZBOWSAM.js.map} +0 -0
- /package/dist/{chunk-D4FZ3ANG.js.map → chunk-UKX3MPB7.js.map} +0 -0
- /package/dist/{chunk-YBH4SPMM.js.map → chunk-URHX4FAQ.js.map} +0 -0
- /package/dist/{chunk-4CXCOR6F.js.map → chunk-V2UZQS2K.js.map} +0 -0
- /package/dist/{chunk-TXGB2WSW.js.map → chunk-VJ2BNJ5M.js.map} +0 -0
- /package/dist/{chunk-ASYR22BJ.js.map → chunk-VJG7NMGL.js.map} +0 -0
- /package/dist/{chunk-BWHOCNGW.js.map → chunk-VPPIODKX.js.map} +0 -0
- /package/dist/{chunk-4B5XUQQS.js.map → chunk-WB6ZU3B3.js.map} +0 -0
- /package/dist/{chunk-W7F2QIAT.js.map → chunk-WCRGSMLV.js.map} +0 -0
- /package/dist/{chunk-G62KCU3D.js.map → chunk-WL6N33AB.js.map} +0 -0
- /package/dist/{chunk-VIRYHNEM.js.map → chunk-WY5PBZ7Q.js.map} +0 -0
- /package/dist/{chunk-TKKQ7RGT.js.map → chunk-WZNTZX5N.js.map} +0 -0
- /package/dist/{chunk-KE473LK6.js.map → chunk-YMTZN54Q.js.map} +0 -0
- /package/dist/{chunk-JSD5TFDK.js.map → chunk-YS67XMOP.js.map} +0 -0
- /package/dist/{chunk-UGGJ3KDT.js.map → chunk-YTINPQKU.js.map} +0 -0
- /package/dist/{chunk-U3PPLAFB.js.map → chunk-ZN6YATOG.js.map} +0 -0
- /package/dist/{chunk-WC3W36AM.js.map → chunk-ZOUWHGV3.js.map} +0 -0
|
@@ -7,6 +7,7 @@ import TableSortLabel from '@mui/material/TableSortLabel/index.js';
|
|
|
7
7
|
import { useTheme, type Theme } from '@mui/material/styles/index.js';
|
|
8
8
|
import React, { useCallback } from 'react';
|
|
9
9
|
|
|
10
|
+
import { FIELD_BORDER_WIDTH } from '../../../tokens/field-height.core';
|
|
10
11
|
import { rem } from '../../../tokens/relative';
|
|
11
12
|
|
|
12
13
|
import { tableRowHeight } from './Table.helpers';
|
|
@@ -125,14 +126,62 @@ export const EnhancedTableHeader: React.FC<TableHeaderProps> = React.memo(({
|
|
|
125
126
|
|
|
126
127
|
EnhancedTableHeader.displayName = 'EnhancedTableHeader';
|
|
127
128
|
|
|
129
|
+
/** How a virtual cell's wrapper places its content along the row, per `align`. */
|
|
130
|
+
const JUSTIFY: Record<NonNullable<ColumnConfig['align']>, React.CSSProperties['justifyContent']> = {
|
|
131
|
+
left: 'flex-start',
|
|
132
|
+
center: 'center',
|
|
133
|
+
right: 'flex-end',
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* A virtual cell's content (FUT-2668). The cell has no vertical padding, and
|
|
138
|
+
* this fills its content box — the pitch less the cell's bottom rule, the one
|
|
139
|
+
* hairline every variant draws — so the cell's border box is exactly the pitch
|
|
140
|
+
* whatever it holds. Centred vertically, placed by the column's `align`, and
|
|
141
|
+
* clipped rather than allowed to grow the row.
|
|
142
|
+
*/
|
|
143
|
+
const VirtualCellContent: React.FC<{
|
|
144
|
+
rowHeight: number;
|
|
145
|
+
align: NonNullable<ColumnConfig['align']>;
|
|
146
|
+
children: React.ReactNode;
|
|
147
|
+
}> = ({ rowHeight, align, children }) => {
|
|
148
|
+
const theme = useTheme();
|
|
149
|
+
return (
|
|
150
|
+
<div
|
|
151
|
+
style={{
|
|
152
|
+
height: `calc(${rem(theme, rowHeight)} - ${FIELD_BORDER_WIDTH}px)`,
|
|
153
|
+
display: 'flex',
|
|
154
|
+
alignItems: 'center',
|
|
155
|
+
justifyContent: JUSTIFY[align],
|
|
156
|
+
overflow: 'hidden',
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
{children}
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/** What one cell shows: the caller's `renderCell`, else the column's `render`, else the value. */
|
|
165
|
+
const cellContent = (
|
|
166
|
+
column: ColumnConfig,
|
|
167
|
+
rowData: Record<string, unknown>,
|
|
168
|
+
index: number,
|
|
169
|
+
renderCell: TableBodyProps['renderCell'],
|
|
170
|
+
): React.ReactNode => {
|
|
171
|
+
const value = rowData[column.key];
|
|
172
|
+
if (renderCell) return renderCell(value, column, rowData, index);
|
|
173
|
+
return column.render ? column.render(value, rowData) : (value as React.ReactNode);
|
|
174
|
+
};
|
|
175
|
+
|
|
128
176
|
// One data row. Split out of the memoised renderTableRow callback so the
|
|
129
177
|
// callback stays a short dispatch and the row markup is readable on its own.
|
|
178
|
+
// A virtualised row stays in the table's flow at `rowHeight`, and each of its
|
|
179
|
+
// cells holds its content in a `VirtualCellContent` (FUT-2668); a plain row is
|
|
180
|
+
// drawn as MUI draws it.
|
|
130
181
|
export const TableDataRow: React.FC<{
|
|
131
182
|
rowData: Record<string, unknown>;
|
|
132
183
|
rowKey: string | number;
|
|
133
184
|
index: number;
|
|
134
|
-
/** Where a virtualised row sits, in design px — drawn through `rem`, like its height. */
|
|
135
|
-
offsetY: number;
|
|
136
185
|
columns: ColumnConfig[];
|
|
137
186
|
selected: boolean;
|
|
138
187
|
selectable?: boolean;
|
|
@@ -142,13 +191,13 @@ export const TableDataRow: React.FC<{
|
|
|
142
191
|
onRowFocus?: TableBodyProps['onRowFocus'];
|
|
143
192
|
onRowBlur?: TableBodyProps['onRowBlur'];
|
|
144
193
|
onSelect: (event: React.MouseEvent | React.ChangeEvent, rowKey: string | number) => void;
|
|
145
|
-
|
|
194
|
+
/** Whether the row is one of a virtual window's. */
|
|
195
|
+
virtualised: boolean;
|
|
146
196
|
renderCell?: TableBodyProps['renderCell'];
|
|
147
197
|
}> = ({
|
|
148
198
|
rowData,
|
|
149
199
|
rowKey,
|
|
150
200
|
index,
|
|
151
|
-
offsetY,
|
|
152
201
|
columns,
|
|
153
202
|
selected,
|
|
154
203
|
selectable,
|
|
@@ -157,9 +206,19 @@ export const TableDataRow: React.FC<{
|
|
|
157
206
|
onRowFocus,
|
|
158
207
|
onRowBlur,
|
|
159
208
|
onSelect,
|
|
160
|
-
|
|
209
|
+
virtualised,
|
|
161
210
|
renderCell }) => {
|
|
162
211
|
const theme = useTheme();
|
|
212
|
+
const pitch = tableRowHeight(rowHeight);
|
|
213
|
+
const fit = (align: NonNullable<ColumnConfig['align']>, content: React.ReactNode) =>
|
|
214
|
+
virtualised ? (
|
|
215
|
+
<VirtualCellContent rowHeight={pitch} align={align}>
|
|
216
|
+
{content}
|
|
217
|
+
</VirtualCellContent>
|
|
218
|
+
) : (
|
|
219
|
+
content
|
|
220
|
+
);
|
|
221
|
+
|
|
163
222
|
return (
|
|
164
223
|
<TableRow
|
|
165
224
|
key={String(rowKey)}
|
|
@@ -168,62 +227,62 @@ export const TableDataRow: React.FC<{
|
|
|
168
227
|
onClick={(event: React.MouseEvent<globalThis.HTMLTableRowElement>) => onRowClick?.(event, rowData)}
|
|
169
228
|
onFocus={(event: React.FocusEvent<globalThis.HTMLTableRowElement>) => onRowFocus?.(event, rowData)}
|
|
170
229
|
onBlur={(event: React.FocusEvent<globalThis.HTMLTableRowElement>) => onRowBlur?.(event, rowData)}
|
|
171
|
-
style={
|
|
172
|
-
transform: `translateY(${rem(theme, offsetY)})`,
|
|
173
|
-
position: 'absolute',
|
|
174
|
-
top: 0,
|
|
175
|
-
left: 0,
|
|
176
|
-
right: 0,
|
|
177
|
-
height: rem(theme, tableRowHeight(rowHeight)) } : undefined}
|
|
230
|
+
style={virtualised ? { height: rem(theme, pitch) } : undefined}
|
|
178
231
|
>
|
|
179
232
|
{selectable && (
|
|
180
233
|
<TableCell padding="checkbox">
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
234
|
+
{fit(
|
|
235
|
+
'left',
|
|
236
|
+
<Checkbox
|
|
237
|
+
checked={selected}
|
|
238
|
+
onChange={(event) => onSelect(event, rowKey)}
|
|
239
|
+
onClick={(event) => event.stopPropagation()}
|
|
240
|
+
inputProps={{ 'aria-label': `select row ${index + 1}` }}
|
|
241
|
+
/>,
|
|
242
|
+
)}
|
|
187
243
|
</TableCell>
|
|
188
244
|
)}
|
|
189
|
-
{columns.map((column) =>
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
? renderCell(value, column, rowData, index)
|
|
195
|
-
: column.render
|
|
196
|
-
? column.render(value, rowData)
|
|
197
|
-
: (value as React.ReactNode)
|
|
198
|
-
}
|
|
199
|
-
</TableCell>
|
|
200
|
-
);
|
|
201
|
-
})}
|
|
245
|
+
{columns.map((column) => (
|
|
246
|
+
<TableCell key={column.key} align={column.align || 'left'}>
|
|
247
|
+
{fit(column.align || 'left', cellContent(column, rowData, index, renderCell))}
|
|
248
|
+
</TableCell>
|
|
249
|
+
))}
|
|
202
250
|
</TableRow>
|
|
203
251
|
);
|
|
204
252
|
};
|
|
205
253
|
|
|
206
|
-
|
|
207
|
-
|
|
254
|
+
/**
|
|
255
|
+
* A stand-in for the rows outside the window, `heightPx` design px tall. A bare
|
|
256
|
+
* `<tr>` and `<td>` with no padding or border: none of MUI's row or cell
|
|
257
|
+
* classes, so hover, striping and cell padding never reach it. Not rendered at
|
|
258
|
+
* all when there is nothing to stand in for.
|
|
259
|
+
*/
|
|
260
|
+
const SpacerRow: React.FC<{ heightPx: number; colSpan: number }> = ({ heightPx, colSpan }) => {
|
|
261
|
+
const theme = useTheme();
|
|
262
|
+
if (heightPx <= 0) return null;
|
|
263
|
+
return (
|
|
264
|
+
<tr aria-hidden="true" style={{ height: rem(theme, heightPx) }}>
|
|
265
|
+
<td colSpan={colSpan} style={{ padding: 0, border: 0 }} />
|
|
266
|
+
</tr>
|
|
267
|
+
);
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
// Only the rows in view are rendered, in the table's own flow between two
|
|
271
|
+
// spacer rows standing in for the rest (FUT-2668) — an absolutely positioned
|
|
272
|
+
// `<tr>` is blockified and leaves the column grid. Every height is design px,
|
|
208
273
|
// drawn through `rem`. The `<tbody>` sits directly in the `<table>`; the one
|
|
209
274
|
// scroll container wraps the whole table, header included (FUT-2658).
|
|
210
275
|
const VirtualisedBody: React.FC<{
|
|
211
276
|
visibleItems: VirtualWindow;
|
|
212
|
-
|
|
213
|
-
renderTableRow: (
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
offsetY
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
<TableBody
|
|
220
|
-
style={{
|
|
221
|
-
height: visibleItems.totalHeight,
|
|
222
|
-
position: 'relative' }}
|
|
223
|
-
>
|
|
224
|
-
{visibleItems.items.map((rowData, index) =>
|
|
225
|
-
renderTableRow(rowData, visibleItems.startIndex + index, visibleItems.offsetY + index * rowHeight)
|
|
277
|
+
colSpan: number;
|
|
278
|
+
renderTableRow: (rowData: Record<string, unknown>, index: number) => React.ReactNode;
|
|
279
|
+
}> = ({ visibleItems, colSpan, renderTableRow }) => (
|
|
280
|
+
<TableBody>
|
|
281
|
+
<SpacerRow heightPx={visibleItems.offsetY} colSpan={colSpan} />
|
|
282
|
+
{visibleItems.items.map((rowData, index) =>
|
|
283
|
+
renderTableRow(rowData, visibleItems.startIndex + index)
|
|
226
284
|
)}
|
|
285
|
+
<SpacerRow heightPx={visibleItems.trailingPx} colSpan={colSpan} />
|
|
227
286
|
</TableBody>
|
|
228
287
|
);
|
|
229
288
|
|
|
@@ -242,13 +301,17 @@ export const EnhancedTableBody: React.FC<TableBodyProps> = React.memo((props) =>
|
|
|
242
301
|
const { data, virtualWindow } = props;
|
|
243
302
|
// The row renderer takes the body's own props; its `rowHeight` stays the
|
|
244
303
|
// caller's design px, and the row resolves the default where it draws it.
|
|
245
|
-
const renderTableRow = useTableRowRenderer({
|
|
304
|
+
const renderTableRow = useTableRowRenderer({
|
|
305
|
+
...props,
|
|
306
|
+
selectedRows: props.selectedRows ?? [],
|
|
307
|
+
virtualised: Boolean(virtualWindow),
|
|
308
|
+
});
|
|
246
309
|
|
|
247
310
|
if (virtualWindow) {
|
|
248
311
|
return (
|
|
249
312
|
<VirtualisedBody
|
|
250
313
|
visibleItems={virtualWindow}
|
|
251
|
-
|
|
314
|
+
colSpan={props.columns.length + (props.selectable ? 1 : 0)}
|
|
252
315
|
renderTableRow={renderTableRow}
|
|
253
316
|
/>
|
|
254
317
|
);
|
|
@@ -22,7 +22,9 @@ it themes automatically in light/dark.
|
|
|
22
22
|
- **Responsive** — below `railBreakpoint` the rail either stacks above the panel
|
|
23
23
|
(`switcher`) or hands the width to a list→detail drilldown (`drilldown`)
|
|
24
24
|
- **Situation markers** per item — host-resolved, with the meaning in text
|
|
25
|
-
- **Section chip strip** on narrow widths, scrolling itself to the open section
|
|
25
|
+
- **Section chip strip** on narrow widths, scrolling itself to the open section —
|
|
26
|
+
and again when a chip or the strip resizes after mount (a status marker that
|
|
27
|
+
resolves late, a web font), until the visitor scrolls the strip themselves
|
|
26
28
|
- **Agnostic** — no app-specific content; drive it with any `groups` data
|
|
27
29
|
|
|
28
30
|
## The two narrow-width shapes
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telling the strip's own scrolls from the visitor's (FUT-2606).
|
|
3
|
+
*
|
|
4
|
+
* Split from `SettingsSectionChips.tsx` so the chips stay a component file and
|
|
5
|
+
* the rule for "who moved the strip" can be read in one place.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* How near to where the strip aimed itself it has to come to rest for the scroll
|
|
10
|
+
* to count as the strip's own. A smooth scroll lands on a device pixel, and the
|
|
11
|
+
* target it was given is fractional.
|
|
12
|
+
*/
|
|
13
|
+
const LANDED_SLACK = 1;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Where `scrollend` is missing: how long the strip has to go without a `scroll`
|
|
17
|
+
* before it counts as settled. Generous on purpose — a busy main thread can go
|
|
18
|
+
* several frames between ticks of a smooth scroll, and judging one mid-flight
|
|
19
|
+
* would read the strip's own animation as the visitor's. Too long only delays a
|
|
20
|
+
* re-centre; too short can latch the strip for good.
|
|
21
|
+
*/
|
|
22
|
+
const QUIET_BEFORE_SETTLED_MS = 250;
|
|
23
|
+
|
|
24
|
+
interface VisitorScrollWatch {
|
|
25
|
+
/** True once the visitor has moved the strip themselves. */
|
|
26
|
+
hasScrolled: () => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* True while a scroll the visitor MAY be making has not come to rest yet. The
|
|
29
|
+
* strip must not scroll itself under it: that would yank a drag in progress.
|
|
30
|
+
*/
|
|
31
|
+
isUndecided: () => boolean;
|
|
32
|
+
/** Where the strip last aimed itself, in its own pixels; `NaN` before it has. */
|
|
33
|
+
aimedAt: () => number;
|
|
34
|
+
/**
|
|
35
|
+
* The strip is about to scroll itself to `left`. Records the aim and NOTHING
|
|
36
|
+
* else: it used to disarm too, and a re-centre landing between a visitor's key
|
|
37
|
+
* press (or wheel, or pan) and the first tick of the scroll it causes wiped
|
|
38
|
+
* the arming — their scroll went unclaimed, read as the strip's own. Left
|
|
39
|
+
* armed, the worst a stale arming does is put the strip's OWN next scroll
|
|
40
|
+
* under judgement, which rests on its aim, is not latched, and disarms.
|
|
41
|
+
*/
|
|
42
|
+
beforeOwnScroll: (left: number) => void;
|
|
43
|
+
/** Called once an undecided scroll has come to rest and been judged. */
|
|
44
|
+
onSettled: (listener: () => void) => void;
|
|
45
|
+
detach: () => void;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type Listeners = Array<[string, (event: Event) => void]>;
|
|
49
|
+
|
|
50
|
+
/** A wheel's sideways travel: `deltaX`, or `deltaY` with Shift held, as browsers read it. */
|
|
51
|
+
function horizontalDelta(event: Event): number {
|
|
52
|
+
if (!(event instanceof WheelEvent)) return 0;
|
|
53
|
+
return event.deltaX !== 0 ? event.deltaX : event.shiftKey ? event.deltaY : 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface WatchState {
|
|
57
|
+
pointer: boolean;
|
|
58
|
+
touch: boolean;
|
|
59
|
+
nudged: boolean;
|
|
60
|
+
undecided: boolean;
|
|
61
|
+
scrolled: boolean;
|
|
62
|
+
aimed: number;
|
|
63
|
+
quiet: ReturnType<typeof setTimeout> | undefined;
|
|
64
|
+
settled: () => void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Whether the strip came to rest where it last aimed itself — clamped as the browser would. */
|
|
68
|
+
function restsOnAim(strip: HTMLElement, aimed: number): boolean {
|
|
69
|
+
const reachable = Math.min(aimed, strip.scrollWidth - strip.clientWidth);
|
|
70
|
+
// Written so that `NaN` — the strip never aimed — reads as "not on aim".
|
|
71
|
+
return Math.abs(strip.scrollLeft - reachable) <= LANDED_SLACK;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Tell a scroll the VISITOR made from every other one.
|
|
76
|
+
*
|
|
77
|
+
* The `scroll` event cannot say: the strip's own `scrollTo` fires it, and so does
|
|
78
|
+
* the browser clamping a strip whose content shrank. So a scroll is only a
|
|
79
|
+
* CANDIDATE when it arrives during something only a visitor does:
|
|
80
|
+
*
|
|
81
|
+
* - a finger held on the strip (`touchstart` until `touchend`) — a drag;
|
|
82
|
+
* - a pointer held on it (`pointerdown` until `pointerup`);
|
|
83
|
+
* - a key press, a SIDEWAYS wheel, or the browser taking a pointer over to pan
|
|
84
|
+
* it (`pointercancel`), each armed until the next scroll under judgement has
|
|
85
|
+
* been judged — whoever's it turns out to be.
|
|
86
|
+
*
|
|
87
|
+
* and the verdict waits until the strip comes to REST (`scrollend`, or a quiet
|
|
88
|
+
* spell where the browser has no `scrollend`): it is the visitor's only if the
|
|
89
|
+
* strip rests somewhere other than where it last aimed itself.
|
|
90
|
+
*
|
|
91
|
+
* Judged at rest rather than per `scroll` because the strip's own smooth scroll
|
|
92
|
+
* fires `scroll` for a third of a second, and a visitor who presses Tab or puts
|
|
93
|
+
* a finger on a chip to scroll the PAGE in that window is not scrolling the
|
|
94
|
+
* strip. Every tick of that animation used to count as theirs, the strip stopped
|
|
95
|
+
* re-centring for good, and the open chip could be left clipped (FUT-2606
|
|
96
|
+
* again, by another door). A visitor who really drags or wheels the strip
|
|
97
|
+
* mid-animation cancels it, so the strip rests where THEY left it — and that
|
|
98
|
+
* still counts. The one loss: a visitor who happens to leave it within a pixel
|
|
99
|
+
* of the strip's own aim is not told apart from it, and the strip there is
|
|
100
|
+
* already where it would have put itself.
|
|
101
|
+
*
|
|
102
|
+
* A tap is a pointer held with no scroll under it, so it never counts. A
|
|
103
|
+
* vertical wheel scrolls the PAGE — the strip is `overflowY: hidden` — and is
|
|
104
|
+
* not armed at all.
|
|
105
|
+
*/
|
|
106
|
+
export function watchVisitorScroll(strip: HTMLElement): VisitorScrollWatch {
|
|
107
|
+
const view = strip.ownerDocument.defaultView;
|
|
108
|
+
const hasScrollEnd = 'onscrollend' in strip;
|
|
109
|
+
const state: WatchState = {
|
|
110
|
+
pointer: false,
|
|
111
|
+
touch: false,
|
|
112
|
+
nudged: false,
|
|
113
|
+
undecided: false,
|
|
114
|
+
scrolled: false,
|
|
115
|
+
aimed: Number.NaN,
|
|
116
|
+
quiet: undefined,
|
|
117
|
+
settled: () => undefined,
|
|
118
|
+
};
|
|
119
|
+
const set =
|
|
120
|
+
(key: 'pointer' | 'touch' | 'nudged', value: boolean) =>
|
|
121
|
+
(): void => {
|
|
122
|
+
state[key] = value;
|
|
123
|
+
};
|
|
124
|
+
const settle = (): void => {
|
|
125
|
+
// Only a scroll that was UNDER JUDGEMENT disarms. Chromium can end the
|
|
126
|
+
// strip's own smooth scroll with a `scrollend` when another scroll cuts it
|
|
127
|
+
// off, fired BEFORE that scroll's first `scroll` (seen with an instant one);
|
|
128
|
+
// disarming there would hand the visitor's scroll to nobody.
|
|
129
|
+
if (!state.undecided) return;
|
|
130
|
+
state.undecided = false;
|
|
131
|
+
state.nudged = false;
|
|
132
|
+
if (!restsOnAim(strip, state.aimed)) state.scrolled = true;
|
|
133
|
+
state.settled();
|
|
134
|
+
};
|
|
135
|
+
const onWheel = (event: Event): void => {
|
|
136
|
+
if (horizontalDelta(event) !== 0) state.nudged = true;
|
|
137
|
+
};
|
|
138
|
+
const onScroll = (): void => {
|
|
139
|
+
if (state.pointer || state.touch || state.nudged) state.undecided = true;
|
|
140
|
+
if (!state.undecided || hasScrollEnd) return;
|
|
141
|
+
// Every tick while undecided, armed or not: a quiet spell that began while
|
|
142
|
+
// the strip was still moving would judge it mid-flight, away from its aim.
|
|
143
|
+
clearTimeout(state.quiet);
|
|
144
|
+
state.quiet = setTimeout(settle, QUIET_BEFORE_SETTLED_MS);
|
|
145
|
+
};
|
|
146
|
+
const onStrip: Listeners = [
|
|
147
|
+
['pointerdown', set('pointer', true)],
|
|
148
|
+
['touchstart', set('touch', true)],
|
|
149
|
+
['pointercancel', set('nudged', true)],
|
|
150
|
+
['keydown', set('nudged', true)],
|
|
151
|
+
['wheel', onWheel],
|
|
152
|
+
['scroll', onScroll],
|
|
153
|
+
['scrollend', settle],
|
|
154
|
+
];
|
|
155
|
+
// A gesture can END off the strip, so its end is heard on the window.
|
|
156
|
+
const onView: Listeners = [
|
|
157
|
+
['pointerup', set('pointer', false)],
|
|
158
|
+
['pointercancel', set('pointer', false)],
|
|
159
|
+
['touchend', set('touch', false)],
|
|
160
|
+
['touchcancel', set('touch', false)],
|
|
161
|
+
];
|
|
162
|
+
for (const [type, listener] of onStrip) strip.addEventListener(type, listener, { passive: true });
|
|
163
|
+
for (const [type, listener] of onView) view?.addEventListener(type, listener, { passive: true });
|
|
164
|
+
return {
|
|
165
|
+
hasScrolled: () => state.scrolled,
|
|
166
|
+
isUndecided: () => state.undecided,
|
|
167
|
+
aimedAt: () => state.aimed,
|
|
168
|
+
beforeOwnScroll: (left) => {
|
|
169
|
+
state.aimed = left;
|
|
170
|
+
},
|
|
171
|
+
onSettled: (listener) => {
|
|
172
|
+
state.settled = listener;
|
|
173
|
+
},
|
|
174
|
+
detach: () => {
|
|
175
|
+
clearTimeout(state.quiet);
|
|
176
|
+
for (const [type, listener] of onStrip) strip.removeEventListener(type, listener);
|
|
177
|
+
for (const [type, listener] of onView) view?.removeEventListener(type, listener);
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -4,6 +4,7 @@ import Box from '@mui/material/Box/index.js';
|
|
|
4
4
|
import { alpha, useTheme, type Theme } from '@mui/material/styles/index.js';
|
|
5
5
|
import React, { useEffect, useRef, type RefObject } from 'react';
|
|
6
6
|
|
|
7
|
+
import { watchVisitorScroll } from './SettingsSectionChips.scroll';
|
|
7
8
|
import { SettingsStatusMarker } from './SettingsStatusMarker';
|
|
8
9
|
import { TOUCH_TARGET } from './SettingsLayout.styles';
|
|
9
10
|
import { rem, sxRem } from '../../../tokens/relative';
|
|
@@ -37,7 +38,38 @@ function prefersReducedMotion(): boolean {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
|
-
*
|
|
41
|
+
* Where the strip has to scroll for `chip`'s centre to sit on its own, clamped
|
|
42
|
+
* to what the strip can scroll.
|
|
43
|
+
*
|
|
44
|
+
* Measured from the two boxes rather than from `chip.offsetLeft`. `offsetLeft`
|
|
45
|
+
* counts from the nearest POSITIONED ancestor, and the strip is not one — nor
|
|
46
|
+
* are the panel and layout around it — so it counted from whatever box the host
|
|
47
|
+
* happened to position, and every target overshot by the strip's offset inside
|
|
48
|
+
* it. The clamp hid that for the last chip; a middle one was simply off-centre.
|
|
49
|
+
* The boxes are both in viewport coordinates, so their difference is the strip's
|
|
50
|
+
* own, whatever the host wraps it in.
|
|
51
|
+
*/
|
|
52
|
+
function centredScrollLeft(strip: HTMLElement, chip: HTMLElement): number {
|
|
53
|
+
const chipBox = chip.getBoundingClientRect();
|
|
54
|
+
const visibleStart = strip.getBoundingClientRect().left + strip.clientLeft;
|
|
55
|
+
const chipCentre = chipBox.left - visibleStart + strip.scrollLeft + chipBox.width / 2;
|
|
56
|
+
const target = chipCentre - strip.clientWidth / 2;
|
|
57
|
+
return Math.max(0, Math.min(target, strip.scrollWidth - strip.clientWidth));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The chip for `id`, walked rather than selected. */
|
|
61
|
+
function findChip(strip: HTMLElement, id: string): HTMLElement | undefined {
|
|
62
|
+
// An id is host data, and a section id carrying a quote would turn a selector
|
|
63
|
+
// string into a thrown SyntaxError — which here would take the whole strip
|
|
64
|
+
// down to centre one chip.
|
|
65
|
+
return Array.from(strip.children).find(
|
|
66
|
+
(node): node is HTMLElement => node instanceof HTMLElement && node.dataset.chipId === id,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Keep the open section's chip in view, however the visitor got here — and
|
|
72
|
+
* however the strip's content settles after it mounted.
|
|
41
73
|
*
|
|
42
74
|
* Keyed on `activeItemId` in an effect rather than done in a click handler:
|
|
43
75
|
* arriving by the desktop rail, by a card, by a pasted link and by the browser's
|
|
@@ -46,9 +78,22 @@ function prefersReducedMotion(): boolean {
|
|
|
46
78
|
* the active chip off the right edge on any list longer than a screen — the
|
|
47
79
|
* visitor is told where they are by an element they cannot see.
|
|
48
80
|
*
|
|
81
|
+
* Centring ONCE is not enough (FUT-2606). A host can widen a chip after mount
|
|
82
|
+
* with the ids unchanged — a status marker whose read resolves late, a web font
|
|
83
|
+
* arriving — and a strip that fitted at mount then overflows with its last chip
|
|
84
|
+
* clipped, because the one centring saw nothing to scroll. So the strip and
|
|
85
|
+
* every chip are watched with a `ResizeObserver`, and a resize re-aims at the
|
|
86
|
+
* active chip when its target has moved.
|
|
87
|
+
*
|
|
88
|
+
* Never against the visitor, though: once they have scrolled the strip
|
|
89
|
+
* themselves, it is theirs until the open section changes
|
|
90
|
+
* ({@link watchVisitorScroll}, which also says why the strip's OWN smooth scroll
|
|
91
|
+
* never counts as theirs). A strip that yanks back mid-drag because a
|
|
92
|
+
* marker loaded is worse than one that does not centre.
|
|
93
|
+
*
|
|
49
94
|
* `itemsKey` rather than `items`: a host almost always rebuilds that array per
|
|
50
95
|
* render (`groups.flatMap(...)`), and depending on it would re-run this on every
|
|
51
|
-
* render and
|
|
96
|
+
* render and reset the visitor's latch with it.
|
|
52
97
|
*
|
|
53
98
|
* The key joins on NUL — as the ESCAPE `'\u0000'`, which it must stay. A
|
|
54
99
|
* literal NUL byte works identically at runtime and makes git classify this file
|
|
@@ -63,25 +108,38 @@ function useCentreActiveChip(
|
|
|
63
108
|
): void {
|
|
64
109
|
useEffect(() => {
|
|
65
110
|
const strip = stripRef.current;
|
|
66
|
-
if (!strip || !activeItemId) return;
|
|
67
|
-
// Walked rather than selected: an id is host data, and a section id carrying
|
|
68
|
-
// a quote would turn a selector string into a thrown SyntaxError — which
|
|
69
|
-
// here would take the whole strip down to centre one chip.
|
|
70
|
-
const chip = Array.from(strip.children).find(
|
|
71
|
-
(node): node is HTMLElement =>
|
|
72
|
-
node instanceof HTMLElement && node.dataset.chipId === activeItemId,
|
|
73
|
-
);
|
|
74
|
-
if (!chip) return;
|
|
111
|
+
if (!strip || !activeItemId) return undefined;
|
|
75
112
|
// Feature-checked, not assumed. `Element.scrollTo` is absent in jsdom and in
|
|
76
113
|
// a few embedded webviews, and an unguarded call there THROWS out of an
|
|
77
114
|
// effect — which React escalates to the nearest error boundary. The whole
|
|
78
115
|
// settings area would go down to centre one chip, and the host's own tests
|
|
79
116
|
// could not render the shell at all. Same reasoning as walking the children
|
|
80
117
|
// instead of building a selector: nothing in here is worth a crash.
|
|
81
|
-
if (typeof strip.scrollTo !== 'function') return;
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
|
|
118
|
+
if (typeof strip.scrollTo !== 'function') return undefined;
|
|
119
|
+
const visitor = watchVisitorScroll(strip);
|
|
120
|
+
const centre = (): void => {
|
|
121
|
+
const chip = findChip(strip, activeItemId);
|
|
122
|
+
// Not while a scroll that may be the visitor's is still moving: a resize
|
|
123
|
+
// mid-drag must not yank the strip. It is re-tried once that scroll rests.
|
|
124
|
+
if (!chip || visitor.hasScrolled() || visitor.isUndecided()) return;
|
|
125
|
+
const left = centredScrollLeft(strip, chip);
|
|
126
|
+
// Only when the target MOVED: a resize that leaves it where it was must not
|
|
127
|
+
// restart a smooth scroll that is already on its way there. The aim is a
|
|
128
|
+
// runtime-computed scroll offset, like the exempt `left` below — not a size.
|
|
129
|
+
if (Math.abs(left - visitor.aimedAt()) < 0.5) return;
|
|
130
|
+
visitor.beforeOwnScroll(left);
|
|
131
|
+
strip.scrollTo({ left, behavior: prefersReducedMotion() ? 'auto' : 'smooth' });
|
|
132
|
+
};
|
|
133
|
+
visitor.onSettled(centre);
|
|
134
|
+
centre();
|
|
135
|
+
// Also feature-checked: without it the strip still centres once, as before.
|
|
136
|
+
const resizes = typeof ResizeObserver === 'function' ? new ResizeObserver(centre) : undefined;
|
|
137
|
+
resizes?.observe(strip);
|
|
138
|
+
for (const child of Array.from(strip.children)) resizes?.observe(child);
|
|
139
|
+
return () => {
|
|
140
|
+
resizes?.disconnect();
|
|
141
|
+
visitor.detach();
|
|
142
|
+
};
|
|
85
143
|
}, [stripRef, activeItemId, itemsKey]);
|
|
86
144
|
}
|
|
87
145
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/Table/Table.hooks.ts"],"sourcesContent":["import { useTheme } from '@mui/material/styles/index.js';\nimport useMediaQuery from '@mui/material/useMediaQuery/index.js';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { rem, remPx } from '../../../tokens/relative';\n\nimport type { ColumnConfig, TableProps, VirtualWindow } from './Table.types';\n\n/**\n * The virtual window. `rowHeight` and `containerHeight` are design px: the\n * window is computed in the px `scrollTop` is measured in (`remPx`), and what it\n * hands back to draw with stays in design px (`offsetY`) or is CSS already\n * (`totalHeight`), so the rows and the window share one pitch at any type scale.\n *\n * The scroller holds the header as well as the body, so the `<tbody>` starts\n * the header's height into it. `handleScroll` measures that height from\n * `headerRef` in the same live px as `scrollTop`, and the window subtracts it\n * before dividing by the pitch (FUT-2658).\n */\nexport const useVirtualScrolling = (\n data: Record<string, unknown>[],\n rowHeight: number,\n containerHeight: number,\n overscan: number = 5,\n headerRef?: React.RefObject<HTMLElement | null>,\n) => {\n const theme = useTheme();\n // Both live px, as the browser measures them.\n const [scroll, setScroll] = useState({ scrollTop: 0, headerPx: 0 });\n \n const visibleItems = useMemo((): VirtualWindow => {\n const pitch = remPx(theme, rowHeight);\n const bodyScrollTop = Math.max(0, scroll.scrollTop - scroll.headerPx);\n const startIndex = Math.floor(bodyScrollTop / pitch);\n const endIndex = Math.min(\n data.length,\n Math.ceil((bodyScrollTop + remPx(theme, containerHeight)) / pitch)\n );\n \n const start = Math.max(0, startIndex - overscan);\n const end = Math.min(data.length, endIndex + overscan);\n \n return {\n startIndex: start,\n endIndex: end,\n items: data.slice(start, end),\n totalHeight: rem(theme, data.length * rowHeight),\n offsetY: start * rowHeight,\n };\n }, [data, rowHeight, containerHeight, scroll, overscan, theme]);\n\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n setScroll({\n scrollTop: e.currentTarget.scrollTop,\n headerPx: headerRef?.current?.offsetHeight ?? 0,\n });\n }, [headerRef]);\n\n return { visibleItems, handleScroll };\n};\n\n// Responsive Hook\n\nconst useResponsive = (\n columns: ColumnConfig[],\n columnPriorities?: number[]\n) => {\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('md'));\n const isTablet = useMediaQuery(theme.breakpoints.down('lg'));\n \n const [hiddenColumns, setHiddenColumns] = useState<number[]>([]);\n const [columnMenuAnchor, setColumnMenuAnchor] = useState<null | HTMLElement>(null);\n\n useEffect(() => {\n if (!columnPriorities) return;\n \n let columnsToHide: number[] = [];\n \n if (isMobile) {\n // Hide lowest priority columns on mobile\n columnsToHide = columnPriorities\n .map((priority, index) => ({ priority, index }))\n .sort((a, b) => b.priority - a.priority)\n .slice(0, Math.floor(columns.length / 2))\n .map(item => item.index);\n } else if (isTablet) {\n // Hide some columns on tablet\n columnsToHide = columnPriorities\n .map((priority, index) => ({ priority, index }))\n .sort((a, b) => b.priority - a.priority)\n .slice(0, Math.floor(columns.length / 3))\n .map(item => item.index);\n }\n \n setHiddenColumns(columnsToHide);\n }, [isMobile, isTablet, columnPriorities, columns.length]);\n\n const visibleColumns = columns.filter((_, index) => !hiddenColumns.includes(index));\n\n return {\n visibleColumns,\n hiddenColumns,\n isMobile,\n columnMenuAnchor,\n setColumnMenuAnchor,\n setHiddenColumns,\n };\n};\n\n// Enhanced Table Header Component\n// Visible/hidden column split for responsive mode, plus row selection.\nexport const useTableSelection = ({\n columns,\n data,\n responsive,\n columnPriorities,\n selectedRows,\n rowKeyExtractor,\n onSelectionChange,\n}: {\n columns?: ColumnConfig[];\n data: TableProps['data'];\n responsive?: boolean;\n columnPriorities?: number[];\n selectedRows: (string | number)[];\n rowKeyExtractor?: (row: Record<string, unknown>, index: number) => string | number;\n onSelectionChange?: TableProps['onSelectionChange'];\n}) => {\n \n // Use responsive hook if responsive mode is enabled\n const {\n visibleColumns,\n hiddenColumns,\n isMobile,\n columnMenuAnchor,\n setColumnMenuAnchor,\n setHiddenColumns,\n } = useResponsive(\n columns || [],\n responsive ? columnPriorities : undefined\n );\n\n // Handle selection changes\n const handleSelectionChange = useCallback((rowKey: string | number, selected: boolean) => {\n if (!onSelectionChange) return;\n \n let newSelection: (string | number)[];\n if (selected) {\n newSelection = [...selectedRows, rowKey];\n } else {\n newSelection = selectedRows.filter(key => key !== rowKey);\n }\n onSelectionChange(newSelection);\n }, [selectedRows, onSelectionChange]);\n\n const handleSelectAll = useCallback((selected: boolean) => {\n if (!onSelectionChange || !data) return;\n \n if (selected) {\n const allKeys = data.map((rowData, index) => \n rowKeyExtractor ? rowKeyExtractor(rowData, index) : (rowData.id as string | number) || index\n );\n onSelectionChange(allKeys);\n } else {\n onSelectionChange([]);\n }\n }, [data, onSelectionChange, rowKeyExtractor]);\n\n // Loading state\n\n return {\n visibleColumns,\n hiddenColumns,\n isMobile,\n columnMenuAnchor,\n setColumnMenuAnchor,\n setHiddenColumns,\n handleSelectionChange,\n handleSelectAll,\n };\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/Table/Table.tsx"],"sourcesContent":["import MoreVertIcon from '@mui/icons-material/MoreVert';\nimport Box from '@mui/material/Box/index.js';\nimport FormControlLabel from '@mui/material/FormControlLabel/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport Menu from '@mui/material/Menu/index.js';\nimport MenuItem from '@mui/material/MenuItem/index.js';\nimport Skeleton from '@mui/material/Skeleton/index.js';\nimport Switch from '@mui/material/Switch/index.js';\nimport MuiTable from '@mui/material/Table/index.js';\nimport TableBody from '@mui/material/TableBody/index.js';\nimport TableCell from '@mui/material/TableCell/index.js';\nimport TableContainer from '@mui/material/TableContainer/index.js';\nimport TableRow from '@mui/material/TableRow/index.js';\nimport { styled, useTheme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport type {\n ColumnConfig,\n TableDensity,\n TableProps,\n TableStripeColor} from './Table.types';\nimport {\n TABLE_DEFAULTS,\n definedProps,\n scrollerStyle,\n tableDomProps,\n tableRowHeight,\n virtualHeight,\n} from './Table.helpers';\nimport { useTableSelection, useVirtualScrolling } from './Table.hooks';\nimport { EnhancedTableBody, EnhancedTableHeader } from './TableParts';\nimport { EmptyRow, NoDataPlaceholder } from './TableStates';\nimport {\n tableStyles } from './Table.styles';\nimport { rem } from '../../../tokens/relative';\n\n// Helper function to get stripe color from theme\nconst StyledTable = styled(MuiTable, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'glow', 'pulse', 'hoverable', 'density', 'stickyHeader', 'stripeColor'].includes(prop as string) })<{\n customVariant?: string;\n glow?: boolean;\n pulse?: boolean;\n hoverable?: boolean;\n density?: TableDensity;\n stickyHeader?: boolean;\n stripeColor?: TableStripeColor;\n}>(({ theme, customVariant, glow, pulse, hoverable, density, stickyHeader, stripeColor = 'neutral' }) => {\n return tableStyles({\n theme,\n customVariant,\n glow,\n pulse,\n hoverable,\n density,\n stickyHeader,\n stripeColor });\n});\n\n// Virtual Scrolling Hook\nconst TableShell: React.FC<{\n innerRef: React.Ref<globalThis.HTMLTableElement>;\n variant?: string;\n stripeColor?: TableStripeColor;\n glow?: boolean;\n pulse?: boolean;\n hoverable?: boolean;\n density?: TableDensity;\n stickyHeader?: boolean;\n header: React.ReactNode;\n rest: Record<string, unknown>;\n children: React.ReactNode;\n}> = ({\n innerRef,\n variant,\n stripeColor,\n glow,\n pulse,\n hoverable,\n density,\n stickyHeader,\n header,\n rest,\n children }) => (\n <TableContainer>\n <StyledTable\n ref={innerRef}\n customVariant={variant}\n stripeColor={stripeColor}\n glow={glow}\n pulse={pulse}\n hoverable={hoverable}\n density={density}\n stickyHeader={stickyHeader}\n {...rest}\n >\n {header}\n {children}\n </StyledTable>\n </TableContainer>\n);\n\nconst SKELETON_ROW_COUNT = 5;\n\nconst LoadingSkeletonRows: React.FC<{ columns?: ColumnConfig[] }> = ({ columns }) => {\n const theme = useTheme();\n return (\n <>\n {Array.from({ length: SKELETON_ROW_COUNT }, (_, index) => (\n <TableRow key={index}>\n {columns?.map((column) => (\n <TableCell key={column.key}>\n <Skeleton height={rem(theme, 20)} />\n </TableCell>\n ))}\n </TableRow>\n ))}\n </>\n );\n};\n\nexport type TableShellProps = Omit<React.ComponentProps<typeof TableShell>, 'children'>;\n\ntype Selection = ReturnType<typeof useTableSelection>;\n\ninterface RendererProps {\n resolved: TableProps;\n selection: Selection;\n innerRef: React.Ref<globalThis.HTMLTableElement>;\n rest: Record<string, unknown>;\n}\n\n// The column-visibility control, shown only when responsive mode has actually\n// hidden something on a narrow viewport.\nconst ColumnToggleMenu: React.FC<{\n columns: ColumnConfig[];\n hiddenColumns: number[];\n anchor: HTMLElement | null;\n setAnchor: (element: HTMLElement | null) => void;\n setHiddenColumns: (next: number[]) => void;\n}> = ({ columns, hiddenColumns, anchor, setAnchor, setHiddenColumns }) => (\n <Box position=\"absolute\" top={8} right={8}>\n <IconButton onClick={(event) => setAnchor(event.currentTarget)} size=\"small\">\n <MoreVertIcon />\n </IconButton>\n <Menu anchorEl={anchor} open={Boolean(anchor)} onClose={() => setAnchor(null)}>\n {columns.map((column, index) => (\n <MenuItem key={column.key}>\n <FormControlLabel\n control={\n <Switch\n checked={!hiddenColumns.includes(index)}\n onChange={(event) =>\n setHiddenColumns(\n event.target.checked\n ? hiddenColumns.filter((i: number) => i !== index)\n : [...hiddenColumns, index],\n )\n }\n size=\"small\"\n />\n }\n label={column.label}\n />\n </MenuItem>\n ))}\n </Menu>\n </Box>\n);\n\n// The populated table. Local because StyledTable cannot cross a module\n// boundary (TS2742).\nconst columnsFor = (resolved: TableProps, selection: Selection): ColumnConfig[] =>\n (resolved.responsive ? selection.visibleColumns : resolved.columns) ?? [];\n\n// The toggle only earns its place when responsive mode has actually hidden\n// something on a narrow viewport.\nconst showsColumnToggle = (resolved: TableProps, selection: Selection): boolean =>\n Boolean(\n resolved.responsive &&\n selection.isMobile &&\n resolved.showColumnToggle &&\n selection.hiddenColumns.length > 0,\n );\n\n// The virtual window lives here, with the one scroller whose offset drives it;\n// the header's ref lets it subtract the height the `<thead>` pushes the body down.\nconst AdvancedTable: React.FC<RendererProps> = ({ resolved: p, selection, innerRef, rest }) => {\n const theme = useTheme();\n const finalColumns = columnsFor(p, selection);\n const showToggle = showsColumnToggle(p, selection);\n const headRef = React.useRef<globalThis.HTMLTableSectionElement>(null);\n const windowHeight = virtualHeight(p);\n const { visibleItems, handleScroll } = useVirtualScrolling(\n p.data ?? [],\n tableRowHeight(p.rowHeight) || 40,\n windowHeight ?? 400,\n p.overscan,\n headRef,\n );\n\n return (\n <Box position=\"relative\">\n <TableContainer\n style={scrollerStyle(theme, p)}\n onScroll={windowHeight ? handleScroll : undefined}\n >\n <StyledTable\n ref={innerRef}\n customVariant={p.variant}\n stripeColor={p.stripeColor}\n glow={p.glow}\n pulse={p.pulse}\n hoverable={p.hoverable}\n density={p.density}\n stickyHeader={p.stickyHeader}\n {...rest}\n >\n <EnhancedTableHeader\n columns={finalColumns}\n data={p.data ?? []}\n sortable={p.sortable}\n sortConfig={p.sortConfig}\n onSortChange={p.onSortChange}\n selectable={p.selectable}\n selectedRows={p.selectedRows}\n onSelectAll={selection.handleSelectAll}\n density={p.density}\n stickyHeader={p.stickyHeader}\n headRef={headRef}\n />\n <EnhancedTableBody\n data={p.data ?? []}\n columns={finalColumns}\n selectedRows={p.selectedRows}\n onRowClick={p.onRowClick}\n onRowFocus={p.onRowFocus}\n onRowBlur={p.onRowBlur}\n onSelectionChange={selection.handleSelectionChange}\n rowKeyExtractor={p.rowKeyExtractor}\n density={p.density}\n selectable={p.selectable}\n hoverable={p.hoverable}\n renderRow={p.renderRow}\n renderCell={p.renderCell}\n virtualScrolling={p.virtualScrolling}\n virtualWindow={windowHeight ? visibleItems : undefined}\n rowHeight={p.rowHeight}\n />\n </StyledTable>\n </TableContainer>\n\n {showToggle && (\n <ColumnToggleMenu\n columns={p.columns ?? []}\n hiddenColumns={selection.hiddenColumns}\n anchor={selection.columnMenuAnchor}\n setAnchor={selection.setColumnMenuAnchor}\n setHiddenColumns={selection.setHiddenColumns}\n />\n )}\n </Box>\n );\n};\n\n// The loading and empty states render the same shell as the populated table, so\n// they share TableShell rather than repeating it three times.\nconst buildShell = ({\n resolved,\n selection,\n innerRef,\n rest,\n finalColumns }: RendererProps & { finalColumns?: ColumnConfig[] }) => ({\n innerRef,\n variant: resolved.variant,\n stripeColor: resolved.stripeColor,\n glow: resolved.glow,\n pulse: resolved.pulse,\n hoverable: resolved.hoverable,\n density: resolved.density,\n stickyHeader: resolved.stickyHeader,\n header: resolved.columns ? (\n <EnhancedTableHeader\n columns={finalColumns ?? []}\n data={[]}\n sortable={resolved.sortable}\n sortConfig={resolved.sortConfig}\n onSortChange={resolved.onSortChange}\n selectable={resolved.selectable}\n selectedRows={resolved.selectedRows}\n onSelectAll={selection.handleSelectAll}\n density={resolved.density}\n stickyHeader={resolved.stickyHeader}\n />\n ) : null,\n rest: rest as Record<string, unknown> });\n\nconst TableLoadingState: React.FC<{\n shell: TableShellProps;\n loadingComponent?: React.ReactNode;\n columns?: ColumnConfig[];\n}> = ({ shell, loadingComponent, columns }) => (\n <TableShell {...shell}>\n <TableBody data-testid=\"table-loading\">\n {loadingComponent || <LoadingSkeletonRows columns={columns} />}\n </TableBody>\n </TableShell>\n);\n\nconst TableEmptyState: React.FC<{\n shell: TableShellProps;\n emptyStateComponent?: React.ReactNode;\n emptyText: string;\n colSpan: number;\n}> = ({ shell, emptyStateComponent, emptyText, colSpan }) => (\n <TableShell {...shell}>\n <EmptyRow colSpan={colSpan}>\n {emptyStateComponent || <NoDataPlaceholder emptyText={emptyText} />}\n </EmptyRow>\n </TableShell>\n);\n\nexport const Table = React.forwardRef<globalThis.HTMLTableElement, TableProps>(\n (tableProps, ref) => {\n const resolved = { ...TABLE_DEFAULTS, ...definedProps(tableProps) } as TableProps;\n const {\n columns,\n data,\n responsive,\n loading,\n loadingComponent,\n emptyStateComponent,\n emptyText,\n children,\n } = resolved;\n\n const selection = useTableSelection({\n columns,\n data,\n responsive,\n columnPriorities: resolved.columnPriorities,\n selectedRows: resolved.selectedRows ?? [],\n rowKeyExtractor: resolved.rowKeyExtractor,\n onSelectionChange: resolved.onSelectionChange });\n\n // Only MUI's and the DOM's own props reach the `<table>` (FUT-2658).\n const rest = tableDomProps(tableProps);\n const renderer: RendererProps = { resolved, selection, innerRef: ref, rest };\n const finalColumns = responsive ? selection.visibleColumns : columns;\n const shell = buildShell({ ...renderer, finalColumns });\n\n if (loading) {\n return (\n <TableLoadingState shell={shell} loadingComponent={loadingComponent} columns={columns} />\n );\n }\n\n if (data && data.length === 0) {\n return (\n <TableEmptyState\n shell={shell}\n emptyStateComponent={emptyStateComponent}\n emptyText={emptyText}\n colSpan={finalColumns?.length || 1}\n />\n );\n }\n\n if (columns && data) return <AdvancedTable {...renderer} />;\n\n // Basic table (backward compatibility)\n return (\n <StyledTable\n ref={ref}\n customVariant={resolved.variant}\n stripeColor={resolved.stripeColor}\n glow={resolved.glow}\n pulse={resolved.pulse}\n hoverable={resolved.hoverable}\n density={resolved.density}\n stickyHeader={resolved.stickyHeader}\n {...rest}\n >\n {children}\n </StyledTable>\n );\n },\n);\n\nTable.displayName = 'Table';"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/Table/Table.styles.ts"],"sourcesContent":["import { alpha, keyframes } from '@mui/material/styles/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\n\nimport type { TableDensity, TableStripeColor } from './Table.types';\nimport { rem, rems } from '../../../tokens/relative';\n\nconst pulseAnimation = (theme: Theme) => keyframes`\n 0% {\n box-shadow: 0 0 0 0 currentColor;\n opacity: 1;\n }\n 70% {\n box-shadow: 0 0 0 ${rem(theme, 10)} currentColor;\n opacity: 0;\n }\n 100% {\n box-shadow: 0 0 0 0 currentColor;\n opacity: 0;\n }\n`;\n\n// Density configurations. The row height stays design px (`…Px`) and goes\n// through `rem` where the cell is drawn.\nconst getDensityConfig = (theme: Theme, density: TableDensity = 'normal') => {\n const configs = {\n compact: {\n rowHeightPx: 36,\n cellPadding: rems(theme, 6, 12),\n fontSize: rem(theme, 13),\n headerPadding: rems(theme, 8, 12) },\n normal: {\n rowHeightPx: 52,\n cellPadding: rems(theme, 12, 16),\n fontSize: rem(theme, 14),\n headerPadding: rems(theme, 16, 16) },\n comfortable: {\n rowHeightPx: 68,\n cellPadding: rems(theme, 18, 24),\n fontSize: rem(theme, 14),\n headerPadding: rems(theme, 20, 24) } };\n return configs[density];\n};\n\nconst getStripeColorFromTheme = (theme: { palette: { primary: { main: string }; secondary: { main: string }; info: { main: string }; success: { main: string }; warning: { main: string }; error: { main: string }; action: { hover: string } } }, stripeColor: TableStripeColor = 'neutral') => {\n const colorMap: Record<TableStripeColor, string> = {\n primary: theme.palette.primary.main,\n secondary: theme.palette.secondary.main,\n info: theme.palette.info.main,\n success: theme.palette.success.main,\n warning: theme.palette.warning.main,\n danger: theme.palette.error.main,\n neutral: theme.palette.action.hover };\n return colorMap[stripeColor];\n};\n\n/**\n * The zebra stripe for one body row.\n *\n * `neutral` — the default — resolves to `palette.action.hover`, which ALREADY\n * carries its subtlety in its own alpha (`rgba(0,0,0,0.04)` in the light\n * theme). MUI's `alpha()` REPLACES that channel rather than multiplying it, so\n * re-alpha-ing it at 0.5 amplified the tint 12.5× into `rgba(0,0,0,0.5)` —\n * solid #808080 on a white card, which reads as a selected or errored row\n * rather than as a stripe (FUT-755). It is used as-is instead.\n *\n * The named colours are opaque `*.main` values with no alpha of their own, so\n * they still need one.\n */\nconst stripeRowColor = (\n theme: Parameters<typeof getStripeColorFromTheme>[0],\n stripeColor: TableStripeColor = 'neutral',\n): string => {\n const color = getStripeColorFromTheme(theme, stripeColor);\n return stripeColor === 'neutral' ? color : alpha(color, 0.15);\n};\n\n// One variant applies at a time, so a lookup replaces the mutually exclusive\n// spreads.\nconst TABLE_VARIANTS: Record<string, (args: VariantArgs) => CSSObject> = {\n default: ({ theme }) => ({\n backgroundColor: theme.palette.background.paper,\n '& .MuiTableHead-root': {\n backgroundColor: alpha(theme.palette.primary.main, 0.1) } }),\n striped: ({ theme, stripeColor }) => ({\n backgroundColor: theme.palette.background.paper,\n '& .MuiTableBody-root .MuiTableRow-root:nth-of-type(even)': {\n backgroundColor: stripeRowColor(theme, stripeColor) } }),\n glass: ({ theme }) => ({\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: `blur(${rem(theme, 20)})`,\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}` }),\n minimal: ({ theme }) => ({\n backgroundColor: 'transparent',\n '& .MuiTableCell-root': {\n borderBottom: `1px solid ${alpha(theme.palette.divider, 0.1)}` } }),\n gradient: ({ theme }) => ({\n background: `linear-gradient(135deg, ${alpha(theme.palette.primary.main, 0.05)}, ${alpha(theme.palette.secondary.main, 0.05)})`,\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n '& .MuiTableHead-root': {\n background: `linear-gradient(135deg, ${alpha(theme.palette.primary.main, 0.15)}, ${alpha(theme.palette.secondary.main, 0.15)})` },\n '& .MuiTableCell-root': {\n borderBottom: `1px solid ${alpha(theme.palette.divider, 0.15)}` } }) };\n\ntype VariantArgs = {\n theme: Theme;\n densityConfig: ReturnType<typeof getDensityConfig>;\n stripeColor?: TableStripeColor;\n};\n\nconst tableVariantStyles = (args: VariantArgs, customVariant?: string): CSSObject =>\n customVariant ? (TABLE_VARIANTS[customVariant]?.(args) ?? {}) : {};\n\n// Sticky headers and row hover are independent of the variant.\nconst stickyHeaderStyles = (\n theme: Theme,\n densityConfig: ReturnType<typeof getDensityConfig>,\n): CSSObject => ({\n '& .MuiTableHead-root': {\n position: 'sticky',\n top: 0,\n zIndex: 100,\n backgroundColor: theme.palette.background.paper,\n '& .MuiTableCell-root': {\n borderBottom: `${rem(theme, 2)} solid ${theme.palette.divider}`,\n fontWeight: 600,\n padding: densityConfig.headerPadding } } });\n\nconst hoverableRowStyles = (theme: Theme): CSSObject => ({\n '& .MuiTableBody-root .MuiTableRow-root:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.08),\n cursor: 'pointer',\n transition: 'background-color 0.15s ease-in-out' } });\n\n// glow and pulse combine into three distinct looks, spelled out rather than\n// layered — the glow-only shadow differs from the one used when both are on.\nconst emphasisStyles = (theme: Theme, glow?: boolean, pulse?: boolean): CSSObject => {\n if (glow && pulse) return ({\n position: 'relative',\n boxShadow: `${rems(theme, 0, 0, 20, 5)} ${alpha(theme.palette.primary.main, 0.3)} !important`,\n filter: 'brightness(1.05)',\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: 'inherit',\n backgroundColor: theme.palette.primary.main,\n opacity: 0.1,\n animation: `${pulseAnimation(theme)} 2s infinite`,\n pointerEvents: 'none',\n zIndex: -1 } });\n if (glow) return ({\n boxShadow: `${rems(theme, 0, 0, 20, 5)} ${alpha(theme.palette.primary.main, 0.3)} !important`,\n filter: 'brightness(1.05)' });\n if (pulse) return ({\n position: 'relative',\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: 'inherit',\n backgroundColor: theme.palette.primary.main,\n opacity: 0.1,\n animation: `${pulseAnimation(theme)} 2s infinite`,\n pointerEvents: 'none',\n zIndex: -1 } });\n\n return {};\n};\n\n// The table's own styling, lifted out so the styled() callback just forwards\n// its props.\nexport const tableStyles = ({\n theme,\n customVariant,\n glow,\n pulse,\n hoverable,\n density,\n stickyHeader,\n stripeColor = 'neutral' }: {\n theme: Theme;\n customVariant?: string;\n glow?: boolean;\n pulse?: boolean;\n hoverable?: boolean;\n density?: TableDensity;\n stickyHeader?: boolean;\n stripeColor?: TableStripeColor;\n}): CSSObject => {\n const densityConfig = getDensityConfig(theme, density);\n \n return {\n borderRadius: theme.spacing(1),\n overflow: 'hidden',\n transition: 'all 0.3s ease',\n position: 'relative',\n\n // Density styles\n '& .MuiTableCell-root': {\n padding: densityConfig.cellPadding,\n fontSize: densityConfig.fontSize,\n height: rem(theme, densityConfig.rowHeightPx) },\n\n // Sticky header\n ...tableVariantStyles({ theme, densityConfig, stripeColor }, customVariant),\n ...(stickyHeader ? stickyHeaderStyles(theme, densityConfig) : {}),\n ...(hoverable ? hoverableRowStyles(theme) : {}),\n ...emphasisStyles(theme, glow, pulse),\n\n\n // Variant styles\n\n\n\n\n\n\n\n\n\n\n // Hoverable rows\n\n\n // Selection styles\n '& .MuiTableRow-root.selected': {\n backgroundColor: alpha(theme.palette.primary.main, 0.12),\n '&:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.16) } },\n\n // Glow effect\n\n\n // Pulse animation\n\n\n // Both glow and pulse\n\n };\n}\n"],"mappings":";;;;;;AAAA,SAAS,OAAO,iBAAiB;AAMjC,IAAM,iBAAiB,CAAC,UAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMjB,IAAI,OAAO,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWtC,IAAM,mBAAmB,CAAC,OAAc,UAAwB,aAAa;AAC3E,QAAM,UAAU;AAAA,IACd,SAAS;AAAA,MACP,aAAa;AAAA,MACb,aAAa,KAAK,OAAO,GAAG,EAAE;AAAA,MAC9B,UAAU,IAAI,OAAO,EAAE;AAAA,MACvB,eAAe,KAAK,OAAO,GAAG,EAAE;AAAA,IAAE;AAAA,IACpC,QAAQ;AAAA,MACN,aAAa;AAAA,MACb,aAAa,KAAK,OAAO,IAAI,EAAE;AAAA,MAC/B,UAAU,IAAI,OAAO,EAAE;AAAA,MACvB,eAAe,KAAK,OAAO,IAAI,EAAE;AAAA,IAAE;AAAA,IACrC,aAAa;AAAA,MACX,aAAa;AAAA,MACb,aAAa,KAAK,OAAO,IAAI,EAAE;AAAA,MAC/B,UAAU,IAAI,OAAO,EAAE;AAAA,MACvB,eAAe,KAAK,OAAO,IAAI,EAAE;AAAA,IAAE;AAAA,EAAE;AACzC,SAAO,QAAQ,OAAO;AACxB;AAEA,IAAM,0BAA0B,CAAC,OAAkN,cAAgC,cAAc;AAC/R,QAAM,WAA6C;AAAA,IACjD,SAAS,MAAM,QAAQ,QAAQ;AAAA,IAC/B,WAAW,MAAM,QAAQ,UAAU;AAAA,IACnC,MAAM,MAAM,QAAQ,KAAK;AAAA,IACzB,SAAS,MAAM,QAAQ,QAAQ;AAAA,IAC/B,SAAS,MAAM,QAAQ,QAAQ;AAAA,IAC/B,QAAQ,MAAM,QAAQ,MAAM;AAAA,IAC5B,SAAS,MAAM,QAAQ,OAAO;AAAA,EAAM;AACtC,SAAO,SAAS,WAAW;AAC7B;AAeA,IAAM,iBAAiB,CACrB,OACA,cAAgC,cACrB;AACX,QAAM,QAAQ,wBAAwB,OAAO,WAAW;AACxD,SAAO,gBAAgB,YAAY,QAAQ,MAAM,OAAO,IAAI;AAC9D;AAIA,IAAM,iBAAmE;AAAA,EACvE,SAAS,CAAC,EAAE,MAAM,OAAO;AAAA,IACrB,iBAAiB,MAAM,QAAQ,WAAW;AAAA,IAC1C,wBAAwB;AAAA,MACtB,iBAAiB,MAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG;AAAA,IAAE;AAAA,EAAE;AAAA,EAChE,SAAS,CAAC,EAAE,OAAO,YAAY,OAAO;AAAA,IAClC,iBAAiB,MAAM,QAAQ,WAAW;AAAA,IAC1C,4DAA4D;AAAA,MAC1D,iBAAiB,eAAe,OAAO,WAAW;AAAA,IAAE;AAAA,EAAE;AAAA,EAC5D,OAAO,CAAC,EAAE,MAAM,OAAO;AAAA,IACnB,iBAAiB,MAAM,MAAM,QAAQ,WAAW,OAAO,GAAG;AAAA,IAC1D,gBAAgB,QAAQ,IAAI,OAAO,EAAE,CAAC;AAAA,IACtC,QAAQ,aAAa,MAAM,MAAM,QAAQ,SAAS,GAAG,CAAC;AAAA,EAAG;AAAA,EAC7D,SAAS,CAAC,EAAE,MAAM,OAAO;AAAA,IACrB,iBAAiB;AAAA,IACjB,wBAAwB;AAAA,MACtB,cAAc,aAAa,MAAM,MAAM,QAAQ,SAAS,GAAG,CAAC;AAAA,IAAG;AAAA,EAAE;AAAA,EACvE,UAAU,CAAC,EAAE,MAAM,OAAO;AAAA,IACtB,YAAY,2BAA2B,MAAM,MAAM,QAAQ,QAAQ,MAAM,IAAI,CAAC,KAAK,MAAM,MAAM,QAAQ,UAAU,MAAM,IAAI,CAAC;AAAA,IAC5H,QAAQ,aAAa,MAAM,MAAM,QAAQ,SAAS,GAAG,CAAC;AAAA,IACtD,wBAAwB;AAAA,MACtB,YAAY,2BAA2B,MAAM,MAAM,QAAQ,QAAQ,MAAM,IAAI,CAAC,KAAK,MAAM,MAAM,QAAQ,UAAU,MAAM,IAAI,CAAC;AAAA,IAAI;AAAA,IAClI,wBAAwB;AAAA,MACtB,cAAc,aAAa,MAAM,MAAM,QAAQ,SAAS,IAAI,CAAC;AAAA,IAAG;AAAA,EAAE;AAAG;AAQ7E,IAAM,qBAAqB,CAAC,MAAmB,kBAC7C,gBAAiB,eAAe,aAAa,IAAI,IAAI,KAAK,CAAC,IAAK,CAAC;AAGnE,IAAM,qBAAqB,CACzB,OACA,mBACe;AAAA,EACX,wBAAwB;AAAA,IACtB,UAAU;AAAA,IACV,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,iBAAiB,MAAM,QAAQ,WAAW;AAAA,IAC1C,wBAAwB;AAAA,MACtB,cAAc,GAAG,IAAI,OAAO,CAAC,CAAC,UAAU,MAAM,QAAQ,OAAO;AAAA,MAC7D,YAAY;AAAA,MACZ,SAAS,cAAc;AAAA,IAAc;AAAA,EAAE;AAAE;AAEnD,IAAM,qBAAqB,CAAC,WAA6B;AAAA,EACnD,gDAAgD;AAAA,IAC9C,iBAAiB,MAAM,MAAM,QAAQ,QAAQ,MAAM,IAAI;AAAA,IACvD,QAAQ;AAAA,IACR,YAAY;AAAA,EAAqC;AAAE;AAI3D,IAAM,iBAAiB,CAAC,OAAc,MAAgB,UAA+B;AACnF,MAAI,QAAQ,MAAO,QAAQ;AAAA,IACvB,UAAU;AAAA,IACV,WAAW,GAAG,KAAK,OAAO,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI,MAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG,CAAC;AAAA,IAChF,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,MACV,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,iBAAiB,MAAM,QAAQ,QAAQ;AAAA,MACvC,SAAS;AAAA,MACT,WAAW,GAAG,eAAe,KAAK,CAAC;AAAA,MACnC,eAAe;AAAA,MACf,QAAQ;AAAA,IAAG;AAAA,EAAE;AACnB,MAAI,KAAM,QAAQ;AAAA,IACd,WAAW,GAAG,KAAK,OAAO,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI,MAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG,CAAC;AAAA,IAChF,QAAQ;AAAA,EAAmB;AAC/B,MAAI,MAAO,QAAQ;AAAA,IACf,UAAU;AAAA,IACV,YAAY;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,MACV,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,iBAAiB,MAAM,QAAQ,QAAQ;AAAA,MACvC,SAAS;AAAA,MACT,WAAW,GAAG,eAAe,KAAK,CAAC;AAAA,MACnC,eAAe;AAAA,MACf,QAAQ;AAAA,IAAG;AAAA,EAAE;AAEnB,SAAO,CAAC;AACV;AAIO,IAAM,cAAc,CAAC;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAU,MAST;AACf,QAAM,gBAAgB,iBAAiB,OAAO,OAAO;AAErD,SAAO;AAAA,IACL,cAAc,MAAM,QAAQ,CAAC;AAAA,IAC7B,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,UAAU;AAAA;AAAA,IAGV,wBAAwB;AAAA,MACtB,SAAS,cAAc;AAAA,MACvB,UAAU,cAAc;AAAA,MACxB,QAAQ,IAAI,OAAO,cAAc,WAAW;AAAA,IAAE;AAAA;AAAA,IAGhD,GAAG,mBAAmB,EAAE,OAAO,eAAe,YAAY,GAAG,aAAa;AAAA,IAC1E,GAAI,eAAe,mBAAmB,OAAO,aAAa,IAAI,CAAC;AAAA,IAC/D,GAAI,YAAY,mBAAmB,KAAK,IAAI,CAAC;AAAA,IAC7C,GAAG,eAAe,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA,IAkBpC,gCAAgC;AAAA,MAC9B,iBAAiB,MAAM,MAAM,QAAQ,QAAQ,MAAM,IAAI;AAAA,MACvD,WAAW;AAAA,QACT,iBAAiB,MAAM,MAAM,QAAQ,QAAQ,MAAM,IAAI;AAAA,MAAE;AAAA,IAAE;AAAA;AAAA;AAAA;AAAA,EAUjE;AACF;","names":[]}
|